From testing-plugin
Generates property-based tests using fast-check (TypeScript/JavaScript with Vitest) and Hypothesis (Python) to find edge cases, verify properties like roundtrips and invariants.
npx claudepluginhub laurigates/claude-plugins --plugin testing-pluginThis skill is limited to using the following tools:
Expert knowledge for property-based testing - automatically generating test cases to verify code properties rather than testing specific examples.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Expert knowledge for property-based testing - automatically generating test cases to verify code properties rather than testing specific examples.
| Use this skill when... | Use another skill instead when... |
|---|---|
| Testing mathematical properties (commutative, associative) | Writing specific example-based unit tests |
| Testing encode/decode roundtrips | Setting up test runner configuration |
| Finding edge cases automatically | Doing E2E browser testing |
| Validating data transformations and invariants | Analyzing test quality or smells |
| Testing API contracts with generated data | Running mutation testing |
Property-Based Testing Concept
When to Use Property-Based Testing
# Using Bun
bun add -d fast-check
# Using npm
npm install -D fast-check
import { test } from 'vitest'
import * as fc from 'fast-check'
// Property-based test
test('reverse twice returns original - property based', () => {
fc.assert(
fc.property(
fc.array(fc.integer()), // Generate random arrays of integers
(arr) => {
expect(reverse(reverse(arr))).toEqual(arr)
}
)
)
})
// fast-check automatically generates 100s of test cases!
| Generator | Description |
|---|---|
fc.integer() | Any integer (with optional min/max) |
fc.nat() | Natural numbers (>= 0) |
fc.float() / fc.double() | Floating-point numbers |
fc.string() | Any string (with optional length) |
fc.emailAddress() | Email format strings |
fc.array(arb) | Arrays of arbitrary type |
fc.record({...}) | Object with typed fields |
fc.boolean() | Boolean values |
fc.constantFrom(...) | Pick from options |
fc.tuple(...) | Fixed-size tuples |
fc.oneof(...) | Union types |
fc.option(arb) | Value or null |
fc.date() | Date objects |
| Property | Pattern | Example |
|---|---|---|
| Roundtrip | f(g(x)) = x | encode/decode, serialize/parse |
| Idempotence | f(f(x)) = f(x) | sort, normalize, format |
| Commutativity | f(a,b) = f(b,a) | add, merge, union |
| Associativity | f(f(a,b),c) = f(a,f(b,c)) | add, concat |
| Identity | f(x, id) = x | multiply by 1, add 0 |
| Inverse | f(g(x)) = x | encrypt/decrypt |
fc.assert(property, {
numRuns: 1000, // Run 1000 tests (default: 100)
seed: 42, // Reproducible tests
endOnFailure: true, // Stop after first failure
})
fc.pre(b !== 0) // Skip cases where b is 0
# Using uv
uv add --dev hypothesis
# Using pip
pip install hypothesis
from hypothesis import given, strategies as st
@given(st.lists(st.integers()))
def test_reverse_twice_property(arr):
assert reverse(reverse(arr)) == arr
# Hypothesis automatically generates 100s of test cases!
| Strategy | Description |
|---|---|
st.integers() | Any integer (with optional bounds) |
st.floats() | Floating-point numbers |
st.text() | Any string (with optional size) |
st.binary() | Byte strings |
st.lists(strat) | Lists of given strategy |
st.sets(strat) | Unique value sets |
st.dictionaries(k, v) | Dictionaries |
st.booleans() | Boolean values |
st.sampled_from(...) | Pick from options |
st.tuples(...) | Fixed-size tuples |
st.one_of(...) | Union types |
st.dates() / st.datetimes() | Date/time values |
st.builds(Class, ...) | Build objects from strategies |
from hypothesis import given, settings, strategies as st
@settings(max_examples=1000, deadline=None)
@given(st.lists(st.integers()))
def test_with_custom_settings(arr):
assert sort(arr) == sorted(arr)
from hypothesis import assume
assume(b != 0) # Skip cases where b is 0
Hypothesis supports stateful testing via RuleBasedStateMachine for testing sequences of operations against invariants.
| Context | Command |
|---|---|
| Quick TS test | bunx vitest --dots --bail=1 --grep 'property' |
| Quick Python test | uv run pytest -x -q --tb=short -k 'property' |
| CI TS test | bunx vitest run --reporter=junit --grep 'property' |
| CI Python test | uv run pytest --hypothesis-show-statistics -q |
| Reproducible | fc.assert(prop, { seed: 42 }) or @settings(derandomize=True) |
| Fast iteration | fc.assert(prop, { numRuns: 50 }) or @settings(max_examples=50) |
For detailed examples, advanced patterns, and best practices, see REFERENCE.md.
vitest-testing - Unit testing frameworkpython-testing - Python pytest testingtest-quality-analysis - Detecting test smellsmutation-testing - Validate test effectiveness