Probitas
Probitas is a scenario-based testing framework for Deno. It provides intuitive APIs for writing integration tests for APIs, databases, message queues, and other backend services.
Features
- Scenario-based testing: Define tests as readable scenarios with setup, steps, and cleanup
- Multi-protocol support: HTTP, gRPC, GraphQL, SQL, Redis, MongoDB, and message queues with unified APIs
- Type-safe: Full type inference through the builder chain
- Fluent assertions: Natural syntax like
expect(result).toBeSuccessful().toHaveContentContaining({...})
Installation
Add to deno.json
Add Probitas to your project's deno.json:
{
"imports": {
"probitas": "jsr:@probitas/probitas"
}
}
Install CLI
Install the CLI to run scenarios:
deno install -grAf -n probitas jsr:@probitas/cli
-gGlobal install-rReload cache (fetch latest version)-AAll permissions-fForce overwrite existing-n probitasCommand name
Using Nix
Use the flake to run or install the CLI without Deno-level globals:
# Run without installing
nix run github:jsr-probitas/probitas
# Install into your profile
nix profile install github:jsr-probitas/probitas#probitas
The flake packages a wrapper that runs the bundled CLI with the repository import map and lockfile.
Quick Start
import { client, expect, scenario } from "probitas";
export default scenario("User API Test")
.resource("http", () =>
client.http.createHttpClient({
url: "http://localhost:8080",
}))
.step("GET /users/1", async (ctx) => {
const { http } = ctx.resources;
const res = await http.get("/users/1");
expect(res)
.toBeSuccessful()
.toHaveStatus(200)
.toHaveContentContaining({ id: 1 });
})
.build();
File Naming Convention
Scenario files should use the .probitas.ts extension:
src/
probitas/
auth.probitas.ts
user-crud.probitas.ts
payment-flow.probitas.ts
Running Scenarios
Initialize a Project
probitas init
This creates:
- deno.json - Configuration with probitas import and settings
- probitas/example.probitas.ts - Example scenario
Run Scenarios
# Run all scenarios
probitas run
# Run scenarios with specific tag
probitas run -s tag:example
# Run with different reporter
probitas run --reporter dot
Tag-Based Filtering
Organize scenarios with tags for easy filtering:
probitas run -s tag:auth # Match tag
probitas run -s "tag:critical,tag:auth" # AND logic
probitas run -s "!tag:slow" # NOT logic
Reporters
Choose output format based on your needs:
list- Detailed human-readable output (default)dot- Compact progress dotsjson- Machine-readable JSONtap- TAP format for CI integration
Available Clients
All clients are accessed via the client namespace:
| Client | Factory Function | Protocol |
|---|---|---|
| HTTP | client.http.createHttpClient() |
HTTP/HTTPS |
| PostgreSQL | client.sql.postgres.createPostgresClient() |
PostgreSQL |
| MySQL | client.sql.mysql.createMySqlClient() |
MySQL |
| SQLite | client.sql.sqlite.createSqliteClient() |
SQLite |
| DuckDB | client.sql.duckdb.createDuckDbClient() |
DuckDB |
| gRPC | client.grpc.createGrpcClient() |
gRPC |
| ConnectRPC | client.connectrpc.createConnectRpcClient() |
Connect/gRPC/gRPC-Web |
| GraphQL | client.graphql.createGraphqlClient() |
GraphQL |
| Redis | client.redis.createRedisClient() |
Redis |
| MongoDB | client.mongodb.createMongoClient() |
MongoDB |
| Deno KV | client.deno_kv.createDenoKvClient() |
Deno KV |
| RabbitMQ | client.rabbitmq.createRabbitMqClient() |
AMQP |
| SQS | client.sqs.createSqsClient() |
AWS SQS |
Core Concepts
Scenario
A scenario is a complete test case composed of:
- Name: Descriptive identifier for the test
- Resources: Managed dependencies (clients, connections)
- Setup hooks: Initialization code with cleanup callbacks
- Steps: Sequential test operations with assertions
Builder Pattern
scenario(name, options?)
.resource(name, factoryFn, options?) // Register resources (factory function)
.setup(name?, fn, options?) // Add setup/cleanup hooks (name optional)
.step(name?, fn, options?) // Define test steps (name optional)
.build() // Create immutable definition
Expect API
The expect() function auto-dispatches based on result type:
// HTTP response
expect(httpResponse)
.toBeSuccessful()
.toHaveStatus(200)
.toHaveContentContaining({ id: 1 });
// SQL result
expect(sqlResult)
.toHaveRowCount(1)
.toHaveContentContaining({ name: "Alice" });
// gRPC response
expect(grpcResponse)
.toBeSuccessful()
.toHaveContentContaining({ id: "123" });
Included Utilities
Probitas re-exports useful libraries for convenience:
import {
assertSpyCalls,
// Test data generation
faker,
// Time control
FakeTime,
// Template literal dedent
outdent,
// Error handling
raise,
// Mocking
spy,
stub,
tryOr,
} from "probitas";
Next Steps
- Scenario Guide - Learn how to write scenarios in detail
- Client API - Detailed reference for each client
- Configuration - Timeout, retry, and other options
