npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

endpoint-tester

v0.4.3

Published

Auto-discover API endpoints and generate comprehensive test suites

Readme

endpoint-tester

Auto-discover API endpoints in your source code and generate ready-to-run test suites.

npm version npm downloads license TypeScript CI

npm · GitHub · Dev.to Article


Demo

A full scan + generate cycle on a real Express app in ~5 seconds. See the Quick Demo section for the exact terminal output.


The problem

Every API project needs endpoint tests. Writing them is tedious, repetitive, and error-prone: you copy-paste test files, update paths, remember which params go where, and hope you didn't miss a route. When the codebase changes, the tests fall behind.

The solution

endpoint-tester scans your source code, discovers every API endpoint automatically, and generates test suites that are ready to run. Point it at your project, get a complete test file in seconds.

Source code in  -->  [endpoint-tester]  -->  Test suite out
  Express                                     Vitest / Jest
  Fastify                                     Pytest
  Koa
  NestJS
  FastAPI
  Flask
  Django
  Spring Boot

How It Works

┌─────────────────────────────────────────────────────────────────┐
│                        Your Source Code                          │
│   src/routes/users.ts   src/routes/orders.ts   src/app.ts       │
└───────────────────────────────┬─────────────────────────────────┘
                                │
                    ┌───────────▼───────────┐
                    │   Framework Detection  │
                    │  (package.json / AST)  │
                    │  express, fastapi, ... │
                    └───────────┬───────────┘
                                │
                    ┌───────────▼───────────┐
                    │    Adapter / Parser    │
                    │  Reads route patterns  │
                    │  Extracts params/body  │
                    └───────────┬───────────┘
                                │
               ┌────────────────▼────────────────┐
               │         Endpoint Registry         │
               │  GET /users                       │
               │  POST /users          body: {...} │
               │  GET /users/:id       param: id   │
               │  PUT /users/:id       param: id   │
               │  DELETE /users/:id    param: id   │
               └────────────────┬────────────────┘
                                │
           ┌────────────────────▼──────────────────────┐
           │              Test Generator                 │
           │  - status code assertions (GET→200, POST→201) │
           │  - auth header tests (Bearer token)         │
           │  - error tests (missing body → 4xx)         │
           │  - boundary value tests (empty, negative ID) │
           └────────────────────┬──────────────────────┘
                                │
          ┌─────────────────────▼──────────────────────┐
          │               Output                        │
          │  tests/api.test.ts   openapi.yaml   stdout  │
          └────────────────────────────────────────────┘

Quick Demo

A real Express.js app, from zero to a complete test suite in under 60 seconds.

The app (src/app.ts):

import express from 'express';
import { Router } from 'express';

const app = express();
const router = Router();

router.get('/users', listUsers);
router.post('/users', createUser);
router.get('/users/:id', getUser);
router.put('/users/:id', updateUser);
router.delete('/users/:id', deleteUser);
router.get('/users/:id/orders', getUserOrders);

app.use('/api', router);
app.listen(3000);

Step 1 — Install

npm install -g endpoint-tester
# or use without installing:
npx endpoint-tester scan ./src

Step 2 — Scan (auto-detects Express)

$ endpoint-tester scan ./src

Auto-detected framework: express (high confidence)
Scanning ./src for express endpoints...
Found 6 endpoint(s):

  GET     /api/users
  POST    /api/users
  GET     /api/users/:id    [params: id]
  PUT     /api/users/:id    [params: id]
  DELETE  /api/users/:id    [params: id]
  GET     /api/users/:id/orders  [params: id]

Step 3 — Generate tests

$ endpoint-tester generate ./src --format vitest --output ./tests/api.test.ts

Generated 6 test cases → ./tests/api.test.ts

The output (tests/api.test.ts) — ready to run with npx vitest:

import { describe, it, expect } from 'vitest';

const BASE_URL = 'http://localhost:3000';
const AUTH_TOKEN = process.env.TEST_AUTH_TOKEN ?? 'test-token';

describe('GET /api/users', () => {
  it('returns 200', async () => {
    const res = await fetch(`${BASE_URL}/api/users`);
    expect(res.status).toBe(200);
  });
  it('returns 401 without auth', async () => {
    const res = await fetch(`${BASE_URL}/api/users`, {
      headers: { Authorization: `Bearer invalid` },
    });
    expect(res.status).toBeOneOf([401, 403]);
  });
});

describe('POST /api/users', () => {
  it('returns 201 with body', async () => {
    const res = await fetch(`${BASE_URL}/api/users`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${AUTH_TOKEN}`,
      },
      body: JSON.stringify({}),
    });
    expect(res.status).toBe(201);
  });
  it('returns 4xx with missing body', async () => {
    const res = await fetch(`${BASE_URL}/api/users`, { method: 'POST' });
    expect(res.status).toBeGreaterThanOrEqual(400);
  });
});

describe('GET /api/users/:id', () => {
  it('returns 200 for valid id', async () => {
    const res = await fetch(`${BASE_URL}/api/users/1`);
    expect(res.status).toBe(200);
  });
  it('returns 404 for nonexistent id', async () => {
    const res = await fetch(`${BASE_URL}/api/users/999999`);
    expect(res.status).toBe(404);
  });
  it('returns 4xx for empty id', async () => {
    const res = await fetch(`${BASE_URL}/api/users/`);
    expect(res.status).toBeGreaterThanOrEqual(400);
  });
});

// ... DELETE, PUT, and nested routes follow the same pattern

Step 4 — Run (against your running server)

$ npx vitest run tests/api.test.ts

 PASS  tests/api.test.ts (1.2s)
   GET /api/users
     ✓ returns 200
     ✓ returns 401 without auth
   POST /api/users
     ✓ returns 201 with body
     ✓ returns 4xx with missing body
   GET /api/users/:id
     ✓ returns 200 for valid id
     ✓ returns 404 for nonexistent id
     ✓ returns 4xx for empty id

Bonus — export OpenAPI spec

$ endpoint-tester generate ./src --format openapi --output openapi.yaml

openapi: "3.1.0"
info:
  title: API
  version: "1.0.0"
paths:
  /api/users:
    get:
      summary: GET /api/users
      responses:
        "200": { description: OK }
  /api/users/{id}:
    get:
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      ...

Feed this to Swagger UI, Schemathesis, or openapi-generator — no manual annotations needed.

Postman Collection export

$ endpoint-tester generate ./src --format postman --output postman-collection.json

Generated Postman Collection v2.1.0 -> postman-collection.json

Import the file straight into Postman (or Insomnia — it also reads v2.1). Every request comes with a shared {{baseUrl}} variable, a placeholder Authorization: Bearer {{authToken}} header, and — for POST/PUT/PATCH — a raw JSON body seeded from the inferred fields.

Bonus — detect drift against an existing OpenAPI spec

Already ship a hand-maintained openapi.json? Point endpoint-tester diff at it and get a fail-loud drift check in one command — perfect for CI:

$ endpoint-tester diff ./src ./openapi.json

Scanning ./src for express endpoints...
Found 5 discovered endpoint(s).
Loading OpenAPI spec from ./openapi.json...

Drift detected between OpenAPI spec and source code (3 matched).

In spec, but not in source (1):
  - DELETE /users/{id}

In source, but not in spec (1):
  + PATCH /products/{id}

Exits non-zero when drift is found, so it drops into any CI pipeline as a hard gate. Add --json for machine-readable output. Path placeholders normalise across frameworks: Express :id, Flask <int:id>, and OpenAPI {id} all compare equal.

Features

  • Auto-detection -- Detects your framework automatically from package.json, requirements.txt, pom.xml, or source imports. No config needed.
  • 13 framework adapters -- Express.js, Fastify, Koa, NestJS, Hono, FastAPI, Flask, Django, Spring Boot, Gin, Echo, Chi, net/http. Extensible for any framework via the Adapter interface.
  • 3 test formats -- Vitest, Jest, Pytest. Generated tests include status code assertions, auth header tests, error response tests, and boundary value tests.
  • OpenAPI 3.1 output -- Emit a spec straight from your source code (--format openapi, JSON or YAML). Feed it to Swagger UI, Schemathesis, Dredd, Apidog, or openapi-generator — no manual annotations, zero runtime dependencies.
  • Postman Collection v2.1 -- Emit a ready-to-import collection (--format postman), with {{baseUrl}}/{{authToken}} variables, body skeletons, and per-request path + query parameter descriptions.
  • OpenAPI drift detection -- Already have a hand-maintained openapi.json? Run endpoint-tester diff <src> <spec> to reconcile discovered routes against the spec and exit non-zero on drift. Drop it into CI to block PRs that add or delete endpoints without updating the spec.
  • Smart route parsing -- Handles router prefixes, middleware chains, app.route() chaining, multi-line decorators, class-level annotations, Blueprints, and more.
  • Zero config -- Works out of the box. One command, one output.

Install

Requirements: Node.js >= 20

# Install globally (recommended)
npm install -g endpoint-tester

# Or use without installing (always pulls the latest version)
npx endpoint-tester scan ./src

Verify the installation:

endpoint-tester --version
# 0.3.0

Quick start

Point endpoint-tester at your source directory — it auto-detects the framework.

# 1. Scan for endpoints (auto-detects framework from package.json / requirements.txt / pom.xml)
endpoint-tester scan ./src

# 2. Generate a test suite
endpoint-tester generate ./src --format vitest --output ./tests/api.test.ts

# 3. Run the generated tests (against your running server)
npx vitest run ./tests/api.test.ts

Framework-specific examples:

# Express.js — auto-detected from package.json
endpoint-tester scan ./src

# FastAPI — auto-detected from requirements.txt
endpoint-tester scan ./app

# Force a specific framework
endpoint-tester scan ./src --framework nestjs
endpoint-tester scan ./src --framework spring

# Generate a Pytest suite for FastAPI
endpoint-tester generate ./app --framework fastapi --format pytest --output ./tests/test_api.py

# Generate an OpenAPI 3.1 spec (no server required)
endpoint-tester generate ./src --format openapi --output openapi.yaml

Working examples you can clone and run right now:

# Express.js example
examples/express-sample/    # see examples/express-sample/README.md

# FastAPI example
examples/fastapi-sample/    # see examples/fastapi-sample/README.md

# Go examples (Gin, Echo, Chi, net/http)
examples/go-sample/         # see examples/go-sample/README.md

Example output

Given an Express app:

// src/routes/users.ts
router.get('/users', listUsers);
router.post('/users', createUser);
router.get('/users/:id', getUser);
router.put('/users/:id', updateUser);
router.delete('/users/:id', deleteUser);

Running endpoint-tester scan ./src outputs:

Auto-detected framework: express (high confidence)
Scanning ./src for express endpoints...
Found 5 endpoint(s):

  GET     /users
  POST    /users
  GET     /users/:id [params: id]
  PUT     /users/:id [params: id]
  DELETE  /users/:id [params: id]

Running endpoint-tester generate ./src --format vitest generates a complete test file with:

  • Success tests with method-specific status codes (POST expects 201, DELETE expects 204, etc.)
  • Auth header tests (Bearer token)
  • Error response tests (missing body returns 4xx)
  • Boundary value tests for path parameters (empty, negative, nonexistent)

CLI reference

scan / generate

| Option | Description | Default | | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | | --framework / -f | Framework adapter (express, fastapi, spring, django, flask, fastify, koa, nestjs, hono, gin, echo, chi, nethttp). Auto-detected if omitted. | auto-detect | | --output / -o | Output path -- directory or file path | ./generated-tests | | --format | Output format (vitest, jest, pytest, go, openapi, postman) | vitest | | --base-url | Base URL for test requests | http://localhost:3000 | | --watch / -w | Watch for source file changes and re-scan/regenerate automatically | off | | --exclude / -e | Glob patterns to exclude (repeatable) | none | | --verbose / -v | Show source file and line number for each endpoint (scan only) | off |

ci

Run in CI to guard against accidental endpoint deletion:

# First run saves a baseline (auto-created if missing)
endpoint-tester ci ./src

# Subsequent CI runs — exits 1 if fewer endpoints than baseline
endpoint-tester ci ./src

# After an intentional endpoint removal, refresh the baseline
endpoint-tester ci ./src --update-baseline

# Custom baseline file path (default: .endpoint-tester-baseline.json)
endpoint-tester ci ./src --baseline-file ci/baseline.json

Exit codes: 0 = pass (count same or higher), 1 = fail (count dropped below baseline).

diff

Reconcile discovered endpoints against an OpenAPI 3.x spec (JSON) and fail fast on drift — ideal as a CI gate on repos where the spec is the source of truth:

# Compare discovered routes against a checked-in spec
endpoint-tester diff ./src ./openapi.json

# Machine-readable output (drift report as JSON)
endpoint-tester diff ./src ./openapi.json --json

# Same, force framework
endpoint-tester diff ./src ./openapi.json --framework fastapi

Exit codes: 0 = in sync, 1 = drift detected (missing endpoints on either side).

Path placeholders normalise across frameworks and specs: Express :id, Flask <int:id>, and OpenAPI {id} all compare equal.

from

Generate a test scaffold directly from an OpenAPI/Swagger spec — no source scanning required. Ideal when the API contract is your source of truth (public APIs, spec-first services, gateways).

Supports OpenAPI 3.x and Swagger 2.0, JSON or YAML, local path or http(s) URL:

# From a local JSON spec (default: vitest tests written to ./generated-tests/)
endpoint-tester from ./openapi.json

# From a YAML spec, custom output and format
endpoint-tester from ./openapi.yaml --output ./tests --format pytest

# From a remote spec URL
endpoint-tester from https://petstore3.swagger.io/api/v3/openapi.json --output ./tests

# Re-emit as a Postman collection
endpoint-tester from ./openapi.json --format postman --output ./postman.json

# Override the base path applied to every imported endpoint
endpoint-tester from ./openapi.yaml --base-path /api/v2

| Option | Description | Default | | ------------- | ------------------------------------------------------------------ | ----------------------- | | --output | Output path — directory or file | ./generated-tests | | --format | Output format (vitest, jest, pytest, go, openapi, postman) | vitest | | --base-url | Base URL for test requests | http://localhost:3000 | | --base-path | Prepend a base path to every imported endpoint (overrides Swagger 2 basePath) | none |

Exit codes: 0 on success, 1 when the spec cannot be loaded or parsed, --format/--base-url are invalid, or the spec fails OpenAPI validation.

GitHub Action

For CI on GitHub, you don't need to install anything — a composite action lives at the repo root (action.yml). It runs endpoint-tester ci and fails the workflow if any endpoint is removed since the last baseline. Minimal example:

# .github/workflows/endpoints.yml
name: endpoint drift guard

on:
  pull_request:
    branches: [main]

jobs:
  guard:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: leopechnicki/[email protected]
        with:
          directory: ./src
          # framework: express       # omit to auto-detect
          # baseline-file: .endpoint-tester-baseline.json
          # update-baseline: 'false' # 'true' to refresh baseline

The action installs the latest published endpoint-tester (or the version you pin in with.version:), runs endpoint-tester ci, and exposes three outputs:

| Output | Description | | ---------------- | ------------------------------------------------ | | endpoint-count | Number of endpoints discovered on this run | | baseline-count | Number recorded in the baseline (or 0 if none) | | drift | ok / added / removed / no-baseline |

Use them for downstream conditional steps (e.g. only notify Slack when drift == 'removed').

Config file

Instead of repeating CLI flags on every run, you can set defaults in a .endpointtesterrc (or .endpointtesterrc.json) file in the root of the project you are scanning:

{
  "framework": "express",
  "outputDir": "./tests/generated",
  "testRunner": "vitest",
  "baseUrl": "http://localhost:3000",
  "exclude": ["legacy/**", "migrations/**"]
}

The loader searches for the config in this order (first hit wins):

  1. The scanned directory (e.g. endpoint-tester generate ./src looks inside ./src).
  2. The current working directory — where you actually ran the command. This is the case most users hit: rc file at the project root, endpoint-tester generate ./src.
  3. Parent directories of the scanned directory, walking up to the filesystem root (same pattern as ESLint/Prettier).

CLI flags always override config file values. Supported fields:

| Field | Type | Description | | ------------ | -------- | -------------------------------------------------------------- | | framework | string | Override auto-detection (express, fastapi, nestjs, etc.) | | outputDir | string | Default output directory for generated tests | | testRunner | string | Default format (vitest, jest, pytest, go, openapi) | | baseUrl | string | Default base URL used in generated tests | | exclude | string[] | Glob patterns to exclude from scanning | | include | string[] | Additional glob patterns to include |

Watch mode

Re-scan and regenerate every time a source file changes:

# Watch and rescan
endpoint-tester scan ./src --watch

# Watch and regenerate tests
endpoint-tester generate ./src --watch --output ./tests/api.test.ts

Watches .ts, .js, .py, .go, .java, .kt, .rs files. Changes are debounced (300 ms) to avoid spurious re-runs during saves. Press Ctrl+C to stop.

Supported frameworks

| Framework | Patterns detected | | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Express.js | app.get(), router.post(), app.route().get().post(), route params, router prefixes via app.use() and router.use(), middleware chains | | Hono | app.get(), app.post(), app.route() groups, app.use() mounts, :param path params, c.req.query() inference, body inference from c.req.json() | | Fastify | fastify.get(), fastify.route({ method, url, handler }), shorthand method registrations | | Koa | @koa/router with router.get() / router.post(), route params, router.prefix() | | NestJS | @Controller('prefix') + method decorators (@Get, @Post, ...), @Param, @Query, @Body DTO inference | | FastAPI | @app.get(), @router.post(), APIRouter prefixes, {param} parameters, multi-line decorators with kwargs | | Flask | @app.route() with methods list, @app.get() shorthand, Blueprint url_prefix, typed parameters (<int:id>) | | Django | path(), re_path(), typed parameters (<int:pk>), regex named groups | | Spring Boot | @GetMapping, @PostMapping, @RequestMapping (both argument orderings), class-level @RequestMapping prefix, @PathVariable, multiline annotations, Kotlin fun syntax | | Gin | r.GET(), r.POST(), router.Group() prefixes, route params (:id), gin.Default() and gin.New() | | Echo | e.GET(), e.POST(), e.Group() prefixes, route params (:id), echo.New() | | Chi | r.Get(), r.Post(), r.Route(), r.Mount() prefixes, route params ({id}) | | net/http | http.HandleFunc(), mux.HandleFunc(), http.Handle(), route params (custom patterns) |

Test formats

| | Vitest | Jest | Pytest | | -------------- | ----------------------------------- | ------------------------ | ------------------------------------ | | Imports | import { describe, it, expect } | Uses globals (no import) | import requests | | File | .ts | .ts | .py | | Assertions | expect(response.status).toBe(201) | Same | assert response.status_code == 201 |

All formats generate:

  • Method-specific status code assertions (GET -> 200, POST -> 201, DELETE -> 204)
  • Auth header tests with Bearer token
  • Error response tests for body-accepting endpoints
  • Boundary value tests for path parameters

Programmatic API

import {
  Scanner,
  TestGenerator,
  getAdapter,
  detectFramework,
} from 'endpoint-tester';

// Auto-detect the framework
const detected = await detectFramework('./src');
if (!detected) throw new Error('Could not detect framework');
const adapter = getAdapter(detected.framework);

// Scan for endpoints
const scanner = new Scanner(adapter);
const endpoints = await scanner.scan({
  directory: './src',
  framework: detected.framework,
});

// Generate tests
const generator = new TestGenerator();
const tests = generator.generate({
  endpoints,
  output: './tests',
  format: 'vitest',
  baseUrl: 'http://localhost:3000',
});

Custom adapters

Implement the Adapter interface to add support for any framework:

import { Adapter, Endpoint, Framework, registerAdapter } from 'endpoint-tester';

class HonoAdapter implements Adapter {
  framework = 'hono' as Framework;
  fileExtensions = ['.ts', '.js'];

  parse(source: string, filePath?: string): Endpoint[] {
    // Your parsing logic here
    return [];
  }
}

registerAdapter(new HonoAdapter());

Comparison with alternatives

vs. Schemathesis, Bruno, and Optic

The key distinction: most tools go spec → tests. endpoint-tester goes source code → spec.

| | endpoint-tester | Schemathesis | Bruno | Optic | | ------------------- | -------------------------- | ------------------------ | -------------------------- | ------------------------------ | | Starting point | Source code | OpenAPI/GraphQL spec | Existing API collection | OpenAPI spec or traffic | | Spec required? | No — generates it | Yes | Yes (or import) | Yes | | Test framework | Vitest, Jest, Pytest, Go | pytest (property-based) | Bruno runner | Optic CI | | Approach | Static analysis of routes | Fuzzing + property tests | Manual collection + run | Diff / contract testing | | Framework-aware | 13 built-in adapters | Spec-agnostic | Spec-agnostic | Spec-agnostic | | Setup time | Zero — point at source dir | Write/import spec first | Import or write collection | Import spec or capture traffic | | CI guard | Built-in (ci command) | Via pytest integration | Bruno CLI | Optic CI action | | Watch mode | Built-in (--watch) | No | No | No | | OpenAPI export | Yes (3.1, JSON + YAML) | Consumes, not generates | Consumes | Generates from traffic | | Price | Free / open-source | Free / open-source | Free / open-source | Free tier + paid | | Language | TypeScript (Node.js) | Python | Any (CLI) | TypeScript |

When to use each:

  • endpoint-tester — You have source code but no spec yet. Start here: get tests and a spec in one step.
  • Schemathesis — You have a spec and want property-based fuzzing to find edge cases.
  • Bruno — You prefer a Git-friendly Postman replacement for manual API exploration.
  • Optic — You want to diff two spec versions or detect breaking changes in CI.

vs. writing tests manually or Postman

| | endpoint-tester | Writing tests manually | Postman export | | ---------------------- | ---------------- | ---------------------- | --------------------- | | Setup time | 0 (auto-detects) | N/A | Import collection | | Keeps up with code | Re-scan anytime | Manual updates | Re-export | | Boundary tests | Automatic | Write each one | Manual | | Auth tests | Automatic | Write each one | Configure per request | | Multi-framework | 13 built-in | N/A | Framework-agnostic | | CI friendly | CLI output | Already in repo | Needs Newman |

Development

Prerequisites

  • Node.js >= 20
  • npm

Setup

git clone https://github.com/leopechnicki/endpoint-tester.git
cd endpoint-tester
npm install

Commands

npm run build    # Compile TypeScript to dist/
npm test         # Run tests with vitest
npm run lint     # Lint with ESLint
npm run dev      # Watch mode (tsc --watch)

Library usage (programmatic API)

Install as a dependency:

npm install endpoint-tester

Import types and classes:

import {
  Scanner,
  TestGenerator,
  getAdapter,
  registerAdapter,
  detectFramework,
  Framework,
  type Adapter,
  type Endpoint,
  type EndpointParam,
  type EndpointBody,
  type HttpMethod,
  type ScanOptions,
  type GenerateOptions,
} from 'endpoint-tester';

Contributing

Contributions are welcome. Areas with the most impact:

  • New framework adapters (Hono, Actix, Laravel, etc.)
  • Smarter body inference from type annotations
  • Watch mode for continuous test generation

Commit messages follow Conventional Commits (feat:, fix:, chore:, ...). Releases are cut automatically by release-please based on the commit history.

License

MIT