Writing tests

.saffron and .feature files

Saffron runs two kinds of feature file, side by side in the same project.

.feature is standard Gherkin, exactly as Cucumber defines it: Feature, Background, Rule, Scenario, Scenario Outline with Examples, data tables, doc strings, tags. Any .feature file you already have runs as it is, and every other Gherkin tool can still read it.

.saffron is Saffron's own file type: a superset of Gherkin. It accepts everything a .feature file does, plus one addition, the StepSet keyword for defining and invoking step sets (the rest of this page). Think of TypeScript and JavaScript: .ts is .js plus keywords, under an honest new extension.

.feature .saffron
Standard Gherkin (scenarios, outlines, tables, doc strings, tags) yes yes
Recorded, replayed and healed by Saffron yes yes
{env:VAR} secrets, {date+N} templates, plain-prose tabs, dialogs, API waits yes yes
Define a step set (StepSet: name) no yes
Invoke a step set (StepSet name) no yes
Readable by Cucumber and other Gherkin tools yes no, once it uses StepSet
Completion, hover and diagnostics in VS Code and JetBrains yes yes
Highlighting out of the box your editor's Gherkin support the Saffron extension or plugin

The only difference is step sets. They are kept out of .feature on purpose: a .feature file containing a non-standard keyword would break standard tooling while claiming to be standard, so using StepSet in a .feature file is a parse error that tells you to rename the file.

Which one to write

  • A new project: use .saffron. saffron init --examples does, and you get step sets the day you want them.
  • An existing Cucumber suite: keep your .feature files. They run unchanged, and you can adopt Saffron without touching them.
  • Mixed is fine. Step sets defined in any .saffron file are visible to every other .saffron file in the project; a .feature file simply cannot call them.

Moving a file from .feature to .saffron

Rename it. No content changes are needed, because every valid .feature file is a valid .saffron file. One thing to know: a recording's location is derived from the file's name, so login.feature keeps its recordings in .saffron/cache/login/ and login.saffron looks in .saffron/cache/login-saffron/. Rename that directory along with the file and the scenarios keep replaying at zero tokens. If you do not, they record again on the next run, mostly from steps Saffron has already recorded, and saffron prune lists the old directory afterwards.

Editor and GitHub setup for .saffron

The VS Code extension and the JetBrains plugin register the file type and its highlighting. Without them, two lines give you Gherkin highlighting: in VS Code's settings, "files.associations": { "*.saffron": "feature" }, and in .gitattributes, *.saffron linguist-language=Gherkin so GitHub renders diffs and files with Gherkin colours.