Quality and validation#
Contributor-facing expectations for tests, scientific validation, coding standards, and documentation. For the full reference, see Code standards, Documentation standards, and Architecture.
Command examples live in Practical workflow.
Testing requirements#
For complete information about test coverage requirements, test types, writing tests, and running tests, please refer to the Code standards documentation.
Key points for contributors#
Minimum coverage: ≥ 60% on code touched by the PR (
--cov-fail-under=60)Test types: Unit, baseline, extended, heavy: see Code standards for the full marker reference
Use pytest: The project uses pytest for all testing
Test-driven development (TDD)#
BioPAL strongly encourages contributors to embrace test-driven development (TDD). This development process “relies on the repetition of a very short development cycle: first the developer writes an (initially failing) automated test case that defines a desired improvement or new function, then produces the minimum amount of code to pass that test.”
Why write tests first?
Clarifies requirements: Writing tests first forces you to think about what the code should do before implementing it
Better design: Tests help you design cleaner interfaces and APIs
Prevents regressions: Having tests in place ensures that future changes don’t break existing functionality
Documentation: Tests serve as executable documentation showing how code should be used
Confidence: Tests give you confidence to refactor and improve code
The TDD cycle:
Red: Write a failing test that describes the desired behavior
Green: Write the minimum code needed to make the test pass
Refactor: Improve the code while keeping tests passing
Often the test can be taken from the original GitHub issue. However, it is always worth considering additional use cases and writing corresponding tests.
Adding tests is one of the most common requests after code is pushed to BioPAL. Therefore, it is worth getting in the habit of writing tests ahead of time so that this is never an issue.
Performance testing#
Performance matters and it is worth considering whether your code has introduced performance regressions. BioPAL may include a suite of benchmarking tests to enable easy monitoring of the performance of critical operations.
When to run performance tests:
After making changes to core algorithms
When optimizing code for speed
Before submitting a pull request that affects performance-critical code
When investigating performance issues
Performance considerations:
Memory usage: Monitor memory consumption, especially for large datasets
CPU usage: Check if algorithms can be parallelized
I/O operations: Minimize file read/write operations where possible
Vectorization: Use NumPy vectorized operations instead of Python loops
Caching: Consider caching expensive computations when appropriate
Reporting performance changes:
If your changes affect performance, include performance metrics in your pull request:
Execution time before and after your changes
Memory usage comparisons
Any optimizations made
Benchmark results if available
For detailed commands on how to write tests, run tests, and use performance testing tools, see Testing: code examples and commands).
Scientific validation#
When validation is required#
Tier 1-2 contributions must include scientific validation.
Reference datasets#
Validation relies on TDS (Test Data Sets): golden datasets used as a reference to compare processor outputs. Tests are organized in three levels within each module:
test/baseline/: small reference outputs checked on every PR (marker:baseline)test/extended/: broader validation for Tier 1+ (marker:extended)test/heavy/: full scientific regression for Tier 2 (marker:heavy)
⚠ The extended and heavy TDS are not distributed with the repository. A procedure to retrieve them will be made available shortly. In the meantime, these pipelines run exclusively on CI servers.
Validation workflow#
All Tier 1-2 pull requests are automatically validated using a standardized validation script that runs in the CI/CD pipeline. The validation process works as follows:
Automatic CI Validation: When you submit a Tier 1-2 PR, the CI/CD pipeline automatically:
Executes the validation script on a predetermined Test Data Set (TDS)
Compares your changes against the nominal version (baseline) on the same TDS
Calculates metrics: RMSE, bias, correlation, etc.
Generates a validation report with metrics and visualizations
The report is automatically attached to your PR
Custom Dataset Validation (Optional): If you need validation on a specific dataset that is not part of the standard TDS:
Request access to a specific dataset through the PR description
The validation will be executed on the requested dataset
A separate report will be generated for the custom dataset
This is in addition to (not a replacement for) the standard TDS validation
Important: The main pull request will always be compared with the nominal version on the same predetermined TDS. Custom dataset validations are supplementary and do not replace the standard validation.
Validation report structure#
The validation script automatically generates a comprehensive HTML report that includes:
Plots for all variables: Visualizations showing the results for each variable processed
Comparison with nominal version: Side-by-side comparisons and difference plots between the nominal (baseline) version and your new feature
Metrics and statistics: RMSE, bias, correlation, and other relevant metrics for each variable
Summary tables: Tabulated results for easy review
The HTML report is automatically generated by the validation script and attached to your PR. No manual notebook creation is required - the entire validation process is automated.
Validation report storage#
HTML Report: Automatically generated and attached to the PR
Report Location: Available through the CI/CD pipeline artifacts and linked in the PR
Metrics Summary: Key metrics are also included in the PR description for quick reference
Validation execution#
Standard Validation (Automatic for Tier 1-2):
Runs automatically in the CI/CD pipeline for all Tier 1-2 PRs
Uses the TDS golden dataset consistent across all validations
Compares your changes against the baseline reference on the same TDS
Produces a validation report attached to the PR as a CI artefact
Extended and heavy TDS are not available locally: all Tier 1-2 validations run on CI servers
Custom Dataset Validation (On Request):
If you need validation on a specific dataset beyond the standard TDS, request it in your PR description
Custom validations run on CI servers with access to larger datasets
Requires approval from ESA for dataset access
Supplementary: does not replace the mandatory TDS validation
Data Access:
Tier 0: Baseline tests only (no TDS required)
Tier 1: Extended TDS validation (automatic via CI)
Tier 2: Heavy TDS validation (automatic via CI) + custom dataset on request
Coding standards#
For complete coding standards, naming conventions, formatting rules, type hints, error handling, and logging guidelines, please refer to the Code standards documentation.
Key points:
Follow PEP 8 with modifications enforced by
blackUse type hints for all public functions
Run
black,ruff, andmypybefore committingSet up pre-commit hooks for automatic code quality checks
Backwards compatibility#
Please try to maintain backwards compatibility. BioPAL has a growing number of users with lots of existing code, so don’t break it if at all possible. If you think breakage is required, clearly state why as part of the pull request.
Principles:
Avoid breaking changes: Changes that break existing user code should be avoided unless absolutely necessary
Deprecation cycle: When breaking changes are necessary, use a deprecation cycle to warn users before removing functionality
Clear communication: Document breaking changes clearly in release notes and migration guides
Versioning: Breaking changes should typically be reserved for major version releases
Be especially careful when changing function and method signatures, because any change may require a deprecation warning. Instead of simply raising an error when users pass deprecated arguments, you should catch them and emit a deprecation warning that clearly states what is deprecated, what to use instead, and when it will be removed.
Deprecation cycle process:
Add deprecation warning: In the current version, add a
DeprecationWarningthat clearly states:What is deprecated
What to use instead
When it will be removed (typically next major version)
Update documentation:
Mark deprecated features in the documentation
Provide migration examples
Update docstrings with deprecation notices
Wait for next major version: Remove the deprecated functionality only in a major version release
Update release notes: Clearly document all deprecations and breaking changes
For code examples showing how to implement deprecation warnings, see Coding standards: code examples).
When breaking changes are acceptable:
Security vulnerabilities: Fixing security issues may require breaking changes
Scientific correctness: If the current implementation is scientifically incorrect, breaking changes may be necessary
Major architectural improvements: Significant improvements that benefit the entire project
Removing clearly broken or unused features: Features that are known to be broken or unused
Always discuss breaking changes in an issue or pull request before implementing them, and ensure they are clearly documented.
Documentation standards#
If you’re not the developer type, contributing to the documentation is still of huge value. You don’t even have to be an expert on BioPAL to do so! In fact, there are sections of the docs that are worse off after being written by experts. If something in the docs doesn’t make sense to you, updating the relevant section after you figure it out is a great way to ensure it will help the next person.
For complete information about documentation standards, docstring format (NumPy style), writing conventions, documentation types, and best practices, please refer to the Documentation standards documentation.
Key points:
Docstrings should follow the NumPy Docstring Standard
Standalone documentation should provide why and when to use features, with examples and tutorials
Keep documentation up to date: When you change code, update the corresponding documentation
Write for your past self: Document things that weren’t obvious to you when you first learned them
Documentation updates required#
When contributing, update:
User guides (if user-facing changes)
Developer guides (if workflow changes)
API documentation (if adding/modifying functions)
Notebooks (if examples affected)
Product definitions (if products change)
For detailed commands on how to build and preview documentation, see Documentation standards: code examples).
Previous: CI automation and contribution tiers | Next: Architecture