# Testing Guide This project uses modern Go testing practices for 2025, focusing on reliability, maintainability, and efficiency. ## Testing Stack - **Ginkgo**: BDD testing framework for expressive, readable test specifications - **Gomega**: Matcher library for flexible assertions - **Testify**: Additional assertion helpers and mocking capabilities - **TestContainers**: For integration tests with real dependencies (planned) ## Test Structure ``` internal/ ├── service/ │ ├── *_test.go # Unit tests for services │ └── ... ├── testutils/ │ └── fixtures.go # Test data fixtures └── ... ``` ## Running Tests ### Unit Tests ```bash # Run all tests go test ./... # Run specific package go test ./internal/service # Run with coverage go test -cover ./internal/service # Run with verbose output go test -v ./internal/service ``` ### BDD Tests with Ginkgo ```bash # Install ginkgo CLI go install github.com/onsi/ginkgo/v2/ginkgo # Run tests ginkgo ./internal/service # Watch mode ginkgo watch ./internal/service ``` ## Writing Tests ### Unit Tests with Ginkgo/Gomega ```go package service_test import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "your-project/internal/service" ) var _ = Describe("MyService", func() { var svc *service.MyService BeforeEach(func() { svc = service.NewMyService() }) Describe("DoSomething", func() { Context("with valid input", func() { It("returns expected result", func() { result := svc.DoSomething("input") Expect(result).To(Equal("expected")) }) }) }) }) ``` ### Using Test Utilities The `internal/testutils` package provides rich, reusable test fixtures and builders: ### Builders for Flexible Test Data ```go // Fluent interface for creating test data rf := testutils.NewResourceFlowBuilder(). WithType(domain.TypeWater). WithQuantity(500, "liters"). WithDirection(domain.DirectionInput). Build() business := testutils.NewBusinessBuilder(). WithNACE("C20.11"). WithCertifications([]string{"ISO 9001"}). WithHighTrustScore(). Build() ``` ### Semantic Factory Functions ```go // Pre-configured test data validFlow := testutils.CreateValidHeatResourceFlow() incompleteFlow := testutils.CreateIncompleteResourceFlow() lowQualityFlow := testutils.CreateLowQualityResourceFlow() highTrustBusiness := testutils.CreateHighTrustBusinessEntity() validMatch := testutils.CreateValidMatchProposal() ``` ### Test Data Suite ```go // Complete suite for comprehensive testing suite := testutils.NewTestDataSuite() // Access: suite.ValidHeatFlow, suite.IncompleteFlow, etc. ``` ### Deterministic Testing ```go // Fixed time for consistent results fixedTime := testutils.FixedTime() // Use in assertions or data creation ``` ### Mocking with GoMock ```go // Generate mocks mockgen -source=internal/repository/interface.go -destination=internal/repository/mock_interface.go // Use in tests mockRepo := &mock_interface.MockRepository{} mockRepo.EXPECT().GetByID("id").Return(expectedResult, nil) ``` ## Test Categories - **Unit Tests**: Test individual functions/methods in isolation - **Integration Tests**: Test component interactions (planned with TestContainers) - **BDD Tests**: Behavior-driven tests for business logic ## Best Practices 1. **Test Naming**: Use descriptive names that explain the behavior 2. **Arrange-Act-Assert**: Structure tests clearly 3. **Table-Driven Tests**: For multiple test cases 4. **Parallel Execution**: Tests run in parallel by default 5. **Fixtures**: Use shared test data for consistency 6. **Coverage**: Aim for >80% coverage on critical paths ## Continuous Integration Tests are designed to run efficiently in CI/CD pipelines with: - Fast execution (<30s for unit tests) - No external dependencies for unit tests - Deterministic results - Clear failure reporting