Approval Testing Toolkit
lexler/skill-factory
Writes snapshot-style approval tests in Python, JavaScript, TypeScript or Java, comparing output against an approved file instead of writing individual assertions.
Property-based testing with fast-check (TypeScript/JavaScript) and Hypothesis (Python).
$ npx skills add foryourhealth111-pixel/Vibe-Skills --skill property-based-testing -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install foryourhealth111-pixel/Vibe-Skills property-based-testing --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/foryourhealth111-pixel/Vibe-Skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/bundled/skills/property-based-testing .claude/skills/property-based-testing && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "property-based-testing" agent skill from https://github.com/foryourhealth111-pixel/Vibe-Skills/tree/main/bundled/skills/property-based-testing into .claude/skills/property-based-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "property-based-testing", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/foryourhealth111-pixel/Vibe-Skills/tree/main/bundled/skills/property-based-testingType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add foryourhealth111-pixel/Vibe-Skills --skill property-based-testing -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install foryourhealth111-pixel/Vibe-Skills property-based-testing --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/foryourhealth111-pixel/Vibe-Skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/bundled/skills/property-based-testing .agents/skills/property-based-testing && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "property-based-testing" agent skill from https://github.com/foryourhealth111-pixel/Vibe-Skills/tree/main/bundled/skills/property-based-testing into .agents/skills/property-based-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "property-based-testing", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add foryourhealth111-pixel/Vibe-Skills --skill property-based-testing -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install foryourhealth111-pixel/Vibe-Skills property-based-testing --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/foryourhealth111-pixel/Vibe-Skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/bundled/skills/property-based-testing .cursor/skills/property-based-testing && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "property-based-testing" agent skill from https://github.com/foryourhealth111-pixel/Vibe-Skills/tree/main/bundled/skills/property-based-testing into .cursor/skills/property-based-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "property-based-testing", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/foryourhealth111-pixel/Vibe-Skills.git --path bundled/skills/property-based-testing--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add foryourhealth111-pixel/Vibe-Skills --skill property-based-testing -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install foryourhealth111-pixel/Vibe-Skills property-based-testing --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/foryourhealth111-pixel/Vibe-Skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/bundled/skills/property-based-testing .gemini/skills/property-based-testing && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "property-based-testing" agent skill from https://github.com/foryourhealth111-pixel/Vibe-Skills/tree/main/bundled/skills/property-based-testing into .gemini/skills/property-based-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "property-based-testing", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install foryourhealth111-pixel/Vibe-Skills property-based-testingInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add foryourhealth111-pixel/Vibe-Skills --skill property-based-testing -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/foryourhealth111-pixel/Vibe-Skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/bundled/skills/property-based-testing .github/skills/property-based-testing && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "property-based-testing" agent skill from https://github.com/foryourhealth111-pixel/Vibe-Skills/tree/main/bundled/skills/property-based-testing into .github/skills/property-based-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "property-based-testing", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add foryourhealth111-pixel/Vibe-Skills --skill property-based-testing -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install foryourhealth111-pixel/Vibe-Skills property-based-testing --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/foryourhealth111-pixel/Vibe-Skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/bundled/skills/property-based-testing .opencode/skills/property-based-testing && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "property-based-testing" agent skill from https://github.com/foryourhealth111-pixel/Vibe-Skills/tree/main/bundled/skills/property-based-testing into .opencode/skills/property-based-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "property-based-testing", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
property-based-testingProperty-based testing with fast-check (TypeScript/JavaScript) and Hypothesis (Python).
Property Based Testing is an agent skill from foryourhealth111-pixel/Vibe-Skills. Property-based testing with fast-check (TypeScript/JavaScript) and Hypothesis (Python). Generate test cases automatically, find edge cases, and test mathematical properties. Use when user mentions property-based testing, fast-check, Hypothesis, generating test data, QuickCheck-style testing, or finding edge cases automatically.
Its SKILL.md is about 4.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Testing & QA, covering Test generation. It works with JavaScript, Python and TypeScript. The repository describes itself as: Intelligent Skill routing and workflow orchestration for AI agents — +21.12 pp reward, −29.6% tokens on SkillsBench with DeepSeekV4Flash-VE. The licence is Apache-2.0.
Read from SKILL.md and the folder at commit ddcaa2a. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
BashReadEditWriteGrepGlobTodoWriteFrom allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
bunnpmuvpipFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
fast-check.devhypothesis.readthedocs.iofsharpforfunandprofit.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Property Based Testing loads about 4.8k tokens when it runs. Until then it costs about 88 tokens; SKILL.md has 295 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check noted patterns worth knowing about, such as sudo or a known installer.
allowed-tools: Bash, Read, Edit, Write, Grep, Glob, TodoWriteAutomated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from foryourhealth111-pixel/Vibe-Skills at commit ddcaa2a, republished under its Apache-2.0 licence (© foryourhealth111-pixel). 295 words, ~4,750 tokens.
.claude/skills/property-based-testing/SKILL.md (or your agent's skills folder).Expert knowledge for property-based testing - automatically generating test cases to verify code properties rather than testing specific examples.
Property-Based Testing Concept
When to Use Property-Based Testing
# Using Bun
bun add -d fast-check
# Using npm
npm install -D fast-checkimport { test } from 'vitest'
import * as fc from 'fast-check'
// Traditional example-based test
test('reverse twice returns original', () => {
expect(reverse(reverse([1, 2, 3]))).toEqual([1, 2, 3])
})
// 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!import * as fc from 'fast-check'
// Numbers
fc.integer() // Any integer
fc.integer({ min: 0, max: 100 }) // Range
fc.nat() // Natural numbers (≥ 0)
fc.float() // Floating-point
fc.double() // Double precision
// Strings
fc.string() // Any string
fc.string({ minLength: 1, maxLength: 10 })
fc.hexaString() // Hex strings
fc.asciiString() // ASCII only
fc.unicodeString() // Unicode
fc.emailAddress() // Email format
// Arrays and Objects
fc.array(fc.integer()) // Array of integers
fc.array(fc.string(), { minLength: 1, maxLength: 5 })
fc.set(fc.integer()) // Unique values
fc.record({ // Objects
name: fc.string(),
age: fc.nat(),
})
// Booleans and Constants
fc.boolean()
fc.constant('value')
fc.constantFrom('a', 'b', 'c') // Pick from options
// Dates
fc.date()
fc.date({ min: new Date('2020-01-01') })
// Complex Types
fc.tuple(fc.string(), fc.integer()) // Fixed-size tuple
fc.oneof(fc.string(), fc.integer()) // Union type
fc.option(fc.string()) // string | null// Generate user objects
const userArbitrary = fc.record({
id: fc.nat(),
name: fc.string({ minLength: 1, maxLength: 50 }),
email: fc.emailAddress(),
age: fc.integer({ min: 18, max: 120 }),
roles: fc.array(fc.constantFrom('admin', 'user', 'guest'), {
minLength: 1,
maxLength: 3,
}),
})
test('user validation properties', () => {
fc.assert(
fc.property(userArbitrary, (user) => {
const validated = validateUser(user)
expect(validated.age).toBeGreaterThanOrEqual(18)
expect(validated.name.length).toBeGreaterThan(0)
expect(validated.roles.length).toBeGreaterThan(0)
})
)
})
// Generate using map
const positiveNumberArbitrary = fc.nat().map((n) => n + 1)
// Generate using chain (dependent values)
const emailAndDomainArbitrary = fc.string().chain((domain) =>
fc.record({
email: fc.constant(`user@${domain}.com`),
domain: fc.constant(domain),
})
)test('JSON serialization roundtrip', () => {
fc.assert(
fc.property(
fc.record({
name: fc.string(),
age: fc.nat(),
tags: fc.array(fc.string()),
}),
(obj) => {
const serialized = JSON.stringify(obj)
const deserialized = JSON.parse(serialized)
expect(deserialized).toEqual(obj)
}
)
)
})test('sort is idempotent', () => {
fc.assert(
fc.property(fc.array(fc.integer()), (arr) => {
const sorted = sort(arr)
const doubleSorted = sort(sorted)
expect(doubleSorted).toEqual(sorted)
})
)
})test('addition is commutative', () => {
fc.assert(
fc.property(fc.integer(), fc.integer(), (a, b) => {
expect(add(a, b)).toBe(add(b, a))
})
)
})test('addition is associative', () => {
fc.assert(
fc.property(fc.integer(), fc.integer(), fc.integer(), (a, b, c) => {
expect(add(add(a, b), c)).toBe(add(a, add(b, c)))
})
)
})test('multiplication identity', () => {
fc.assert(
fc.property(fc.integer(), (n) => {
expect(multiply(n, 1)).toBe(n)
})
)
})test('encryption/decryption inverse', () => {
fc.assert(
fc.property(fc.string(), fc.string(), (plaintext, key) => {
const encrypted = encrypt(plaintext, key)
const decrypted = decrypt(encrypted, key)
expect(decrypted).toBe(plaintext)
})
)
})// When a property fails, fast-check automatically shrinks
// the input to the minimal failing case
test('finds minimal failing case', () => {
fc.assert(
fc.property(fc.array(fc.integer()), (arr) => {
// This will fail for arrays containing 42
expect(arr).not.toContain(42)
})
)
})
// Output:
// Property failed after 1 tests
// Shrunk 5 time(s)
// Counterexample: [[42]] ← Minimal failing case!test('configured property test', () => {
fc.assert(
fc.property(fc.array(fc.integer()), (arr) => {
expect(sort(arr)).toBeSorted()
}),
{
numRuns: 1000, // Run 1000 tests (default: 100)
seed: 42, // Reproducible tests
endOnFailure: true, // Stop after first failure
verbose: true, // Show all generated values
}
)
})test('division properties for non-zero divisors', () => {
fc.assert(
fc.property(fc.integer(), fc.integer(), (a, b) => {
fc.pre(b !== 0) // Skip cases where b is 0
const result = divide(a, b)
expect(multiply(result, b)).toBeCloseTo(a)
})
)
})# Using uv
uv add --dev hypothesis
# Using pip
pip install hypothesisfrom hypothesis import given, strategies as st
import pytest
# Traditional example-based test
def test_reverse_twice_example():
assert reverse(reverse([1, 2, 3])) == [1, 2, 3]
# Property-based test
@given(st.lists(st.integers()))
def test_reverse_twice_property(arr):
assert reverse(reverse(arr)) == arr
# Hypothesis automatically generates 100s of test cases!from hypothesis import strategies as st
# Numbers
st.integers() # Any integer
st.integers(min_value=0, max_value=100)
st.floats() # Floating-point
st.floats(min_value=0.0, max_value=1.0, allow_nan=False)
st.decimals() # Decimal precision
# Strings
st.text() # Any string
st.text(min_size=1, max_size=10)
st.text(alphabet='abc') # Limited alphabet
st.binary() # Bytes
# Collections
st.lists(st.integers()) # List of integers
st.lists(st.text(), min_size=1, max_size=5)
st.sets(st.integers()) # Unique values
st.dictionaries(keys=st.text(), values=st.integers())
# Booleans and Constants
st.booleans()
st.just('value') # Constant
st.sampled_from(['a', 'b', 'c']) # Pick from options
# Dates and Times
st.dates()
st.datetimes()
st.times()
st.timedeltas()
# Complex Types
st.tuples(st.text(), st.integers()) # Fixed-size tuple
st.one_of(st.text(), st.integers()) # Union typefrom hypothesis import strategies as st
from dataclasses import dataclass
@dataclass
class User:
id: int
name: str
email: str
age: int
# Strategy for generating users
users = st.builds(
User,
id=st.integers(min_value=1),
name=st.text(min_size=1, max_size=50),
email=st.emails(),
age=st.integers(min_value=18, max_value=120),
)
@given(users)
def test_user_validation(user):
validated = validate_user(user)
assert validated.age >= 18
assert len(validated.name) > 0# Using map
positive_numbers = st.integers(min_value=0).map(lambda n: n + 1)
# Using flatmap (dependent values)
@st.composite
def email_and_domain(draw):
domain = draw(st.text(min_size=1))
return {
'email': f'user@{domain}.com',
'domain': domain,
}import json
from hypothesis import given, strategies as st
@given(st.dictionaries(
keys=st.text(),
values=st.one_of(st.integers(), st.text(), st.booleans())
))
def test_json_roundtrip(obj):
serialized = json.dumps(obj)
deserialized = json.loads(serialized)
assert deserialized == obj@given(st.lists(st.integers()))
def test_sort_idempotent(arr):
sorted_once = sorted(arr)
sorted_twice = sorted(sorted_once)
assert sorted_once == sorted_twice@given(st.integers(), st.integers())
def test_addition_commutative(a, b):
assert add(a, b) == add(b, a)@given(st.integers(), st.integers(), st.integers())
def test_addition_associative(a, b, c):
assert add(add(a, b), c) == add(a, add(b, c))@given(st.integers())
def test_multiplication_identity(n):
assert multiply(n, 1) == n@given(st.text(), st.text(min_size=1))
def test_encryption_inverse(plaintext, key):
encrypted = encrypt(plaintext, key)
decrypted = decrypt(encrypted, key)
assert decrypted == plaintextfrom hypothesis import given, strategies as st
@given(st.lists(st.integers()))
def test_finds_minimal_failing_case(arr):
# This will fail for arrays containing 42
assert 42 not in arr
# Output:
# Falsifying example: test_finds_minimal_failing_case(
# arr=[42] ← Minimal failing case!
# )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)
# Global settings
from hypothesis import settings, Verbosity
settings.register_profile("ci", max_examples=1000, verbosity=Verbosity.verbose)
settings.register_profile("dev", max_examples=100)
settings.load_profile("dev")from hypothesis import given, assume, strategies as st
@given(st.integers(), st.integers())
def test_division_properties(a, b):
assume(b != 0) # Skip cases where b is 0
result = divide(a, b)
assert abs(multiply(result, b) - a) < 0.0001from hypothesis.stateful import RuleBasedStateMachine, rule, invariant
from hypothesis import strategies as st
class ShoppingCartMachine(RuleBasedStateMachine):
def __init__(self):
super().__init__()
self.cart = ShoppingCart()
self.items = []
@rule(item=st.text(min_size=1), price=st.floats(min_value=0.01, max_value=1000))
def add_item(self, item, price):
self.cart.add(item, price)
self.items.append((item, price))
@rule()
def clear_cart(self):
self.cart.clear()
self.items = []
@invariant()
def total_matches_items(self):
expected_total = sum(price for _, price in self.items)
assert abs(self.cart.total() - expected_total) < 0.01
# Run stateful test
TestCart = ShoppingCartMachine.TestCaseimport * as fc from 'fast-check'
test('URL parsing roundtrip', () => {
fc.assert(
fc.property(
fc.webUrl(), // Built-in URL generator
(url) => {
const parsed = parseURL(url)
const reconstructed = buildURL(parsed)
expect(normalizeURL(reconstructed)).toBe(normalizeURL(url))
}
)
)
})from hypothesis import given, strategies as st
from pydantic import BaseModel, ValidationError
class Product(BaseModel):
name: str
price: float
quantity: int
@given(st.builds(
Product,
name=st.text(min_size=1),
price=st.floats(min_value=0.01, max_value=10000),
quantity=st.integers(min_value=0, max_value=1000),
))
def test_product_validation_accepts_valid_data(product):
# Should not raise
validated = Product(**product.dict())
assert validated.price > 0
assert validated.quantity >= 0test('filter and map compose correctly', () => {
fc.assert(
fc.property(
fc.array(fc.integer()),
fc.func(fc.boolean()),
fc.func(fc.integer()),
(arr, predicate, transform) => {
const result1 = arr.filter(predicate).map(transform)
const result2 = arr.map(transform).filter((_, i) =>
predicate(arr[i])
)
// Order might differ but length should match
expect(result1.length).toBe(result2.length)
}
)
)
})from hypothesis import given, strategies as st
@given(st.text(), st.integers())
def test_cache_returns_same_value(key, value):
cache = Cache()
# First set
cache.set(key, value)
result1 = cache.get(key)
# Second get should return same value
result2 = cache.get(key)
assert result1 == value
assert result2 == valueStart with Properties
Complement Example-Based Tests
// Use both approaches
test('addition examples', () => {
expect(add(2, 3)).toBe(5)
expect(add(-1, 1)).toBe(0)
})
test('addition properties', () => {
fc.assert(
fc.property(fc.integer(), fc.integer(), (a, b) => {
expect(add(a, b)).toBe(add(b, a)) // Commutative
expect(add(a, 0)).toBe(a) // Identity
})
)
})Shrinking is Your Friend
Performance Considerations
// Limit expensive tests
fc.assert(
fc.property(fc.array(fc.integer()), (arr) => {
expensiveOperation(arr)
}),
{ numRuns: 50 } // Reduce from default 100
)Reproducibility
# Set seed for reproducible failures
@settings(derandomize=True)
@given(st.lists(st.integers()))
def test_reproducible(arr):
assert process(arr) is not NoneOverly Permissive Assertions
// ❌ BAD: Too weak
fc.assert(
fc.property(fc.array(fc.integer()), (arr) => {
expect(sort(arr)).toBeDefined() // Passes even if sort is broken!
})
)
// ✅ GOOD: Specific properties
fc.assert(
fc.property(fc.array(fc.integer()), (arr) => {
const sorted = sort(arr)
// Check actual properties
for (let i = 1; i < sorted.length; i++) {
expect(sorted[i]).toBeGreaterThanOrEqual(sorted[i - 1])
}
})
)Too Many Assumptions
# ❌ BAD: Filters out too many cases
@given(st.integers(), st.integers())
def test_slow(a, b):
assume(a > 100)
assume(a < 110)
assume(b > 200)
assume(b < 210)
# Better to use specific strategy!
# ✅ GOOD: Generate what you need
@given(st.integers(min_value=101, max_value=109),
st.integers(min_value=201, max_value=209))
def test_fast(a, b):
# No filtering neededTesting Implementation, Not Properties
// ❌ BAD: Tests implementation
fc.assert(
fc.property(fc.array(fc.integer()), (arr) => {
const spy = vi.spyOn(Math, 'max')
sort(arr)
expect(spy).toHaveBeenCalled() // Testing how it's implemented
})
)
// ✅ GOOD: Tests properties
fc.assert(
fc.property(fc.array(fc.integer()), (arr) => {
const sorted = sort(arr)
// Test what it does, not how
expect(sorted.length).toBe(arr.length)
expect(new Set(sorted)).toEqual(new Set(arr))
})
){
"scripts": {
"test": "vitest",
"test:property": "vitest --grep 'property'",
"test:ci": "vitest --run --coverage"
}
}# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v1
- run: uv sync
- run: uv run pytest --hypothesis-show-statisticsTests taking too long
// Reduce number of runs
fc.assert(property, { numRuns: 50 })@settings(max_examples=50)
@given(...)Hard to find failing case
// Increase attempts
fc.assert(property, { numRuns: 10000 })Flaky property tests
# Use seed for reproducibility
@settings(derandomize=True)Too many filtered cases
Hypothesis: Unable to satisfy assumptions→ Use more specific generators instead of assume()
vitest-testing - Unit testing frameworkpython-testing - Python pytest testingtest-quality-analysis - Detecting test smellsmutation-testing - Validate test effectiveness© foryourhealth111-pixel, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in bundled/skills/property-based-testing of foryourhealth111-pixel/Vibe-Skills.
Open the folder on GitHubat commit ddcaa2a
Property Based Testing next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Property Based Testing this skillforyourhealth111-pixel/Vibe-Skills | 3.6k | — | ~4.8k | Automated safety check: Notes | Apache-2.0 | |
| Approval Testing Toolkitlexler/skill-factory | 239 | — | ~1.2k | Automated safety check: Pass | Apache-2.0 | |
| Polyglot Test Agentboshi-xixixi/TraeSkill | 276 | — | ~1.7k | Automated safety check: Pass | MIT | |
| Langgraph Testing Evaluationsoba-labs/langchain-agent-skills | 107 | — | ~2.3k | Automated safety check: Pass | MIT | |
| Liveblog Devliveblog/liveblog | 119 | — | ~1.9k | Automated safety check: Pass | AGPL-3.0 | |
| Supercovsupercorp-ai/supercov | 152 | 1 repos | ~415 | Automated safety check: Pass | MIT |
lexler/skill-factory
Writes snapshot-style approval tests in Python, JavaScript, TypeScript or Java, comparing output against an approved file instead of writing individual assertions.
boshi-xixixi/TraeSkill
Generates comprehensive, workable unit tests for any programming language using a multi-agent pipeline.
soba-labs/langchain-agent-skills
A skill your agent uses when you need to test or evaluate LangGraph/LangChain agents: writing unit or integration tests, generating test scaffolds, mocking LLM/tool behavior, running trajectory…
liveblog/liveblog
Run a local Liveblog development environment. An agent skill from liveblog/liveblog.
supercorp-ai/supercov
Measures test coverage and code quality in a repository with the supercov CLI, and turns what it finds into small, focused tests or fixes.
swingerman/engineer
A skill your agent uses to produce a risk-based refactor + test plan for recently-changed code on a diff/branch/PR by computing CRAP (complexity × untested) on changed methods.
foryourhealth111-pixel/Vibe-Skills
Produces long consulting-style market research and industry reports covering market sizing, competitive landscape, market entry and investment theses.
foryourhealth111-pixel/Vibe-Skills
Supplies venue-specific LaTeX templates and formatting rules for journals, conferences and posters, and checks a manuscript against page limits and submission requirements.
foryourhealth111-pixel/Vibe-Skills
This skill should be used when the user asks to "write a post", "check my voice", "look up contact", "prepare for meeting", "weekly review", "track goals", or mentions personal brand, content…
foryourhealth111-pixel/Vibe-Skills
Diagnoses why a file write failed (permissions, disk space, path length, locks, read-only mounts) before retrying, instead of repeating the same call blindly.
foryourhealth111-pixel/Vibe-Skills
Turns footage, audio and a storyboard plan into a finished short video with FFmpeg jump-cuts, subtitle burn-in and a final polish pass.
foryourhealth111-pixel/Vibe-Skills
Turns DOIs, PMIDs and arXiv IDs into clean BibTeX, searches Google Scholar and PubMed, and checks and deduplicates a reference list.
Works with
Categories
Property-based testing with fast-check (TypeScript/JavaScript) and Hypothesis (Python). Property Based Testing is an agent skill from foryourhealth111-pixel/Vibe-Skills. Property-based testing with fast-check (TypeScript/JavaScript) and Hypothesis (Python).
Property Based Testing fits situations like: user mentions property-based testing; generating test data; quickCheck-style testing; finding edge cases automatically.
Run `npx skills add foryourhealth111-pixel/Vibe-Skills --skill property-based-testing -a claude-code`. Or copy the skill folder (bundled/skills/property-based-testing in foryourhealth111-pixel/Vibe-Skills) into .claude/skills/property-based-testing in your project. Claude Code loads it when a task matches its description.
Run `npx skills add foryourhealth111-pixel/Vibe-Skills --skill property-based-testing -a codex`. Or copy the skill folder (bundled/skills/property-based-testing in foryourhealth111-pixel/Vibe-Skills) into .agents/skills/property-based-testing in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add foryourhealth111-pixel/Vibe-Skills --skill property-based-testing -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/property-based-testing, .gemini/skills/property-based-testing, .github/skills/property-based-testing and .opencode/skills/property-based-testing in your project.
Going by SKILL.md and its folder, Property Based Testing needs the command-line tools its instructions call (bun, npm, uv and pip). Our summary lists: Python 3; Node.js. Its frontmatter pre-approves these tools: Bash, Read, Edit, Write, Grep, Glob, TodoWrite.
SKILL.md names 3 domains. As links in the text: fast-check.dev, hypothesis.readthedocs.io and fsharpforfunandprofit.com. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (pre-approves every shell command (allowed-tools: bash)), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Property Based Testing is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.8k tokens (SKILL.md is roughly 19k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Property Based Testing: Approval Testing Toolkit (lexler/skill-factory, 239 stars), Polyglot Test Agent (boshi-xixixi/TraeSkill, 276 stars), Langgraph Testing Evaluation (soba-labs/langchain-agent-skills, 107 stars) and Liveblog Dev (liveblog/liveblog, 119 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
foryourhealth111-pixel (a GitHub user) maintains it in foryourhealth111-pixel/Vibe-Skills, which has 3,627 GitHub stars. The repository holds 81 skills in this directory. The repository was last updated on August 31, 2026.
Source: foryourhealth111-pixel/Vibe-Skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.