Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
Acceptance testing verifies that software meets business requirements by executing human-readable specifications. Behavior-Driven Development (BDD) bridges the gap between business stakeholders and developers through a collaborative workflow: business rules are written as executable specifications (feature files), automated with step definitions, and run as part of the CI pipeline.
For Gherkin specification syntax (Given/When/Then), see specs/documentation/gherkin.
For Gauge specification syntax (Markdown specs), see specs/documentation/gauge.
# features/user-registration.feature
Feature: User Registration
As a new visitor
I want to create an account
So that I can access personalized features
Background:
Given the registration page is displayed
Scenario: Successful registration with valid details
When I fill in the registration form with:
| field | value |
| name | Jane Doe |
| email | jane@example.com |
| password | SecurePass123! |
And I accept the terms of service
And I click the "Register" button
Then I should see a welcome message "Welcome, Jane Doe!"
And a confirmation email should be sent to "jane@example.com"
Scenario: Registration fails with duplicate email
Given a user exists with email "jane@example.com"
When I fill in the registration form with:
| field | value |
| name | Jane Doe |
| email | jane@example.com |
| password | SecurePass123! |
And I click the "Register" button
Then I should see an error "An account with this email already exists"
Scenario Outline: Registration fails with invalid input
When I fill in "<field>" with "<value>"
And I click the "Register" button
Then I should see an error "<error>"
Examples:
| field | value | error |
| name | | Name is required |
| email | not-an-email | Please enter a valid email address |
| password | short | Password must be at least 8 chars |
Step Definitions by Language
JavaScript / TypeScript (Cucumber.js)
// features/step-definitions/registration.steps.jsconst { Given, When, Then } = require("@cucumber/cucumber");
const { expect } = require("@playwright/test");
Given("the registration page is displayed", asyncfunction () {
awaitthis.page.goto("/register");
awaitexpect(this.page.locator("h1")).toHaveText("Create Account");
});
Given("a user exists with email {string}", asyncfunction (email) {
// Seed the database or call an API to create the userawaitthis.api.post("/test/seed-user", { email });
});
When("I fill in the registration form with:", asyncfunction (dataTable) {
const rows = dataTable.rowsHash();
for (const [field, value] ofObject.entries(rows)) {
awaitthis.page.fill(`[name="${field}"]`, value);
}
});
When("I fill in {string} with {string}", asyncfunction (field, value) {
awaitthis.page.fill(`[name="${field}"]`, value);
});
When("I accept the terms of service", asyncfunction () {
awaitthis.page.check("#terms-checkbox");
});
When("I click the {string} button", asyncfunction (buttonText) {
awaitthis.page.click(`button:has-text("${buttonText}")`);
});
Then("I should see a welcome message {string}", asyncfunction (message) {
awaitexpect(this.page.locator(".welcome-message")).toHaveText(message);
});
Then(
"a confirmation email should be sent to {string}",
asyncfunction (email) {
// Verify via test email service (e.g., Mailhog, Mailtrap)const emails = awaitthis.mailService.getEmails(email);
expect(emails.length).toBeGreaterThan(0);
expect(emails[0].subject).toContain("Confirm your account");
}
);
Then("I should see an error {string}", asyncfunction (errorMessage) {
awaitexpect(this.page.locator(".error-message")).toHaveText(errorMessage);
});
// Features/StepDefinitions/RegistrationSteps.csusing Reqnroll; // or TechTalk.SpecFlow for SpecFlowusing Microsoft.Playwright;
using Xunit;
[Binding]
publicclassRegistrationSteps
{
privatereadonly IPage _page;
privatereadonly ApiClient _api;
// Context injection — Reqnroll/SpecFlow injects shared state automaticallypublicRegistrationSteps(BrowserContext context, ApiClient api)
{
_page = context.Page;
_api = api;
}
[Given("the registration page is displayed")]
publicasync Task GivenTheRegistrationPageIsDisplayed()
{
await _page.GotoAsync("/register");
var heading = await _page.TextContentAsync("h1");
Assert.Equal("Create Account", heading);
}
[Given("a user exists with email {string}")]
publicasync Task GivenAUserExistsWithEmail(string email)
{
await _api.PostAsync("/test/seed-user", new { Email = email });
}
[When("I fill in the registration form with:")]
publicasync Task WhenIFillInTheRegistrationFormWith(Table table)
{
foreach (var row in table.Rows)
{
var field = row["field"];
varvalue = row["value"];
await _page.FillAsync($"[name=\"{field}\"]", value);
}
}
[When("I accept the terms of service")]
publicasync Task WhenIAcceptTheTermsOfService()
{
await _page.CheckAsync("#terms-checkbox");
}
[When("I click the {string} button")]
publicasync Task WhenIClickTheButton(string buttonText)
{
await _page.ClickAsync($"button:has-text(\"{buttonText}\")");
}
[Then("I should see a welcome message {string}")]
publicasync Task ThenIShouldSeeAWelcomeMessage(string message)
{
var text = await _page.TextContentAsync(".welcome-message");
Assert.Equal(message, text);
}
[Then("a confirmation email should be sent to {string}")]
publicasync Task ThenAConfirmationEmailShouldBeSentTo(string email)
{
var emails = await _api.GetAsync<List<Email>>($"/test/emails?to={email}");
Assert.NotEmpty(emails);
Assert.Contains("Confirm your account", emails[0].Subject);
}
[Then("I should see an error {string}")]
publicasync Task ThenIShouldSeeAnError(string errorMessage)
{
var text = await _page.TextContentAsync(".error-message");
Assert.Equal(errorMessage, text);
}
}
Python (Behave)
# features/steps/registration_steps.pyfrom behave import given, when, then
from playwright.sync_api import expect
@given("the registration page is displayed")defstep_registration_page(context):
context.page.goto("/register")
expect(context.page.locator("h1")).to_have_text("Create Account")
@given('a user exists with email "{email}"')defstep_user_exists(context, email):
context.api.post("/test/seed-user", json={"email": email})
@when("I fill in the registration form with")defstep_fill_form(context):
for row in context.table:
field = row["field"]
value = row["value"]
context.page.fill(f'[name="{field}"]', value)
@when('I fill in "{field}" with "{value}"')defstep_fill_field(context, field, value):
context.page.fill(f'[name="{field}"]', value)
@when("I accept the terms of service")defstep_accept_terms(context):
context.page.check("#terms-checkbox")
@when('I click the "{button_text}" button')defstep_click_button(context, button_text):
context.page.click(f'button:has-text("{button_text}")')
@then('I should see a welcome message "{message}"')defstep_welcome_message(context, message):
expect(context.page.locator(".welcome-message")).to_have_text(message)
@then('a confirmation email should be sent to "{email}"')defstep_confirmation_email(context, email):
emails = context.mail_service.get_emails(email)
assertlen(emails) > 0assert"Confirm your account"in emails[0]["subject"]
@then('I should see an error "{error_message}"')defstep_error_message(context, error_message):
expect(context.page.locator(".error-message")).to_have_text(error_message)
Gauge (by ThoughtWorks) uses Markdown-based specification files instead of Gherkin. Specifications are written as natural-language steps in .spec files, with reusable abstractions called "concepts".
For Gauge specification syntax details, see specs/documentation/gauge.
Gauge Spec Example
# User Registration## Successful registration with valid details
Tags: registration, smoke
* Navigate to the registration page
* Fill in registration form with name "Jane Doe" and email "jane@example.com" and password "SecurePass123!"
* Accept terms of service
* Click the "Register" button
* Verify welcome message "Welcome, Jane Doe!" is displayed
* Verify confirmation email sent to "jane@example.com"
## Registration fails with duplicate email
Tags: registration, negative
* Ensure user exists with email "jane@example.com"
* Navigate to the registration page
* Fill in registration form with name "Jane Doe" and email "jane@example.com" and password "SecurePass123!"
* Click the "Register" button
* Verify error message "An account with this email already exists" is displayed
Gauge Concept (Reusable Step Group)
# Register a new user with <name> and <email>* Navigate to the registration page
* Fill in registration form with name <name> and email <email> and password "DefaultPass123!"
* Accept terms of service
* Click the "Register" button
Gauge Step Implementation (JavaScript)
// tests/step_implementations/registration.jsconst { Step, BeforeSuite, AfterSuite } = require("gauge-ts");
const { openBrowser, closeBrowser, goto, write, click, into, textBox, text, checkBox } = require("taiko");
Step("Navigate to the registration page", async () => {
awaitgoto("http://localhost:3000/register");
});
Step(
"Fill in registration form with name <name> and email <email> and password <password>",
async (name, email, password) => {
awaitwrite(name, into(textBox({ name: "name" })));
awaitwrite(email, into(textBox({ name: "email" })));
awaitwrite(password, into(textBox({ name: "password" })));
}
);
Step("Accept terms of service", async () => {
awaitcheckBox({ id: "terms-checkbox" }).check();
});
Step("Click the <buttonText> button", async (buttonText) => {
awaitclick(buttonText);
});
Step("Verify welcome message <message> is displayed", async (message) => {
assert(awaittext(message).exists());
});
Step("Verify error message <message> is displayed", async (message) => {
assert(awaittext(message).exists());
});
Godog (Go)
Overview
Godog is the official Cucumber BDD framework for Go. It uses standard Gherkin feature files with step definitions written in Go.