Description
Introduce a plugin architecture that allows adding new test runners, result parsers, and export formats without modifying ModuleTester's core code. This enables the community and internal teams to contribute integrations (e.g., Google Test, dotnet test, custom report formats) as independent packages.
Current behavior
- Test execution, result parsing, and export logic are hardcoded in the core.
- Adding a new test runner or export format requires modifying ModuleTester source code.
- No extension mechanism for third-party contributions.
Expected behavior
- A well-defined plugin API with clear interfaces:
ITestRunner: discover(), execute(), parse_result()
IExporter: export(results, template, output_path)
IResultParser: parse(stdout, stderr, exit_code) -> TestResult
- Plugins are discovered automatically via Python entry points:
[project.entry-points."moduletester.runners"]
gtest = "moduletester_gtest:GoogleTestRunner"
- Built-in runners (Python/guitest) are refactored as internal plugins using the same API.
- Plugin configuration via
moduletester.ini:
[plugins]
enabled = gtest, dotnet, custom_exporter
Implementation ideas
- Define abstract base classes in
moduletester/plugins/base.py.
- Use
importlib.metadata.entry_points() for plugin discovery.
- Refactor existing Python test runner as the reference plugin implementation.
- Provide a
moduletester-plugin-template cookiecutter or minimal example.
- Plugin lifecycle:
register() → configure(ini_section) → execute().
Acceptance criteria
Description
Introduce a plugin architecture that allows adding new test runners, result parsers, and export formats without modifying ModuleTester's core code. This enables the community and internal teams to contribute integrations (e.g., Google Test, dotnet test, custom report formats) as independent packages.
Current behavior
Expected behavior
ITestRunner:discover(),execute(),parse_result()IExporter:export(results, template, output_path)IResultParser:parse(stdout, stderr, exit_code) -> TestResultmoduletester.ini:Implementation ideas
moduletester/plugins/base.py.importlib.metadata.entry_points()for plugin discovery.moduletester-plugin-templatecookiecutter or minimal example.register()→configure(ini_section)→execute().Acceptance criteria
moduletester.ini