Skip to content

Testing

Tests require Docker for Redis and Virtuoso containers.

Terminal window
uv sync
Terminal window
./test/start-test-databases.sh

This starts:

  • Redis on port 6381 (databases 0 and 5)
  • Virtuoso data on port 8805 (SPARQL), 1105 (ISQL)
  • Virtuoso provenance on port 8806 (SPARQL), 1106 (ISQL)

Wait for the script to confirm services are ready.

Terminal window
uv run coverage run --rcfile=test/coverage/.coveragerc

View coverage report:

Terminal window
uv run coverage report

Generate HTML report:

Terminal window
uv run coverage html -d htmlcov
Terminal window
./test/stop-test-databases.sh

Run a single test file:

Terminal window
uv run python -m pytest test/curator_test.py -v

Run tests matching a pattern:

Terminal window
uv run python -m pytest test/ -k "test_doi" -v

Tests are in the test/ directory:

FileTests
curator_test.pyData validation and normalization
creator_test.pyRDF generation
meta_process_test.pyEnd-to-end pipeline
editor_test.pyPost-processing modifications
finder_test.pyEntity lookup
group_entities_test.pyMerge grouping algorithm

Test fixtures use minimal datasets in test/ subdirectories.

Tests run automatically on push and pull request via .github/workflows/run_tests.yml:

name: Run tests
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]

The workflow:

  1. Sets up Python with UV
  2. Installs dependencies
  3. Starts Redis and Virtuoso containers
  4. Runs tests with coverage
  5. Uploads coverage report

Tests run on Python 3.10, 3.11, 3.12, and 3.13.

Test files: *_test.py Test functions: test_*

Use pytest fixtures for common setup:

@pytest.fixture
def redis_handler():
return RedisCounterHandler(
host="localhost",
port=6381,
db=5,
supplier_prefix="060"
)
def test_counter_increment(redis_handler):
initial = redis_handler.read_counter("br")
redis_handler.increment_counter("br")
assert redis_handler.read_counter("br") == initial + 1

Tests that need SPARQL use the test Virtuoso instance:

SPARQL_ENDPOINT = "http://localhost:8805/sparql"
def test_sparql_query():
finder = ResourceFinder(ts=SPARQL_ENDPOINT, base_iri="https://w3id.org/oc/meta")
# Test queries...

Tests should clean up after themselves:

def test_with_cleanup(redis_handler):
try:
# Test code...
finally:
# Cleanup
redis_handler.delete_counter("br")

Or use fixtures with cleanup:

@pytest.fixture
def temp_graph():
g = Graph()
yield g
# Cleanup happens automatically after test

Aim for high coverage on:

  • oc_meta.core.curator - Data validation logic
  • oc_meta.core.creator - RDF generation
  • oc_meta.lib.finder - Entity lookup
  • oc_meta.lib.cleaner - Identifier normalization

Lower coverage is acceptable for:

  • CLI scripts (tested via integration tests)
  • Error handling paths (hard to trigger in tests)