# Testing ## Tổng quan Testing là một phần quan trọng trong quy trình phát triển, đảm bảo chất lượng mã nguồn và giảm thiểu bugs. Dự án này sử dụng các công cụ và phương pháp testing tiêu chuẩn trong Golang. ## Unit Testing ### Công cụ sử dụng - Testify: Framework unit testing cho Go - Table-driven tests: Thiết kế test cases linh hoạt - Mocking: Giả lập dependencies ### Quy ước và cấu trúc - Mỗi package cần có file `*_test.go` tương ứng - Các test functions có format `Test{FunctionName}` - Test cases nên bao gồm cả happy path và error cases - Coverage yêu cầu tối thiểu: 80% - Sử dụng t.Run() để chạy các subtest ### Mẫu Unit Test ```go // user_service_test.go package user import ( "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) // Mocking repository type MockUserRepository struct { mock.Mock } func (m *MockUserRepository) FindByID(id string) (*User, error) { args := m.Called(id) if args.Get(0) == nil { return nil, args.Error(1) } return args.Get(0).(*User), args.Error(1) } func TestGetUser(t *testing.T) { // Test cases testCases := []struct { name string userID string mockUser *User mockError error expectedUser *User expectedError error }{ { name: "successful_get", userID: "123", mockUser: &User{ID: "123", Name: "Test User"}, mockError: nil, expectedUser: &User{ID: "123", Name: "Test User"}, expectedError: nil, }, { name: "user_not_found", userID: "456", mockUser: nil, mockError: ErrUserNotFound, expectedUser: nil, expectedError: ErrUserNotFound, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { // Setup mock mockRepo := new(MockUserRepository) mockRepo.On("FindByID", tc.userID).Return(tc.mockUser, tc.mockError) // Create service with mock dependency service := NewUserService(mockRepo) // Call the method user, err := service.GetUser(tc.userID) // Assert results assert.Equal(t, tc.expectedUser, user) assert.Equal(t, tc.expectedError, err) // Verify expectations mockRepo.AssertExpectations(t) }) } } ``` ## Integration Testing ### Approach - Test containers: Chạy dependent services (database, caching, etc) trong Docker containers - API testing: Kiểm tra endpoints và responses - DB testing: Kiểm tra queries và migrations ### Setup và Teardown - Sử dụng `TestMain` để setup và teardown test environment - Cấu hình Docker containers cho testing - Cleanup sau khi chạy tests ## E2E Testing - API black-box testing - Sequence testing cho business flows - Performance testing ## CI/CD Integration - Chạy tests trên mỗi commit và PR - Lưu test results và coverage - Chỉ merge khi tests pass ## Best Practices 1. **Write tests first (TDD approach)** 2. **Keep tests independent và idempotent** 3. **Sử dụng fixtures cho test data** 4. **Tránh hard-coding external dependencies** 5. **Tách common test code thành helper functions**