@bootstrapp/test
v0.1.1
Published
Test framework for Bootstrapp applications
Maintainers
Readme
@bootstrapp/test
A lightweight test framework for Bootstrapp applications. Supports both Node.js and browser testing environments with a familiar API.
Installation
npm install @bootstrapp/testFeatures
- Zero-configuration test runner
- Runs in both Node.js and browser environments
- Jest-compatible mock functions
- Comprehensive assertion library
- Test suites with lifecycle hooks
- Browser tests via Puppeteer
- Automatic test discovery
CLI Usage
# Run all tests
bootstrapp test
# Run specific test file
bootstrapp test --file path/to/test.js
# Run browser tests
bootstrapp test --browser
# Run browser tests with visible browser
bootstrapp test --browser --headed
# Run tests in a specific project
bootstrapp test --project ./my-project
# Verbose output
bootstrapp test --verboseAPI Reference
Test Structure
import Testing from "@bootstrapp/test";
const { describe, it, assert, mock, beforeEach, afterEach, beforeAll, afterAll } = Testing;
Testing.suite("My Test Suite", () => {
describe("Feature Group", () => {
beforeEach(() => {
// Setup before each test
});
afterEach(() => {
// Cleanup after each test
});
it("should do something", () => {
assert.equal(1 + 1, 2);
});
it("should handle async", async () => {
const result = await fetchData();
assert.ok(result);
});
});
});Browser Tests
Mark tests as browser-only:
Testing.suite("Browser Tests", () => {
describe("DOM Tests", () => {
it("should create elements", () => {
const el = document.createElement("div");
assert.ok(el instanceof HTMLElement);
});
});
}, { env: "browser" });Assertions
import { assert } from "@bootstrapp/test/assert";
// Basic assertions
assert(condition); // Truthy check
assert.ok(value); // Same as assert()
assert.notOk(value); // Falsy check
// Equality
assert.equal(actual, expected); // Strict equality (===)
assert.notEqual(actual, expected); // Strict inequality (!==)
assert.deepEqual(actual, expected); // Deep object equality
// Type checks
assert.isTrue(value); // value === true
assert.isFalse(value); // value === false
assert.isNull(value); // value === null
assert.isNotNull(value); // value !== null
assert.isUndefined(value); // value === undefined
assert.isDefined(value); // value !== undefined
assert.isObject(value); // typeof value === "object"
assert.isFunction(value); // typeof value === "function"
assert.isArray(value); // Array.isArray(value)
// Collection checks
assert.include(haystack, needle); // Array/string includes
assert.notInclude(haystack, needle); // Array/string excludes
// Error handling
assert.throws(fn, /pattern/); // Function throws matching error
await assert.rejects(promise, /pattern/); // Promise rejects with matching errorMock Functions
import { mock } from "@bootstrapp/test/mock";
// Create a mock function
const mockFn = mock.fn();
// With default implementation
const mockFn = mock.fn((x) => x * 2);
// Set return values
mockFn.mockReturnValue(42);
mockFn.mockReturnValueOnce(100);
// Async return values
mockFn.mockResolvedValue({ data: "async" });
mockFn.mockResolvedValueOnce({ data: "once" });
mockFn.mockRejectedValue(new Error("fail"));
mockFn.mockRejectedValueOnce(new Error("fail once"));
// Custom implementation
mockFn.mockImplementation((x) => x + 1);
mockFn.mockImplementationOnce((x) => x * 10);
// Inspect calls
mockFn.mock.calls; // [[arg1, arg2], [arg1, arg2], ...]
mockFn.mock.calls.length; // Number of calls
mockFn.mock.lastCall; // Last call info
mockFn.mock.results; // [{type: "return", value: 42}, ...]
// Reset state
mockFn.mockClear(); // Clear call history
mockFn.mockReset(); // Clear history + implementationLifecycle Hooks
Testing.suite("Suite with Hooks", () => {
beforeAll(() => {
// Run once before all tests in suite
});
afterAll(() => {
// Run once after all tests in suite
});
describe("Group", () => {
beforeEach(() => {
// Run before each test in this describe block
});
afterEach(() => {
// Run after each test in this describe block
});
it("test 1", () => { /* ... */ });
it("test 2", () => { /* ... */ });
});
});Test File Conventions
- Framework packages:
public/{package}/{package}.test.js - Project tests:
projects/{project}/tests/*.test.js - Pattern matching:
**/*.test.js
Running Specific Suites
// Run programmatically
await Testing.run("My Suite Name");
// Run specific describe block
await Testing.runDescribe("path/to/test.js", "describe name", "suite name");
// Run specific file
await Testing.runFile("path/to/test.js");Browser Integration
In browser context, the test framework integrates with $APP:
// Access via $APP
$APP.Testing.run();
$APP.Testing.runFile("/tests/my.test.js");
// Or use iframe runner for isolation
Testing.iframe.run("My Suite");
Testing.iframe.runFile("/tests/my.test.js");Requirements
- Node.js >= 18.0.0
puppeteer(optional, for browser tests)@bootstrapp/base(optional, for browser integration)
License
AGPL-3.0
