-
Notifications
You must be signed in to change notification settings - Fork 0
BDD
Tugkan Boz edited this page Jun 4, 2026
·
1 revision
Two ways to write given / when / then with two-go.
A small, runner-agnostic layer. scenario(steps) returns an async function you
hand to your runner's test(). Steps share a world object.
import { test } from "node:test";
import { go } from "two-go";
import { scenario, given, when, then, and } from "two-go/bdd";
const api = go("https://api.example.com");
test("creating a user", scenario([
given("a valid payload", (w) => { w.payload = { name: "Ada" }; }),
when("the user is created", async (w) => { w.res = await api.post("/users").json(w.payload); }),
then("the response is 201", (w) => w.res.expectStatus(201)),
and("the body echoes the name", (w) => w.res.expectJson("name", "Ada")),
]));feature(name, scenarios) builds a labelled list you can loop and register:
import { feature } from "two-go/bdd";
for (const s of feature("Login", {
"valid credentials": [ given(...), when(...), then(...) ],
"wrong password": [ when(...), then(...) ],
})) {
test(s.name, s.run);
}A when stashes the response on the world, a then asserts on it. Works in
node:test, Jest, Vitest, and Mocha.
If you want .feature files, use cucumber-js and call two-go inside the step
definitions:
Scenario: Get an existing user
Given a user named "Grace" exists
When I get that user by id
Then the response status should be 200When("I get that user by id", async function () {
this.res = await this.api.get(`/users/${this.userId}`);
});
Then("the response status should be {int}", function (status) {
this.res.expectStatus(status);
});A full runnable cucumber example (with Scenario Outline, tags, and an HTML report) lives in two-go-examples/cucumber. There is also an e-commerce BDD suite with 20 scenarios in two-go-examples/ecommerce-bdd.