Back to course overview
Module 4Governance: making the numbers trustworthy 13 min

Testing the semantic layer

Write tests that pin your metric definitions in place so future changes can't silently break the numbers.

Your metric definitions are now business-critical infrastructure. Treat them like it: test them. A test suite lets you refactor the compiler or tweak a metric and instantly know if any number moved.

What's worth testing

  • Known totals. Total revenue is $743,772.80 for the seeded data. Pin it — if it ever changes unexpectedly, a definition drifted.
  • Invariants. The sum of revenue across all channels must equal total revenue. Parts should sum to the whole.
  • Refusals. An impossible metric×dimension combination (marketing spend by product category) should raise SemanticError, not return data.
  • Ratios. AOV should equal revenue ÷ orders_count computed independently.
test_semantic_layer.pypython
from semantic_layer import SemanticLayer, SemanticError

L = SemanticLayer()

def test_total_revenue():
    assert L.query(["revenue"])["rows"][0]["revenue"] == 743772.8

def test_channels_sum_to_total():
    total = L.query(["revenue"])["rows"][0]["revenue"]
    by_channel = L.query(["revenue"], ["channel"])["rows"]
    assert round(sum(r["revenue"] for r in by_channel), 2) == total

def test_impossible_combo_is_refused():
    try:
        L.query(["marketing_spend"], ["product_category"])
        assert False, "should have refused"
    except SemanticError:
        pass

Running the tests

bashbash
pip install pytest
pytest test_semantic_layer.py     # pytest auto-discovers every test_* function

# or, with no new installs — add a __main__ runner to the file, then:
python3 test_semantic_layer.py

For the no-pytest route, the runner is one line at the bottom of the file: if __name__ == "__main__": test_total_revenue(); test_channels_sum_to_total(); test_impossible_combo_is_refused(). Plain asserts either way — and both commands assume your venv is active and you're in the starter-kit root, where semantic_layer/ is importable.

Tests are the safety net for AI, too

In Part 2 the agent will lean entirely on these metrics. If a definition silently breaks, every AI answer becomes wrong. A green test suite is your guarantee that the foundation under the agent is solid.

Note

The 'parts sum to the whole' test is especially powerful — it catches fan-out, missing filters, and join bugs in one assertion, because all of those make the pieces stop adding up.