Skip to content

Tests and assertions

fp.test(name, fn) registers a synchronous test. Errors thrown inside fn — including assertion failures — are caught and recorded as a failed test result. Passing tests record { name, passed: true }; failures record { name, passed: false, error }.

The Tests tab in the response viewer shows every test result for the request. Results can be exported as JSON or JUnit XML from the UI — the JUnit format is meant for CI tools like Jenkins, GitLab, or Azure DevOps.

fp.expect(value) is a fluent, Chai-like builder. The most useful terminals:

  • Equality: equal / eql (identity and deep), closeTo(expected, delta).
  • Existence: exist, ok, true, false, null, undefined, empty.
  • Types: a('string'), instanceOf(Error).
  • Containment: include(value), include.keys('a', 'b'), keys('a', 'b').
  • Numeric: above(n), below(n), least(n), most(n), lengthOf(n).
  • Predicates: match(regex), satisfy(fn), oneOf([...]), throw(matcher?).
  • Strings: startWith(prefix), endWith(suffix).
  • Properties: property('name', value?), with .nested for dotted paths.
  • Modifiers: not negates, deep makes the next equal deep, nested enables dotted paths.
fp.test('user has expected fields', () => {
const body = fp.response.json();
fp.expect(body).to.have.keys('id', 'email');
fp.expect(body.email).to.match(/@example\.com$/);
});

Anything passed to fp.log/warn/error is deep-cloned to a safe representation before being surfaced in the UI: functions become a placeholder mentioning their name, circular references are detected and labelled, and recursion stops at depth 3. A fp.log(someComplexObject) never leaks live references into the UI and never freezes the app on a circular graph.