A BDD (Behavior-Driven Development) testing harness for Deno that integrates seamlessly with [Effection](https://github.com/thefrontside/effection) operations. This package provides a familiar `describe`/`it`/`beforeEach` API that works natively with Effe
npm install @effectionx/bddA BDD (Behavior-Driven Development) testing harness for Deno that integrates
seamlessly with Effection
operations. This package provides a familiar describe/it/beforeEach API
that works natively with Effection's generator-based operations.
- ๐ Native Effection Support: Test functions can be generator functions
that yield operations
- ๐๏ธ Familiar BDD API: Uses the standard describe, it, and beforeEach
functions you know and love
- ๐งน Automatic Cleanup: Proper resource management and cleanup for Effection
operations
- ๐ฏ Skip and Only: Full support for .skip and .only modifiers
- ๐ฆ Zero Configuration: Works out of the box with Deno's built-in testing
framework
Add to your deno.json imports:
``json`
{
"imports": {
"@effectionx/bdd": "jsr:@effectionx/bdd"
}
}
`typescript
import { beforeEach, describe, it } from "@effectionx/bdd";
import { expect } from "@std/expect";
import { sleep, spawn } from "effection";
import { createSignal, is } from "@effectionx/signals";
describe("My async operations", () => {
let counter: ReturnType
beforeEach(function* () {
// Setup that runs before each test
counter = yield* createSignal(0);
yield* sleep(10); // Can use Effection operations in setup
});
it("should increment counter", function* () {
// Test function is a generator that can yield operations
counter.update((n) => n + 1);
yield* is(counter, (value) => value === 1);
expect(counter.valueOf()).toBe(1);
});
});
`
The following packages have been migrated to use @effectionx/bdd and provide
excellent examples of testing patterns:
- stream-helpers: See batch.test.ts for
testing stream batching with time and size limits
- signals: See array.test.ts for testing array
signal operations like push, set, and update
- timebox: See timebox.test.ts for testing
timeout scenarios with both success and timeout cases
- task-buffer: See
task-buffer.test.ts for testing task
queuing and buffer management
- websocket: See websocket.test.ts for
testing bidirectional WebSocket communication and connection lifecycle
- worker: See worker.test.ts for testing web
worker communication, error handling, and lifecycle management
These test files show how to:
- Handle async operations without run() wrappersbeforeEach
- Test error scenarios using try/catch blocks instead of Promise rejections
- Use for test setup with Effection operationsis
- Wait for signal changes using the helper
- Test resource cleanup and proper teardown
- Handle timeouts and concurrent operations
Creates a test suite with the given name. Test suites can be nested.
Options:
- describe.skip() - Skip this test suitedescribe.only()
- - Run only this test suite
Creates a test case with the given description. The body function should be a
generator function that can yield Effection operations.
Options:
- it.skip() - Skip this test caseit.only()
- - Run only this test case
Parameters:
- desc - Description of what the test should dobody
- - Generator function containing the test logic (optional for pending
tests)
Registers a setup function that runs before each test in the current suite. The
body function should be a generator function that can yield Effection
operations.
This package doesn't include afterEach because it's typically used for cleanfinally
up. With Effection, clean up is done in block of the resource.afterEach
Consider creating a resource in beforeEach if you encounter a need for.
Is not implemented yet.
If you're migrating from standard Deno testing with Effection, the changes are
minimal:
Before:
`typescript
import { describe, it } from "@std/testing/bdd";
import { run } from "effection";
describe("my tests", () => {
it("should work", async () => {
await run(function* () {
const result = yield* someOperation();
expect(result).toBe("success");
});
});
});
`
After:
`typescript
import { describe, it } from "@effectionx/bdd";
// No need to import 'run'
describe("my tests", () => {
it("should work", function* () {
const result = yield* someOperation();
expect(result).toBe("success");
});
});
``
This package is part of the
Effection ecosystem. Contributions
are welcome!