Testing Practices
Relevant source files
The following files were used as context for generating this wiki page:
- AGENTS.md
- AGENT_NOTES.md
- apps/api/src/test/kotlin/com/briefy/api/api/SourceControllerTest.kt
- apps/api/src/test/kotlin/com/briefy/api/application/briefing/BriefingExecutionOrchestrationIT.kt
- apps/api/src/test/kotlin/com/briefy/api/domain/knowledgegraph/source/SourceTest.kt
- apps/api/src/test/kotlin/com/briefy/api/application/briefing/BriefingGenerationServiceTest.kt
- apps/api/src/test/kotlin/com/briefy/api/api/BriefingControllerTest.kt
The Briefy project employs a multi-layered testing strategy to ensure the reliability of its AI-driven knowledge graph and briefing generation engine. The testing suite is primarily concentrated in the backend (apps/api), utilizing Kotlin, JUnit 5, and Spring Boot's testing infrastructure to validate domain logic, application services, and API endpoints.
Testing is integrated into the development workflow via CI (GitHub Actions), which executes backend tests on every Pull Request and push to the main branch. The project emphasizes behavior-driven test naming and strict separation between unit tests and integration tests.
Sources: AGENTS.md:14-38, AGENT_NOTES.md:Mistakes Log
Test Hierarchy and Organization
The testing architecture is divided into three primary levels: Unit Tests, Integration Tests (IT), and API/Controller tests.
Unit Testing
Unit tests focus on individual domain entities and isolated services. These tests use Mockito for dependency mocking to ensure that logic remains decoupled from infrastructure.
- Domain Tests: Validate state transitions and business rules within entities like
SourceandBriefing. - Service Tests: Verify application logic, such as
BriefingGenerationServiceorSourceContentFormatterService, by mocking repositories and AI adapters.
Integration Testing (IT)
Integration tests validate the interaction between multiple components and the database.
- Database Integration: Uses Testcontainers with PostgreSQL (specifically
pgvector/pgvector:pg16) to verify real database interactions, Flyway migrations, and complex SQL queries. - Orchestration Tests: Validate complex workflows, such as the
BriefingExecutionOrchestrationIT, which ensures the entire AI subagent loop and synthesis runner work in concert.
API and Controller Testing
Controller tests use MockMvc to verify REST endpoints, request/response mapping, security constraints (via CurrentUserProvider mocks), and status codes.
Sources: AGENTS.md:31-35, apps/api/src/test/kotlin/com/briefy/api/domain/knowledgegraph/source/SourceTest.kt:1-10, apps/api/src/test/kotlin/com/briefy/api/application/briefing/BriefingExecutionOrchestrationIT.kt:40-55
Testing Infrastructure Configuration
The project utilizes specific Spring Boot and JUnit 5 configurations to manage test environments.
Standard Test Annotations
| Annotation | Purpose |
|---|---|
@SpringBootTest | Loads the full application context for integration or controller tests. |
@AutoConfigureMockMvc | Enables MockMvc for testing controller layers without a full server. |
@ActiveProfiles("test") | Switches to the test profile to use H2 or test-specific configuration. |
@Testcontainers | Manages the lifecycle of Docker containers for integration tests. |
@MockitoBean | Replaces a Spring bean with a Mockito mock within the application context. |
Sources: apps/api/src/test/kotlin/com/briefy/api/api/SourceControllerTest.kt:40-50, apps/api/src/test/kotlin/com/briefy/api/application/briefing/BriefingExecutionOrchestrationIT.kt:40-50
Database Management in Tests
For integration tests, the system frequently cleans up the database before each test to ensure isolation. In the BriefingExecutionOrchestrationIT, JdbcTemplate is used to truncate tables in a specific order to respect foreign key constraints.
The diagram shows the standard lifecycle for integration tests requiring a clean database state.
Sources: apps/api/src/test/kotlin/com/briefy/api/application/briefing/BriefingExecutionOrchestrationIT.kt:85-105
Testing State Transitions
A critical part of the testing practice involves validating entity state machines, particularly for Source and Briefing entities which have complex lifecycles.
Source Lifecycle Testing
Tests in SourceTest.kt verify that the Source entity transitions correctly between statuses such as SUBMITTED, EXTRACTING, ACTIVE, and FAILED.
| Initial Status | Action | Resulting Status |
|---|---|---|
SUBMITTED | startExtraction() | EXTRACTING |
EXTRACTING | completeExtraction() | ACTIVE |
EXTRACTING | failExtraction() | FAILED |
ACTIVE | archive() | ARCHIVED |
Sources: apps/api/src/test/kotlin/com/briefy/api/domain/knowledgegraph/source/SourceTest.kt:12-70
Briefing Execution Testing
Testing the briefing generation involves mocking the AI engine to return specific results and ensuring the service updates the briefing status and persists citations.
The sequence diagram illustrates how BriefingGenerationServiceTest validates the transition from APPROVED to READY using a mocked AI engine.
Sources: apps/api/src/test/kotlin/com/briefy/api/application/briefing/BriefingGenerationServiceTest.kt:60-100
Guidelines for Authors
Based on the project's internal documentation and identified mistakes, developers must follow these practices:
- Naming: Backend tests must end in
*Test.kt. Use descriptive names wrapped in backticks (e.g.,`retry transitions from FAILED to SUBMITTED`). - Concurrency: Never run Gradle
testtasks in parallel within the same module, as they may collide when writing XML reports. - Assertions: Avoid index-based JSON assertions (e.g.,
jsonPath("$.items[0]")) when result order is not guaranteed. Instead, use ID-based filtering (e.g.,jsonPath("$.items[?(@.id=='...')]")). - Mocking: Explicitly stub interface properties like
extractionProvider.idwhen using Mockito, as interface properties default to null in unstubbed mocks. - Environment: Use
@DynamicPropertySourceto inject container-managed database credentials into the Spring environment for integration tests.
Sources: AGENTS.md:31-35, AGENT_NOTES.md:Mistakes Log, apps/api/src/test/kotlin/com/briefy/api/application/briefing/BriefingExecutionOrchestrationIT.kt:330-340
Technical Summary
The Briefy testing framework prioritizes high-fidelity integration tests using Testcontainers and PostgreSQL pgvector, alongside strict unit tests for domain logic. By leveraging Spring Boot's test profile and MockMvc, the project ensures that both API contracts and internal state transitions are robustly validated.
Sources: apps/api/src/test/kotlin/com/briefy/api/application/briefing/BriefingExecutionOrchestrationIT.kt, AGENT_NOTES.md