mustrd

Spec-By-Example for RDF & SPARQL

Test your SPARQL queries and transformations with precision, using Given-When-Then principles.

# One spec. Given data. When query. Then result.
:my_test
    must:given [ a must:FileDataset ;
                 must:file "test/data/given.ttl" ] ;
    must:when  [ a must:TextSparqlSource ;
                 must:queryText "CONSTRUCT { ?s ?p ?o }
                                WHERE { ?s a ex:Person ; ?p ?o }" ;
                 must:queryType must:ConstructSparql ] ;
    must:then  [ a must:FileDataset ;
                 must:file "test/data/expected.ttl" ] .

Define your data, run your query, check the result. All in Turtle.

What mustrd is

A pytest plugin

Add --mustrd to your pytest command. Specs become tests. Results show in your runner, CI, and VS Code.

Triplestore agnostic

Run specs against embedded RDFLib, GraphDB, or Anzo. Same specs, different engines. Swap with configuration, not code.

Spec-By-Example

Inspired by Cucumber. Define concrete examples of what your query should do, not abstract assertions about what it might.

Not SHACL

SHACL validates data structure. mustrd validates data transformations. Your query produces the right triples? mustrd checks.

Given-When-Then

Every spec follows the same shape. Load data, run a query, check the output.

Given

The input dataset. A Turtle file, inline statements, an Anzo graphmart, or inherited state.

must:given [
  a must:FileDataset ;
  must:file "data/input.ttl"
] ;

When

The SPARQL action. Inline text, a file reference, or a query builder source. SELECT, CONSTRUCT, or UPDATE.

must:when [
  a must:FileSparqlSource ;
  must:file "sparql/enrich.rq" ;
  must:queryType must:UpdateSparql
] ;

Then

The expected result. An RDF graph, a table of bindings, CSV/Excel, or an empty result.

must:then [
  a must:FileDataset ;
  must:file "data/expected.ttl"
] .

Query types

mustrd validates across SPARQL's full query surface.

TypeWhat it doesResult compared as
SELECTReturn variable bindingsTable (pandas DataFrame)
CONSTRUCTBuild an RDF graphGraph isomorphism
UPDATEINSERT/DELETE triplesModified graph comparison
ASKBoolean existence checkTrue/false
DESCRIBEDescribe a resourceGraph isomorphism

Triplestore support

Write specs once. Run them against any supported engine.

EngineProtocolNotes
RDFLibEmbedded (in-memory)Default. No server needed. Zero config.
GraphDBHTTP SPARQL endpointRepository-based. Optional named graphs.
AnzoHTTP REST APIGraphmart layers, query builders, AnzoGraph.

Flexible datasets

Givens and thens support multiple data formats.

TypeDescription
FileDatasetRDF file — Turtle, NTriples, N3, RDF/XML, TriX
StatementsDatasetInline reified RDF statements in the spec
TableDatasetInline tabular bindings for SELECT results
OrderedTableDatasetTabular data with row ordering (ORDER BY)
FolderDatasetFile path passed as a runtime argument
EmptyTable / EmptyGraphExpect no results
InheritedDatasetKeep existing graph state (chain specs)

VS Code integration

Specs appear as tests in the Test Explorer. Click to run, see diffs on failure.

// settings.json
{
  "python.testing.pytestArgs": [
    "--mustrd",
    "--md=junit/github_job_summary.md",
    "--config=test/test_config_local.ttl"
  ]
}

Status

Get started

pip install mustrd
pytest --mustrd --config=test/mustrd_configuration.ttl

GitHub · mustrd@semanticpartners.com