unit-test

unit-test is a skill for Claude Code, Codex from LuuOW/meridian-mcp. It costs 57 tokens per session (3,197 once invoked), scanned A, original, MIT.

A guide to unit testing Python/FastAPI and React/TypeScript applications. Unit tests check small pieces of code in isolation.

In plain words
What is it for?
It is for configuring pytest and Vitest, creating test fixtures, testing asynchronous code and background tasks, mocking APIs, and safely testing database-related code.
Why use it?
It helps make tests repeatable and prevents them from accidentally changing real databases or calling live external services.

Skill for Claude CodeCodex

Written for no agent in particular: nothing here depends on one.

Needs its repository: it reads a path above its own folder, which exists only inside the repository. The line is import CampaignCard from '../CampaignCard';.

Good fit It is for configuring pytest and Vitest, creating test fixtures, testing asynchronous code and background tasks, mocking APIs, and safely testing database-related code.

Compare 6 skills from other repositories ↓
Install

Getting it into your agent

It runs from inside its repository, so the clone comes first — what it calls does not travel with the file alone.

Clone the repo
git clone --depth 1 https://github.com/LuuOW/meridian-mcp
agentmods
npx agentmods add skills/luuow/meridian-mcp/unit-test

Made for: Claude Code, Codex.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for unit-test

README.md
[![agentmods](https://agentmods.dev/badge/skills/luuow/meridian-mcp/unit-test/github.svg)](https://agentmods.dev/skills/luuow/meridian-mcp/unit-test)
Your own site
<a href="https://agentmods.dev/skills/luuow/meridian-mcp/unit-test"><img src="https://agentmods.dev/badge/skills/luuow/meridian-mcp/unit-test/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for unit-test

Your own site · 80×15
<a href="https://agentmods.dev/skills/luuow/meridian-mcp/unit-test"><img src="https://agentmods.dev/badge/skills/luuow/meridian-mcp/unit-test.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 57 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 3,197 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00057 $0.03197
Opus 5 $0.00028 $0.01598
Sonnet 5 $0.00011 $0.00639
Haiku 4.5 $0.00006 $0.00320

Measured 5d ago against content hash 156ccaf5398f, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-08, from the pricing page.

Security

Grade A, and why

unit-test scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 5d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

skills/unit-test/SKILL.md · 392 lines

How it starts

The opening of the file, as written. The whole thing — 392 lines — stays where its author put it; the contents beside it link to each section on GitHub.

unit-test

Testing patterns for the Python/FastAPI + React/TypeScript stack. Covers pytest configuration, conftest fixtures, database safety guards, external API mocking, async tests, Celery eager mode, and Vitest for frontend.

1) pytest Configuration

# pytest.ini
[pytest]
testpaths = tests
addopts = -v --tb=short
markers =
    db: Database integration tests (require TEST_DATABASE_URL)
    unit: Pure unit tests (no DB, no network)
    celery: Celery task tests
    slow: Tests that call mocked external APIs
    asyncio: Async tests (pytest-asyncio)
# pyproject.toml alternative
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-v --tb=short"
asyncio_mode = "auto"   # for pytest-asyncio: auto-detect async test functions
markers = [
    "db: Database integration tests",
    "unit: Pure unit tests",
    "slow: Mocked external API tests",
]

[tool.coverage.run]
source = ["app", "shared", "api"]
omit = ["tests/*", "*/migrations/*"]

[tool.coverage.report]
show_missing = true
fail_under = 70

2) conftest.py — Session Fixtures + DB Safety Guard

# tests/conftest.py
import os
import pytest
from database.connection import ThreadedConnectionPool
from database.adapters.psycopg2_adapter import Psycopg2Adapter

# ── Safety guard ──────────────────────────────────────────────────────────
@pytest.fixture(scope="session", autouse=True)
def require_test_database():
    url = os.environ.get("TEST_DATABASE_URL", os.environ.get("DATABASE_URL", ""))
    if not url:
        pytest.fail("DATABASE_URL or TEST_DATABASE_URL must be set to run tests")
    if "test" not in url:
        pytest.fail(
            f"Refusing to run tests against non-test database.\n"
            f"URL must contain 'test': {url}"
        )

# ── Connection pool (session-scoped — created once) ───────────────────────
@pytest.fixture(scope="session")
def db_pool(require_test_database):
    url = os.environ["TEST_DATABASE_URL"]
    pool = ThreadedConnectionPool(minconn=1, maxconn=5, dsn=url)
    yield pool
    pool.closeall()

# ── Per-test DB adapter (auto-cleanup after each test) ────────────────────
@pytest.fixture
def db(db_pool):
    adapter = Psycopg2Adapter(db_pool)
    yield adapter
    # Cleanup: delete all rows in reverse FK order
    for table in ["sends", "prospects", "campaigns", "tenants", "users"]:
        adapter.execute_raw(f"DELETE FROM {table}")
    adapter.close()

# ── Domain fixtures ───────────────────────────────────────────────────────
@pytest.fixture
def sample_tenant(db):
    return db.insert("tenants", {"name": "Test Tenant", "domain": "test.example.com"})

@pytest.fixture
def sample_campaign(db, sample_tenant):
    return db.insert("campaigns", {
        "tenant_id": sample_tenant["id"],
        "name": "Test Campaign",
        "status": "active",
    })

@pytest.fixture
def sample_prospects(db, sample_campaign):
    prospects = [
        {"campaign_id": sample_campaign["id"], "email": f"lead{i}@example.com", "status": "new"}
        for i in range(3)
    ]
    return [db.insert("prospects", p) for p in prospects]

Read the full file on GitHub · 392 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 5d ago First seen · 392 lines · 57 tokens per session scan A 156ccaf5398f

Subscribe to this mod's changes

unit-test is a skill published in the GitHub repository LuuOW/meridian-mcp (0 stars, last pushed 4d ago), licensed MIT. It adds 57 tokens to every session and 3,197 once invoked, about $0.0003 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-03.

Related

Other skills, from other repositories

testing-mcp-tools-locally

Set up the local dev environment, seed data, and API keys to test the staff-only managed migrations MCP tools (managed-migrations-support-list, managed-migrations-support-get) end to end. Use when testing batch import support tooling, debugging MCP tool responses or discovery (tools not appearing), or verifying the…

PostHog/posthog · 98 tokens

authoring-data-quality-checks

Adds and runs data quality checks (dbt-test style assertions) on a project's warehouse tables and saved-query views: not-null, uniqueness, accepted values, referential integrity, row-count bounds, freshness, and custom HogQL. Use when asked to test a model, validate a view, check for nulls or duplicates, add data…

PostHog/posthog · 161 tokens

python-testing

Write or modify Python tests. Use when: adding new tests, understanding testing conventions, working with fixtures, writing FastAPI route tests, database tests, or following pytest patterns. DO NOT USE FOR RUNNING TESTS. If you are just running tests, not building them, you do not need this.

tedivm/robs_awesome_python_template · 64 tokens

pytest

Advanced Python unit testing framework for customer support tech enablement, covering FastAPI, SQLAlchemy, PostgreSQL, async operations, mocking, fixtures, parametrization, coverage, and comprehensive testing strategies for backend support systems.

manutej/luxor-claude-marketplace · 44 tokens

test-generator

A skill for creating unit tests, generating mock data or objects, and analysing test coverage. Unit tests check small parts of a program in isolation.

chainlesschain/chainlesschain · 18 tokens

server-side-calls

Call tRPC procedures directly from server code using t.createCallerFactory() and router.createCaller(context) for integration testing, internal server logic, and custom API endpoints. Catch TRPCError and extract HTTP status with getHTTPStatusCodeFromError(). Error handling via onError option.

trpc/trpc · 61 tokens