From 4bdb210ead89c239db19559d7b8e5038a8eda34c Mon Sep 17 00:00:00 2001 From: Beth Probert Date: Fri, 19 Jun 2026 16:45:14 +0100 Subject: [PATCH 1/5] Get CodeCov badge working --- .github/workflows/test.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 683408fc..0fea01d9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -168,6 +168,13 @@ jobs: send-summary-comment: true show-annotations: "warning" + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ./coverage.lcov + fail_ci_if_error: false + test-against-ofm-v3: runs-on: ubuntu-latest defaults: From 29a3e01ff0d405bc304b043b903f6e94d9dfd1d6 Mon Sep 17 00:00:00 2001 From: Beth Probert Date: Fri, 19 Jun 2026 17:00:31 +0100 Subject: [PATCH 2/5] Try updating badge for coverage to another tool --- .github/workflows/test.yml | 31 ++++++++++++++++++++++--------- README.md | 2 +- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0fea01d9..76b015ad 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -77,13 +77,15 @@ jobs: run: flake8 src - name: Test with pytest - run: pytest --cov=src --cov-report=lcov + run: pytest --cov=src --cov-report=lcov --cov-report=json - name: Upload code coverage uses: actions/upload-artifact@v4 with: name: coverage-${{ matrix.python }} - path: ./coverage.lcov + path: | + ./coverage.lcov + ./coverage.json - name: Analyse with MyPy run: mypy @@ -136,6 +138,24 @@ jobs: with: name: coverage-3.12 + - name: Parse coverage percentage + id: get-coverage + run: | + COVERAGE=$(jq -r '.totals.percent_covered_display' coverage.json) + echo "coverage=$COVERAGE" >> $GITHUB_OUTPUT + + - name: Update Coverage Badge + # Only run this on the main branch so PRs don't overwrite the main badge + if: github.ref == 'refs/heads/main' + uses: Schneegans/dynamic-badges-action@v1.7.0 + with: + auth: ${{ secrets.GIST_SECRET }} + gistID: 936bcec8e1815a49d1e7f947924ffa3f + filename: labthings-fastapi-coverage.json + label: coverage + message: ${{ steps.get-coverage.outputs.coverage }}% + color: green + - name: Download code coverage report for base branch id: download-base-coverage continue-on-error: true @@ -168,13 +188,6 @@ jobs: send-summary-comment: true show-annotations: "warning" - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./coverage.lcov - fail_ci_if_error: false - test-against-ofm-v3: runs-on: ubuntu-latest defaults: diff --git a/README.md b/README.md index 9395a8ec..c73cd985 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![codecov](https://codecov.io/gh/rwb27/labthings-fastapi/branch/main/graph/badge.svg?token=IR4QNA8X6M)](https://codecov.io/gh/rwb27/labthings-fastapi) +![Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/bprobert97/936bcec8e1815a49d1e7f947924ffa3f/raw/labthings-fastapi-coverage.json) [![Documentation Status](https://readthedocs.org/projects/labthings-fastapi/badge/?version=latest)](https://labthings-fastapi.readthedocs.io/en/latest/?badge=latest) # labthings-fastapi From d267abb83ea49c5798f1d44d5f565b7c1124f44c Mon Sep 17 00:00:00 2001 From: Beth Probert Date: Fri, 19 Jun 2026 17:04:54 +0100 Subject: [PATCH 3/5] Delete main branch check --- .github/workflows/test.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 76b015ad..40fe33ba 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -145,8 +145,6 @@ jobs: echo "coverage=$COVERAGE" >> $GITHUB_OUTPUT - name: Update Coverage Badge - # Only run this on the main branch so PRs don't overwrite the main badge - if: github.ref == 'refs/heads/main' uses: Schneegans/dynamic-badges-action@v1.7.0 with: auth: ${{ secrets.GIST_SECRET }} From c863073726567bdf8f14fc65d35d40792f469ea5 Mon Sep 17 00:00:00 2001 From: Beth Probert Date: Fri, 19 Jun 2026 17:10:10 +0100 Subject: [PATCH 4/5] Add back in main branch check --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 40fe33ba..76b015ad 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -145,6 +145,8 @@ jobs: echo "coverage=$COVERAGE" >> $GITHUB_OUTPUT - name: Update Coverage Badge + # Only run this on the main branch so PRs don't overwrite the main badge + if: github.ref == 'refs/heads/main' uses: Schneegans/dynamic-badges-action@v1.7.0 with: auth: ${{ secrets.GIST_SECRET }} From 7ba5ae91240dd5319ded7d8477044fc242c5f4f4 Mon Sep 17 00:00:00 2001 From: Beth Probert Date: Fri, 19 Jun 2026 17:38:24 +0100 Subject: [PATCH 5/5] Add testing.md file --- docs/source/testing.md | 85 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 docs/source/testing.md diff --git a/docs/source/testing.md b/docs/source/testing.md new file mode 100644 index 00000000..47945290 --- /dev/null +++ b/docs/source/testing.md @@ -0,0 +1,85 @@ +# Testing `labthings-fastapi` + +Our test suite ensures the framework functions correctly, maintains code quality, and integrates seamlessly with static type checkers. + +## Continuous Integration (CI) Pipeline + +When you submit a Pull Request (PR), our GitHub Actions CI pipeline automatically runs a comprehensive suite of checks. Your PR must pass these checks before it can be merged. + +Here is what the CI pipeline tests: + +* **Matrix Testing:** We run the core test suite (`pytest`) and static type checks (`mypy`) across Python versions 3.10, 3.11, 3.12, and 3.13. +* **Code Quality & Security:** The pipeline runs `ruff` (formatting and linting), `flake8` (docstrings), `codespell` (spelling), and a `pip-audit` to check for dependency vulnerabilities. +* **Coverage:** We track code coverage. A report is generated on your PR to show if your changes increased or decreased overall test coverage. +* **Dependency Checks:** We run the tests twice: once with pinned dependencies (`dev-requirements.txt`) for reproducibility, and once with unpinned dependencies (`.[dev]`) to catch upstream breakages early. +* **Downstream Integration:** The pipeline installs your version of `labthings-fastapi` alongside the `v3` branch of the OpenFlexure Microscope Server. It then runs the entire OFM test suite (unit, integration, and lifecycle) to guarantee backwards compatibility. *(Note: You can target a specific OFM branch by adding `OFM-Feature-Branch: branch-name` to your PR description).* + +--- + +## Running Core Tests Locally + +To ensure your code will pass CI, you should run these checks locally before pushing your commits. + +### 1. Local Environment Setup + +We recommend running the test suite using the pinned development dependencies to mirror the primary CI environment. Ensure you have cloned the repository, then install the package and dependencies: + +```bash +git clone https://github.com/labthings/labthings-fastapi.git +cd labthings-fastapi +pip install -e . -r dev-requirements.txt +``` + +### 2. Linting, Formatting, and Spelling + +Check that your code adheres to the project's formatting and style guidelines from the root of the repository: + +* **Linting:** `ruff check .` +* **Formatting:** `ruff format --check .` +* **Spelling:** `codespell .` +* **Docstrings:** `flake8 src` + +### 3. Static Type Checking + +`labthings-fastapi` is designed to be fully type-hinted. We explicitly test that `mypy` can infer the correct types for `Thing` attributes. Run static type checking across the source code and our dedicated typing tests folder: + +```bash +mypy src typing_tests +``` + +### 4. Unit Tests & Coverage + +We use `pytest` for our core test suite. Execute the unit tests and generate a coverage report using: + +```bash +pytest --cov=src +``` + +--- + +## Downstream Integration Testing Locally + +Because `labthings-fastapi` underpins the [OpenFlexure Microscope software], major architectural changes should be tested against the downstream server locally. This matches the `test-against-ofm-v3` job in our CI pipeline. + +Assuming you have both repositories cloned in the same parent directory: + +```bash +# 1. Setup the OpenFlexure Microscope Server +cd ../openflexure-microscope-server +git checkout v3 +pip install -e .[dev] + +# 2. Install your local version of labthings-fastapi +pip install -e ../labthings-fastapi + +# 3. Pull the OFM web app (required for integration) +python ./pull_webapp.py + +# 4. Run the OFM Test Suite +pytest # Run OFM unit tests +pytest tests/integration_tests # Run OFM integration tests +python tests/lifecycle_test/testfile.py # Run OFM lifecycle tests +mypy src # Run OFM static type checks +``` + +[OpenFlexure Microscope software]: https://gitlab.com/openflexure/openflexure-microscope-server/ \ No newline at end of file