Unit Testing Core EDK
Relevant source files
The following files were used as context for generating this wiki page:
Unit testing within the Meltano Extension Developer Kit (EDK) focuses on validating the core lifecycle methods of extensions, ensuring robust subprocess management, and verifying the integrity of generated extension templates. The testing suite utilizes pytest to exercise the ExtensionBase interface, the Invoker utility for process execution, and the copier template generation logic.
The primary objective is to guarantee that custom extensions correctly implement required methods such as invoke and describe, and that the pass_through_invoker correctly orchestrates the execution flow including pre- and post-invocation hooks. Sources: tests/test_meltano_edk.py, tests/test_process.py
Extension Interface Testing
Testing the extension interface involves creating a concrete implementation of the ExtensionBase abstract class. This allows developers to verify the execution order of lifecycle hooks and the formatting of capability descriptions.
Lifecycle Hook Validation
Tests verify that the pass_through_invoker correctly triggers pre_invoke, invoke, and post_invoke in the specific sequence required by the EDK. A common pattern is to use a history list to track call order and arguments.
The diagram shows the synchronous execution flow managed by the pass-through utility. Sources: meltano/edk/extension.py:118-161, tests/test_meltano_edk.py:65-73
Capabilities and Formatting
Tests validate that the describe method returns a valid models.Describe object and that describe_formatted correctly serializes this data into JSON or YAML.
| Test Case | Method Validated | Expected Output Type |
|---|---|---|
test_canary | describe() | models.Describe object |
test_describe_formatted_json | describe_formatted(DescribeFormat.json) | JSON String |
test_describe_formatted_yaml | describe_formatted(DescribeFormat.yaml) | YAML String |
Sources: tests/test_meltano_edk.py:38-63, meltano/edk/extension.py:100-116
Subprocess and Invoker Testing
The Invoker class is responsible for executing external binaries. Testing this component involves mocking asyncio.create_subprocess_exec to verify that arguments, environment variables, and working directories are correctly passed to the operating system.
Asynchronous Execution Flow
The testing of Invoker._exec ensures that subprocesses are created with the correct pipes and that standard streams (stdout/stderr) are processed.
This flowchart illustrates the internal logic of the asynchronous execution helper. Sources: meltano/edk/process.py:106-155, tests/test_process.py:34-52
Process Mocking
Tests use unittest.mock to simulate process behavior, including EOF signals and return codes. This ensures that the Invoker handles stream reading and process termination correctly without requiring actual binary execution during unit tests. Sources: tests/test_process.py:11-31
Template Generation Testing
The EDK includes a copier template for scaffolding new extensions. Testing this system ensures that the generated code is syntactically correct and adheres to project standards.
Validation Pipeline
The template test follows a multi-stage validation process:
- Generation:
copier.run_copygenerates a project in a temporary directory using a set of test data. - Static Analysis:
mypyis run against the generated files to check for type errors. - Linting:
ruff checkvalidates coding standards. - Formatting:
ruff format --checkensures the generated code matches the EDK style.
Sources: tests/copier_template/test_generated.py:34-79
Template Configuration
The copier.yml file defines the variables used during testing, such as extension_id, library_name, and wrapper_target_name. Tests verify that these variables are correctly substituted into the generated pyproject.toml and extension files. Sources: copier.yml:1-44
Summary of Core Test Components
| Component | File Path | Testing Focus |
|---|---|---|
ExtensionBase | meltano/edk/extension.py | Lifecycle hooks and description formatting |
Invoker | meltano/edk/process.py | Subprocess creation and IO streaming |
Models | meltano/edk/models.py | Data structure integrity for extension capabilities |
Copier Template | copier_template/ | Code generation and static analysis compliance |
Unit testing in the EDK ensures that the framework remains a reliable foundation for building Meltano extensions by strictly validating the interface contract and the underlying execution mechanisms. Sources: tests/test_meltano_edk.py, tests/test_process.py, tests/copier_template/test_generated.py