Kiểm thử từng đơn vị code riêng lẻ - Nền tảng của testing
Unit Testing là kiểm thử từng đơn vị nhỏ nhất của code (function, method) một cách độc lập. Mục tiêu là đảm bảo mỗi unit hoạt động đúng.
Go có testing package built-in, không cần cài thêm.
// calculator.go
package calculator
func Add(a, b int) int {
return a + b
}
func Divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("cannot divide by zero")
}
return a / b, nil
}
// calculator_test.go
package calculator
import "testing"
func TestAdd(t *testing.T) {
result := Add(2, 3)
expected := 5
if result != expected {
t.Errorf("Add(2, 3) = %d; want %d", result, expected)
}
}
// Table-driven tests
func TestDivide(t *testing.T) {
tests := []struct {
name string
a, b int
want int
wantErr bool
}{
{"positive", 10, 2, 5, false},
{"zero divisor", 10, 0, 0, true},
{"negative", -10, 2, -5, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Divide(tt.a, tt.b)
if (err != nil) != tt.wantErr {
t.Errorf("error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("Divide() = %v, want %v", got, tt.want)
}
})
}
}
# Chạy tests
go test ./...
# Với coverage
go test -cover ./...
# Verbose output
go test -v ./...
pytest là framework phổ biến nhất cho Python testing.
# calculator.py
def add(a: int, b: int) -> int:
return a + b
def divide(a: int, b: int) -> float:
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
# test_calculator.py
import pytest
from calculator import add, divide
def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
def test_divide():
assert divide(10, 2) == 5.0
assert divide(-10, 2) == -5.0
def test_divide_by_zero():
with pytest.raises(ValueError, match="Cannot divide by zero"):
divide(10, 0)
# Parametrized tests
@pytest.mark.parametrize("a,b,expected", [
(2, 3, 5),
(-1, 1, 0),
(100, 200, 300),
])
def test_add_parametrized(a, b, expected):
assert add(a, b) == expected
# Cài pytest
pip install pytest pytest-cov
# Chạy tests
pytest
# Với coverage
pytest --cov=. --cov-report=html
Jest là testing framework phổ biến nhất cho JavaScript/TypeScript.
// calculator.js
export function add(a, b) {
return a + b;
}
export function divide(a, b) {
if (b === 0) {
throw new Error("Cannot divide by zero");
}
return a / b;
}
// calculator.test.js
import { add, divide } from './calculator';
describe('Calculator', () => {
describe('add', () => {
test('adds two positive numbers', () => {
expect(add(2, 3)).toBe(5);
});
test('adds negative numbers', () => {
expect(add(-1, 1)).toBe(0);
});
});
describe('divide', () => {
test('divides two numbers', () => {
expect(divide(10, 2)).toBe(5);
});
test('throws error when dividing by zero', () => {
expect(() => divide(10, 0)).toThrow('Cannot divide by zero');
});
});
// Parameterized tests
test.each([
[2, 3, 5],
[-1, 1, 0],
[100, 200, 300],
])('add(%i, %i) returns %i', (a, b, expected) => {
expect(add(a, b)).toBe(expected);
});
});
# Cài Jest
npm install --save-dev jest
# Chạy tests
npm test
# Với coverage
npm test -- --coverage
Mỗi test nên theo pattern Arrange-Act-Assert:
func TestUserCreation(t *testing.T) {
// Arrange - Setup test data
name := "John Doe"
email := "[email protected]"
// Act - Execute the code under test
user, err := CreateUser(name, email)
// Assert - Verify the results
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if user.Name != name {
t.Errorf("got name %q, want %q", user.Name, name)
}
}
TestAdd_PositiveNumbers_ReturnsSumtest_divide_by_zero_raises_errorshould return error when input is invalid