Authoring Guide
Reusing logic — Run Test vs. User-Defined
Two ways to share a step sequence across tests. When to use Run Test (calls another test by name) and when to use User-Defined templates (embedded, editable, propagating).
You'll quickly find sequences you want to reuse: a login flow, a "navigate to settings" pattern, a "set up a clean account" fixture. Mavster has two reuse mechanisms — they look similar from the outside but feel very different in practice.
At a glance
| Run Test | User-Defined template | |
|---|---|---|
| Where the sequence lives | A separate, owned test in the same project | A global template available to every project on your Mac |
| What you see in the call site | A single chip: "Run 'login' test" | The full sequence, embedded as editable steps |
| Edit the source, propagate? | Yes — every Run Test step automatically calls the latest version | Yes — template edits propagate, except to locally-overridden steps |
| Edit the call site without affecting source? | No — the called test is the same test | Yes — local overrides flag a step so future template edits skip it |
| Cross-project reuse? | No — Run Test resolves names within the current project | Yes — templates are global to the Mac |
| Run history attribution | Attributed to the called test | Attributed to whichever test embeds the instance |
| Recursion / nesting | Run Test can call Run Test can call Run Test | One level (children of children are not supported) |
| Per-call argument values | Arguments dictionary on the Run Test step | Arguments dictionary on the User-Defined instance |
Pick Run Test when…
- The sequence has its own meaningful identity (you'd name it "Sign-In Test" or "Setup Test", not "the steps that go before every checkout").
- You want a single source of truth and don't need per-call-site customization.
- You want recursive composition — a smoke suite that's a sequence of Run Test steps, where each called test is itself composed of Run Test steps.
- You want per-test history for the called sequence — every call shows up in the called test's run history with cost and pass/fail.
Pick User-Defined when…
- The sequence is a building block, not a standalone test ("the dialog dismiss pattern", "the standard list-row tap-and-confirm").
- You want call sites to show the full sequence inline so the test reads top-to-bottom.
- You want the template available across every project — User-Defined templates live globally on your Mac.
- You sometimes need to tweak one instance without touching other instances.
Combine both
The two mechanisms compose. A common pattern:
- A
signupUser-Defined template wrapping the field-by-field form interaction. - A
signup-testtest that uses thesignuptemplate and surrounds it with project-specific Visual Asserts. - A
smoke-suitetest that callssignup-test(and many others) via Run Test.
The User-Defined template handles UI-level reuse; the Run Test step handles test-level composition.
Anti-patterns
- Don't use Run Test for one-line wrappers. If the called test is just a single Tap, inline it instead.
- Don't use User-Defined templates for "your one and only sign-up test". That's a test, not a template.
- Don't fight the one-level rule. If you find yourself wanting templates inside templates or children of children, the right fix is usually a Run Test step that calls a smaller test, not a deeper nesting.
