-
When bundling does NOT apply: some things are fixed for a whole document and can't vary per measure — the <part-list> and each part's stave configuration (stave count, tab string count, braces). Those stay as separate category_variant.musicxml files. This is why structure_* (different part-lists) and clef_* (single stave vs grand staff vs 4-/6-line tab) are not bundled: each needs a different part/stave structure, not just a different measure. Rule of thumb: bundle what varies per measure (keys, meters, note/rest/accidental/articulation/beam/slur/tie/tuplet variants, voices); keep separate what needs a different part or stave layout.
-
Name a fixture that covers a whole category category.musicxml (e.g. key, time, note, slur). Use category_variant.musicxml only when different part/stave structures force more than one file in that category (e.g. clef_tab_4_string, structure_grand_staff). Categories: structure, clef, key, time, note, rest, accidental, measures, …; match the existing files in tests/integration/__data__/.
-
Register it in tests/integration/render.test.ts by adding testCase('<filename>.musicxml', '<filename>.png') to the TEST_CASES array. Pass any non-default Config as the third argument.
-
Keep TEST_CASES ordered by increasing rendering complexity. A render implementer should be able to build a correct renderer progressively by going through the tests in array order: basic structure before clefs, clefs before key/time signatures, simple notes/rests before accidentals, measures, beams, chords, ties/slurs, tuplets, articulations, voices, system layout, and broad stress cases. Insert new cases where they fit this progression; the array order is the only ordering — there is no numeric prefix. A bundled category fixture sits in its category's slot; let its most complex measure set the position.
-
Above each testCase(...) declaration, write a detailed comment describing what the screenshot should render: the clefs, staves, notes, and any distinctive notation or layout (positions, accidentals, beams, slurs, ledger lines, system breaks, …). Describe what is actually drawn so the comment alone tells a reader what to expect without opening the PNG. Match the descriptive style of the surrounding cases.
-
For cases spanning more than one measure, split the comment by measure for readability. Start with a one-line lead describing the global setup (stave/clef/time signature and any wrap behavior), then add one bulleted line per measure using a stable M<n>: marker (M2-3: for a span). Wrap continuation lines so they align under the bullet text. For multi-voice cases, use inline V<n> markers (e.g. V1, V2) inside each measure bullet. This keeps the comment scannable for humans and greppable for tools, with each M<n> mapping directly to a <measure number="n"> in the fixture. Example:
testCase('dotted_notes.musicxml', 'dotted_notes.png'),
-
Each measure should test only one thing. Vary one feature per measure and keep everything else stable (pitch, duration, clef); don't vary unrelated musical features within a measure unless the variation is part of what that measure is proving. The fixture as a whole deliberately spans many variants of its category — but each measure isolates exactly one.
-
Wrong pattern: when testing articulations, do not vary duration or pitch needlessly; use stable, boring notes unless pitch or duration affects the articulation behavior being tested.
-
Right pattern: when testing beams, varying pitch can be useful if the goal is to show how the beam renders under normal and extreme stem/ledger-line conditions. There should be a clear reason for every extra variation.
-
Keep each measure as small as practical while still demonstrating its variant, and the fixture as a whole no larger than its variants require.
-
Keep generated MusicXML fixtures as simple and barebones as possible; inspect nearby existing files and match their minimal structure and style.