Gherkin Structure
We use proper Gherkin syntax for both manual and e2e test cases to enable automation tooling for test counting, prioritization, and validation. All test cases must be written in valid Gherkin format.
Each test case should follow this structure:
# Comment: Test in both Chrome and Firefox
@Criticality:Medium @RegressionLikelihood:Low
Scenario: Clear scenario description
Given initial state
When action is performed
Then expected outcome
Metadata with Tags
Use Gherkin tags to provide metadata for test implementation prioritization and automation:
For a more detailed explanation of the tags and their usage, see the Testing README.
Criticality Tags (required)
@Criticality:Low- Nice to have functionality@Criticality:Medium- Important functionality@Criticality:High- Core functionality@Criticality:Critical- System-breaking if fails
Regression Likelihood Tags (required)
@RegressionLikelihood:Low- Unlikely to break@RegressionLikelihood:Medium- Moderate risk of regression@RegressionLikelihood:High- High risk of regression@RegressionLikelihood:Recurring- Previously broken
Issue Tag (optional)
@Issue:issueId- Reference to a specific issue
Every scenario must have exactly one tag from the required categories.
Comments Usage
Use "# Comment:" to document:
- Known limitations: Dependencies, environment-specific behavior, implementation details
Example:
# Comments: Additional notes for testers or implementers
@Criticality:High @RegressionLikelihood:Medium
Scenario: Login with valid credentials
Given I am on the PermaplanT landing page
When I click on the 'Log In' button
And I enter valid username and password
Then I am redirected to the landing page
And there is 'Logout' button
Gherkin Best Practices
Do's
- Use clear, simple language that non-technical stakeholders can understand
- Write from the user's perspective using first person ("I")
- Be specific about user actions and expected results - describe what the user does and what they should see, without being overly detailed about implementation
- Use present tense for actions ("When I click" not "When I clicked")
- Keep test scenarios focused on a single feature or one scenario of a use case
- Use consistent terminology throughout all test cases as defined in the glossary
- File Naming: Every use case should have its own file named the same
Don'ts
- Don't include implementation details in scenarios (avoid CSS selectors, API endpoints)
- Don't write overly long scenarios - break complex flows into smaller, focused tests
- Don't mix multiple features or regression tests in a single test scenario
- Don't use vague language like "should work" or "looks good"
Writing Conventions
Capitalization
- Use sentence case for all Given/When/Then clauses.
- Don't add a
.full stop, as they are clauses and not sentences. - For descriptions and notes use a
.full stop, when they are sentences. - Capitalize proper nouns (PermaplanT, Keycloak, etc.).
- Example:
Given I am on the PermaplanT homepage
- Example:
Indentation
- Indent all Given/When/Then/And steps by one tab character (
\t) under the Scenario line. - This ensures consistent alignment regardless of editor settings.
- Example:
Scenario: Example scenario Given some precondition When an action is performed Then expect a result
Quotation Usage
- Use quotes for UI text elements: buttons, labels, error messages
- Use quotes for specific values: field inputs, selection options
- Use quotes for exact text matching
- Examples:
When I click the 'Log In' buttonThen I see the error message 'Invalid credentials'When I select 'Apple tree' from the plant dropdown
- Examples:
Length Guidelines
- Given clauses: 1-3 statements maximum
- When clauses: 3-7 actions per scenario (break longer flows into multiple tests)
- Then clauses: 2-5 assertions per scenario
- Overall scenario: Should be readable in under 30 seconds
Preconditions (Given)
Specify preconditions with appropriate detail level:
Good examples:
Given I am logged in as 'testuser_e2e@permaplant.net'
Given I have a map (Test Garden) with at least 5 plants
Given the base layer contains a background image
Avoid:
Given the database contains specific plant data with IDs 123, 456...
Given the React component state is initialized with...
Test Resources
When referencing test resources, be specific but flexible:
- Users: Use the standardized test user accounts from 'testusers.md'
- Maps: Reference by descriptive names, not database IDs
- Plants/Seeds: Use names found in the scrapper data
Examples:
Given I am logged in as 'testuser_t@permaplant.net'
Given I have selected the 'Smoke Testing Map'
Given I have added 'Tomato (Solanum lycopersicum)' to the plant layer
Title/Scenario Naming
- Use descriptive, action-focused titles
- Format: "Action + Object + Context" when applicable
- Use colons to separate main action from specific context
- Keep titles under 80 characters
- Use sentence case
Good examples:
Login: Successful authentication with valid credentials
Plant layer: Adding multiple plants to existing garden
Base layer: Rotating background image maintains position
Map creation: Creating map with special characters in name
Avoid:
Test 1
Login stuff
User can do plant things
Super long scenario title that goes on and on describing every detail
Handling Specific Values
- Use exact numbers when testing specific functionality (pagination, limits)
- Use ranges or minimums when testing general behavior
- Document the reasoning in comments
Examples:
# Testing pagination specifically
When I navigate to page 3 of the map list
Then I see 10 maps displayed
# Testing general scrolling behavior
When I scroll down in the map overview
Then I can see at least 31 maps total
Reference Patterns
Good examples from existing test cases:
From login.md:
# Test with both Firefox+Chrome for compatibility
@Criticality:Medium @RegressionLikelihood:Low
Scenario: Successful authentication with valid credentials
Given I am on the PermaplanT landing page
When I click on the 'Log In' button
And I enter valid username and password
Then I am redirected to the landing page
And there is 'Logout' button
From map_search.md:
@Criticality:Low @RegressionLikelihood:Low
Scenario: Filter maps using search functionality
Given I am on a map overview page
When I search for a map using the search field
Then the maps are filtered appropriately