Cases as code
Cases can be kept in git as Markdown files (a folder is a suite, a file is a case) and synchronized with the server:
pnpm tsmc pull -p SHOP -d qa/cases # write the project to a folderpnpm tsmc push -d qa/cases --dry-run # what would changepnpm tsmc push -d qa/cases # send it in one atomic operationA push is refused as a whole if a case changed both in the file and on the server; a pull updates only untouched files and puts the server copy next to a conflicting one.
A project’s cases can live in git next to the product’s code: reviewed in pull requests, searched with grep,
edited in your favourite editor — and synchronized with TSMC with tsmc pull / tsmc push.
Layout
Section titled “Layout”qa/cases/ ← the folder given in --dir .tsmc.json ← {"project": "SHOP"}: no --project needed after that Checkout/ ← folder = suite _suite.md ← suite id, name (if it has characters folders cannot hold), paths and description SHOP-1 Pay by card.md ← file = case; the file name can be anything Promo codes/ ← nested suite expired.md ← a new case: it gets an id after pushA case file
Section titled “A case file”---id: SHOP-12version: 3priority: high # low | medium | high | criticaltype: functional # functional | smoke | regression | acceptance | performance | security | usability | otherstatus: active # draft | active | deprecatedtags: [smoke, payments]automation: checkout.PaymentTest.paysWithSavedCardpaths: [src/payments/**] # code the case checks — for picking by changes---
# Pay with a saved card
## Description
The most common way to pay: about **60%** of orders.
## Preconditions
The user is signed in and has an item in the cart.
## Steps
1. @shared Sign in as a customer2. Open the cart > The cart is open3. Click "Pay" and choose the card {{card}} > The payment form is shown
## Data
| card || --- || *1234 || *5678 |- A new file needs only the
# Titleheading; everything else has defaults. tsmcwritesidandversionitself.versionis the server version the file is based on.- A step is an item of a numbered list; continued action text is indented lines; the expected result is indented
lines starting with
>. N. @shared Nameis a shared step of the project (the “Shared steps” page): one line in the file, and the server fills in its steps onpushby name. Its text is changed in the interface — then every case with it changes, and on the nextpullthe files stay the same: they still have one line.## Dataholds the case’s parameters: a Markdown table with parameter names in the first row and then a row per iteration.{{name}}in the title, preconditions and steps is replaced with the value; in a run the case is executed once per row. A|inside a value is written as\|.## Descriptionsays what the case is about and why: context for whoever runs it. Optional, like every section.- Sections can be named in English or in Russian:
## Description/## Описание,## Preconditions/## Предусловия,## Steps/## Шаги,## Data/## Данные.tsmc pullwrites the Russian names. - Texts are Markdown:
**bold**,*italic*, lists and tables (| a | b |with a| --- | --- |line) work in preconditions, actions and expected results; underline, fonts and sizes from the editor come as inline HTML:<u>…</u>,<span style="font-size: 18px">…</span>(only the fonts and sizes the editor offers are kept). A table in a step is indented like any continuation line, or follows>in the expected result. - Unknown sections and text outside sections are an error: the file is not sent until it is fixed. That way nothing is lost silently.
Synchronization
Section titled “Synchronization”tsmc push sends the whole folder in one atomic operation:
| State of the file | Result |
|---|---|
a new file without id |
the case is created, id and version are written into the file |
changed, the server has not changed since version |
a new case version |
| unchanged | nothing |
| unchanged, but the server has a newer version | outdated — run tsmc pull |
| changed both in the file and on the server | conflict — the push is refused as a whole |
| a case on the server, but no file | missing; deleted only with --delete-missing |
--dry-run shows what would change without changing anything.
tsmc pull brings the folder to the server’s state by comparing three versions (the file, its base version, the
server): untouched files are updated and move along with their suites, files changed locally are kept. If a file
changed on both sides, a copy from the server <file>.server is put next to it.
Resolving a conflict
Section titled “Resolving a conflict”- Compare the file with
<file>.serverand carry the changes you need into the file. - Set
versionin the file to the one from the copy. - Delete the copy and run
tsmc push.
tsmc pull --force instead overwrites local edits with the server version.
A team workflow
Section titled “A team workflow”# oncetsmc pull -p SHOP -d qa/cases && git add qa/cases && git commit -m "Import cases"
# everyday work: case edits go into the same PR as the codevim "qa/cases/Checkout/SHOP-1 Pay by card.md"tsmc push -d qa/cases --dry-run # in CI: check that the push will go throughtsmc push -d qa/cases # after the merge into maingit commit -am "Cases: updated ids and versions"Limitations: in preconditions and steps, do not start a line with # (it would be read as a heading), and do not
start a continuation line of an action with > (it would be read as the expected result).