Unit Testing Guide
Relevant source files
The following files were used as context for generating this wiki page:
The Unit Testing Guide provides a comprehensive framework for testing the flext-target-oracle project in isolation. Unit tests are designed to be fast, executing without external dependencies like a live Oracle database by utilizing extensive mocking of the database API and loader components.
The primary goal of the unit test suite is to verify message routing, state management, and configuration validation within the FlextTargetOracle and FlextTargetOracleLoader classes. These tests ensure that the core logic of the Singer target remains robust across changes without the overhead of containerized environments.
Sources: CONTRIBUTING.md:65-67, tests/README.md:55-58
Test Architecture and Infrastructure
The unit testing infrastructure relies on pytest and specialized fixtures defined in conftest.py. Unit tests are identified by the @pytest.mark.unit marker and are located in the tests/unit/ directory.
Key Components for Unit Testing
| Component | Role in Testing |
|---|---|
mock_oracle_api | A MagicMock fixture that simulates the FlextDbOracleApi, returning success results for DDL/DML operations. |
FlextTargetOracleSettings | Pydantic models used to build deterministic configurations for testing. |
r (Railway Result) | Used to assert success or failure of operations using FLEXT's Railway-Oriented Programming patterns. |
isolate_target_oracle_env | Fixture that clears host environment variables to ensure test determinism. |
Sources: tests/conftest.py:44-51, tests/conftest.py:202-218, tests/unit/test_loader.py:17-29
Mocking Strategy
Unit tests mock all external interactions, specifically targeting the FlextDbOracleApi and the internal loader of the target client. This allows developers to test how the target handles various Singer messages (SCHEMA, RECORD, STATE) without performing actual network I/O.
The diagram shows the isolation of the Target class during unit testing, where the Loader and Oracle API are replaced with mock objects returning predictable r (Result) objects.
Sources: tests/unit/test_target.py:23-45, tests/unit/test_loader.py:65-80
Testing the Target Client
The FlextTargetOracle unit tests focus on the canonical target client's ability to initialize, validate configurations, and process Singer message streams.
Core Test Scenarios
- Initialization: Verifying that the target correctly initializes and can perform a (mocked) connection test.
- Message Processing: Ensuring SCHEMA, RECORD, and STATE messages are routed correctly to the loader or state manager.
- Configuration Validation: Testing that
FlextTargetOracleSettingscorrectly handles valid and invalid configurations. - Error Handling: Validating that malformed JSON or unsupported message types result in a
FlextTargetOracleExceptions.ProcessingError.
Sources: tests/unit/test_target.py:53-75, tests/unit/test_target.py:118-132
Singer Message Routing Flow
The target's process_singer_message method acts as a dispatcher. Unit tests verify this flow by checking if specific loader methods are called when a message is processed.
Testing the Loader Component
The FlextTargetOracleLoader unit tests verify buffering logic and the delegation of SQL generation to the db-oracle library.
Key Logic Areas
- Buffering and Finalization:
load_recordshould buffer records until thebatch_sizeis reached orfinalize_all_streamsis called. - Batch Flushing: Tests verify that
_flush_batchcorrectly interacts with the Oracle API'sexecute_manyandbuild_insert_statementmethods. - Table Existence: Ensuring
ensure_table_existsreturns aFlextResult[bool]regardless of the underlying database state (simulated via mocks).
Sources: tests/unit/test_loader.py:46-60, tests/unit/test_loader.py:85-115
Performance Unit Checks
The project includes lean performance-oriented unit tests to ensure that critical code paths, such as readiness checks and state updates, maintain constant time or linear scaling without incurring the cost of integration tests.
| Test Focus | Metric | Threshold |
|---|---|---|
| Readiness Execution | Time | < 0.05s |
| State Message Processing | Scale | Linear (< 2.0s for 2000 msgs) |
| Message Processing | JSON Overhead | No re-parse loops |
Sources: tests/performance/test_performance.py:54-95
Development Workflow
To maintain code quality, the project enforces specific standards through automated checks.
- Run Unit Tests:
make test-unitorpytest -m unit. - Formatting:
make format(uses Black and Ruff). - Type Checking:
make type-check(uses mypy). - Linters:
make lint.
Sources: CONTRIBUTING.md:46-51, CONTRIBUTING.md:92-106
The Unit Testing Guide ensures that developers can verify core target logic rapidly. By isolating components and using performance unit checks, the suite provides a high-confidence baseline before proceeding to slower integration and e2e tests.