Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
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.