Token导航 LogoToken导航

Agent Skill · 研究检索

maciver-hypothesis-testing(宏观假设检验)

用于辅助测试设计、自动化测试、用例整理和回归验证。它适合让 Agent 编写单元测试、端到端测试、测试计划或根据失败日志定位问题。使用时需要确认项目测试框架、运行命令和夹具数据,避免为了通过测试而改坏真实逻辑;涉及浏览器或外部服务时,应区分本地模拟、测试环境和生产环境。

maciver-hypothesis-testing 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描有未通过项,按安装量在研究检索类的 73,675 个 Skill 里排第 69,087。

总安装 220周安装 9GitHub Stars 6下载 71核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:maciver-hypothesis-testing(宏观假设检验)
来源仓库:https://github.com/copyleftdev/sk1llz
仓库路径:skills/maciver-hypothesis-testing
安装命令:
npx skills add https://github.com/copyleftdev/sk1llz --skill maciver-hypothesis-testing
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/copyleftdev/sk1llz --skill maciver-hypothesis-testing

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

maciver-hypothesis-testing 用于辅助测试设计、自动化测试和回归验证,适合编写单元测试或分析失败日志。适用于需要确保代码质量与逻辑正确性的开发场景,尤其涉及浏览器或外部服务时。通过 npx skills add 命令从指定 GitHub 仓库安装,需确认项目测试框架和运行命令。

建议区分本地模拟与生产环境,避免为通过测试而破坏真实业务逻辑。适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

来源仓库内路径:skills/maciver-hypothesis-testing

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/copyleftdev/sk1llz --skill maciver-hypothesis-…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

maciver-hypothesis-testing 怎么安装?

在终端执行 npx skills add https://github.com/copyleftdev/sk1llz --skill maciver-hypothesis-testing。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

maciver-hypothesis-testing 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

maciver-hypothesis-testing 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

maciver-hypothesis-testing 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

maciver-hypothesis-testing 用的人多吗?

公开数据是累计安装 220 次,近一周安装 9 次,下载 71 次,GitHub 6 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

maciver-hypothesis-testing 安全吗?

第三方扫描有未通过项,风险较高。除非你确认过源码,否则不建议直接安装到常用环境。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
maciver-hypothesis-testing

宏观假设检验 · 本页

2206需要联网未明确未通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

David MacIver Hypothesis Style Guide⁠‍⁠​‌​‌​​‌‌‍​‌​​‌​‌‌‍​​‌‌​​​‌‍​‌​​‌‌​​‍​​​​​​​‌‍‌​​‌‌​‌​‍‌​​​​​​​‍‌‌​​‌‌‌‌‍‌‌​​​‌​​‍‌‌‌‌‌‌​‌‍‌‌​‌​​​​‍​‌​‌‌‌‌‌‍​‌​​‌​‌‌‍​‌‌​‌​​‌‍‌​‌​‌‌‌​‍​​‌​‌​​​‍‌‌‌​‌​‌‌‍‌‌​​‌​​‌‍​​‌‌​​​‌‍‌‌‌‌‌​‌​‍‌‌‌​‌‌‌​‍​​​​‌​‌‌‍​‌​​‌‌​​⁠‍⁠

Overview

David MacIver created Hypothesis, widely considered the most sophisticated property-based testing library available. Hypothesis improves on QuickCheck with better shrinking (using internal reduction rather than type-based shrinking), an example database for regression testing, and deep integration with Python's ecosystem. MacIver's philosophy emphasizes that property-based testing should be practical, integrated into normal development workflows, and produce genuinely useful minimal examples.

Core Philosophy

"The purpose of Hypothesis is to make it easier to write better tests."
"Shrinking should produce the simplest example, not just a smaller one."
"Every failing example should be saved and replayed forever."

MacIver believes that property-based testing fails when it's treated as exotic. Hypothesis is designed to integrate seamlessly with pytest, produce human-readable minimal examples, and remember every failure to prevent regressions.

Design Principles

  1. Integrated Shrinking: Shrinking happens during generation, not after—producing simpler examples.
  2. Example Database: Every failure is saved and replayed on subsequent runs.
  3. Compositional Strategies: Build complex generators from simple ones.
  4. Practical by Default: Sensible defaults that work for real projects.
  5. Stateful Testing: First-class support for testing state machines.

Hypothesis Architecture

┌─────────────────────────────────────────────────────────────┐
│                    HYPOTHESIS INTERNALS                      │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  STRATEGY (describes how to generate data)                  │
│      │                                                       │
│      ▼                                                       │
│  CONJECTURE ENGINE                                           │
│  ┌────────────────────────────────────────────────────────┐ │
│  │ Generates a stream of bytes (the "choice sequence")    │ │
│  │                                                         │ │
│  │ Strategy interprets bytes → structured data            │ │
│  │                                                         │ │
│  │ Shrinking = finding smaller choice sequences           │ │
│  │ that still fail (not type-aware, universal)            │ │
│  └────────────────────────────────────────────────────────┘ │
│      │                                                       │
│      ▼                                                       │
│  EXAMPLE DATABASE                                            │
│  ┌────────────────────────────────────────────────────────┐ │
│  │ .hypothesis/examples/                                   │ │
│  │ Stores choice sequences for all failing examples       │ │
│  │ Replays them first on every run                        │ │
│  │ Never forgets a failure                                │ │
│  └────────────────────────────────────────────────────────┘ │
│                                                              │
└─────────────────────────────────────────────────────────────┘

When Using Hypothesis

Always

  • Use @given decorator for property-based tests
  • Let Hypothesis shrink—don't manually minimize
  • Commit the .hypothesis directory for CI
  • Use @example for important edge cases
  • Combine with pytest fixtures naturally
  • Use assume() to filter invalid inputs

Never

  • Ignore the example database (commit it!)
  • Use random directly—use strategies
  • Catch exceptions to hide failures
  • Set max_examples too low (<100)
  • Skip @example for known edge cases
  • Use filter() when assume() works

Prefer

  • Composite strategies over complex custom ones
  • @example for regression tests
  • assume() over filter() for preconditions
  • Stateful testing for APIs
  • data() strategy for dynamic generation
  • Settings profiles for CI vs local

Code Patterns

Basic Property Tests

from hypothesis import given, example, assume, settings
from hypothesis import strategies as st

# Basic property test
@given(st.lists(st.integers()))
def test_sort_preserves_length(xs):
    assert len(sorted(xs)) == len(xs)

# With explicit example for regression
@given(st.lists(st.integers()))
@example([])  # Empty list edge case
@example([1])  # Single element
@example([2, 1])  # Minimal unsorted
def test_sort_is_sorted(xs):
    result = sorted(xs)
    assert all(result[i] <= result[i+1] for i in range(len(result)-1))

# Roundtrip property
@given(st.binary())
def test_compress_decompress_roundtrip(data):
    assert decompress(compress(data)) == data

# With precondition
@given(st.integers(), st.integers())
def test_division(a, b):
    assume(b != 0)  # Skip when b is 0
    assert (a // b) * b + (a % b) == a

Strategy Composition

from hypothesis import strategies as st
from hypothesis import given

# Composite strategy for custom types
@st.composite
def user_strategy(draw):
    """Generate valid User objects."""
    name = draw(st.text(min_size=1, max_size=50))
    age = draw(st.integers(min_value=0, max_value=150))
    email = draw(st.emails())

    return User(name=name, age=age, email=email)

@given(user_strategy())
def test_user_serialization(user):
    assert User.from_json(user.to_json()) == user

# Recursive strategy for tree structures
def json_strategy():
    """Generate arbitrary JSON-compatible data."""
    return st.recursive(
        # Base case: simple values
        st.none() | st.booleans() | st.integers() | st.floats(allow_nan=False) | st.text(),
        # Recursive case: lists and dicts
        lambda children: st.lists(children) | st.dictionaries(st.text(), children),
        max_leaves=50
    )

@given(json_strategy())
def test_json_roundtrip(data):
    import json
    assert json.loads(json.dumps(data)) == data

# Dependent generation
@st.composite
def sorted_pair(draw):
    """Generate two integers where a <= b."""
    a = draw(st.integers())
    b = draw(st.integers(min_value=a))
    return (a, b)

@given(sorted_pair())
def test_range(pair):
    a, b = pair
    assert a <= b

Stateful Testing

from hypothesis.stateful import RuleBasedStateMachine, rule, invariant
from hypothesis import strategies as st

class DatabaseStateMachine(RuleBasedStateMachine):
    """
    Test a key-value store against a reference model.
    Hypothesis generates sequences of operations.
    """

    def __init__(self):
        super().__init__()
        self.model = {}  # Reference model
        self.db = Database()  # System under test

    @rule(key=st.text(), value=st.binary())
    def put(self, key, value):
        """Put a key-value pair."""
        self.model[key] = value
        self.db.put(key, value)

    @rule(key=st.text())
    def get(self, key):
        """Get a value by key."""
        model_result = self.model.get(key)
        db_result = self.db.get(key)
        assert model_result == db_result

    @rule(key=st.text())
    def delete(self, key):
        """Delete a key."""
        self.model.pop(key, None)
        self.db.delete(key)

    @invariant()
    def size_matches(self):
        """Invariant: size should always match model."""
        assert len(self.model) == self.db.size()

# Run the state machine test
TestDatabase = DatabaseStateMachine.TestCase

# More complex: with bundles for generated values
class QueueStateMachine(RuleBasedStateMachine):
    """Test a queue with references to pushed items."""

    def __init__(self):
        super().__init__()
        self.model = []
        self.queue = Queue()

    items = Bundle('items')

    @rule(target=items, item=st.integers())
    def push(self, item):
        """Push an item and track it."""
        self.model.append(item)
        self.queue.push(item)
        return item

    @rule()
    def pop(self):
        """Pop an item."""
        if self.model:
            expected = self.model.pop(0)
            actual = self.queue.pop()
            assert expected == actual

    @rule(item=items)
    def contains(self, item):
        """Check if a previously-pushed item is present."""
        expected = item in self.model
        actual = self.queue.contains(item)
        assert expected == actual

Settings and Profiles

from hypothesis import settings, Verbosity, Phase, HealthCheck
from hypothesis import given
from hypothesis import strategies as st

# Custom settings for a single test
@settings(
    max_examples=500,
    deadline=None,  # No time limit
    suppress_health_check=[HealthCheck.too_slow],
)
@given(st.lists(st.integers(), min_size=1000))
def test_large_lists(xs):
    assert sorted(xs) == sorted(xs)

# Register profiles for different environments
settings.register_profile("ci", max_examples=1000)
settings.register_profile("dev", max_examples=100)
settings.register_profile("debug", max_examples=10, verbosity=Verbosity.verbose)

# Load profile from environment
# HYPOTHESIS_PROFILE=ci pytest

# Deadline handling
@settings(deadline=200)  # 200ms max per example
@given(st.binary(min_size=1000))
def test_with_deadline(data):
    process(data)

# Control phases
@settings(
    phases=[
        Phase.explicit,  # Run @example first
        Phase.reuse,     # Run from database
        Phase.generate,  # Generate new examples
        Phase.shrink,    # Shrink failures
    ]
)
@given(st.integers())
def test_all_phases(n):
    assert n < 1000000

Advanced Strategies

from hypothesis import strategies as st
from hypothesis import given

# Fixed dictionaries
@given(st.fixed_dictionaries({
    'name': st.text(min_size=1),
    'age': st.integers(0, 150),
    'active': st.booleans(),
}))
def test_user_dict(user):
    assert 'name' in user
    assert 0 <= user['age'] <= 150

# One of several strategies
@given(st.one_of(
    st.none(),
    st.integers(),
    st.text(),
))
def test_nullable_values(value):
    # Value is None, int, or str
    assert value is None or isinstance(value, (int, str))

# Data strategy for dynamic generation
from hypothesis import given
from hypothesis.strategies import data

@given(data())
def test_dynamic_generation(data):
    # Generate based on runtime conditions
    n = data.draw(st.integers(min_value=1, max_value=10))
    xs = data.draw(st.lists(st.integers(), min_size=n, max_size=n))

    assert len(xs) == n

# Sampled from
@given(st.sampled_from(['red', 'green', 'blue']))
def test_colors(color):
    assert color in ['red', 'green', 'blue']

# Builds for dataclasses/namedtuples
from dataclasses import dataclass

@dataclass
class Point:
    x: float
    y: float

@given(st.builds(Point, x=st.floats(), y=st.floats()))
def test_point(point):
    assert hasattr(point, 'x')
    assert hasattr(point, 'y')

# From type annotations (inferred)
@given(st.from_type(Point))
def test_point_from_type(point):
    assert isinstance(point, Point)

Shrinking Examples

# Hypothesis shrinking in action

# BAD: This will shrink to something like [0, 0, 1]
@given(st.lists(st.integers()))
def test_no_duplicates_bad(xs):
    assert len(xs) == len(set(xs))  # Fails for [0, 0]

# Shrunk output: Falsifying example: test_no_duplicates_bad(xs=[0, 0])
# Note: Hypothesis found the MINIMAL failing case automatically

# The shrinking process:
# 1. Initial failure: [42, -17, 0, 999, 42, 3]
# 2. Try smaller list: [42, -17, 0, 999, 42] - still fails? no (no dup)
# 3. Try: [42, -17, 42] - fails? yes (has dup)
# 4. Try: [42, 42] - fails? yes
# 5. Try: [0, 0] - fails? yes (simpler values)
# 6. Try: [0] - fails? no
# 7. Minimal: [0, 0]

# Custom shrinking with map
@given(st.integers().map(lambda x: x * 2))
def test_even_numbers(n):
    assert n % 2 == 0  # Always passes, but shrinks to 0

# Filter affects shrinking
@given(st.integers().filter(lambda x: x > 10))
def test_large_numbers(n):
    assert n < 100  # Shrinks to 11 (smallest that passes filter)

Integration with Pytest

import pytest
from hypothesis import given, settings
from hypothesis import strategies as st

# Combine with fixtures
@pytest.fixture
def database():
    db = Database()
    yield db
    db.close()

@given(key=st.text(), value=st.binary())
def test_database_roundtrip(database, key, value):
    database.put(key, value)
    assert database.get(key) == value

# Parametrize + hypothesis
@pytest.mark.parametrize("operation", ["add", "subtract", "multiply"])
@given(a=st.integers(), b=st.integers())
def test_operations(operation, a, b):
    result = calculate(operation, a, b)
    # Verify properties based on operation
    if operation == "add":
        assert result == a + b

# Mark slow tests
@pytest.mark.slow
@settings(max_examples=10000)
@given(st.binary(min_size=10000))
def test_large_data(data):
    process(data)

# Skip in certain conditions
@pytest.mark.skipif(condition, reason="...")
@given(st.integers())
def test_conditional(n):
    pass

Reproducing Failures

from hypothesis import given, reproduce_failure, settings
from hypothesis import strategies as st

# Hypothesis prints reproduction code on failure:
#
# Falsifying example: test_example(x=[0, 0])
#
# You can add @reproduce_failure(...) to force this example:
# @reproduce_failure('6.100.0', b'AAAB')

# Force a specific failing example for debugging
@reproduce_failure('6.100.0', b'AAAB')  # Version and blob
@given(st.lists(st.integers()))
def test_reproduction(xs):
    assert len(xs) == len(set(xs))

# Example database location
# .hypothesis/examples/<test_function_name>
#
# Commit this to version control!
# Every CI run will replay all known failures first

# Explicit seed for determinism
@settings(database=None)  # Disable database
@given(st.integers())
def test_with_seed(n):
    assert n != 42

# Run with: pytest --hypothesis-seed=12345

Testing APIs

from hypothesis import given, assume
from hypothesis import strategies as st
import requests

# Generate valid HTTP requests
@st.composite
def http_request(draw):
    method = draw(st.sampled_from(['GET', 'POST', 'PUT', 'DELETE']))
    path = '/' + draw(st.text(
        alphabet='abcdefghijklmnopqrstuvwxyz/',
        min_size=1,
        max_size=50
    ))

    if method in ('POST', 'PUT'):
        body = draw(st.dictionaries(
            st.text(min_size=1),
            st.text() | st.integers() | st.booleans()
        ))
    else:
        body = None

    return {'method': method, 'path': path, 'body': body}

@given(http_request())
def test_api_doesnt_crash(request):
    """Property: API should never crash (return 5xx)."""
    response = make_request(
        request['method'],
        request['path'],
        json=request['body']
    )

    # 4xx is fine (client error), 5xx is not
    assert response.status_code < 500

# Schemathesis-style: generate from OpenAPI spec
@given(st.from_schema(openapi_schema))
def test_schema_conformance(request):
    response = client.request(**request)
    validate_response(response, openapi_schema)

Mental Model

MacIver approaches testing by asking:

  1. What properties should hold? Think invariants and roundtrips
  2. What's the simplest failure? Trust Hypothesis shrinking
  3. Am I saving failures? Commit the example database
  4. Can I compose strategies? Build complex from simple
  5. Is it stateful? Use RuleBasedStateMachine

The Hypothesis Checklist

□ Use @given with appropriate strategies
□ Add @example for known edge cases
□ Use assume() for preconditions
□ Commit .hypothesis/ directory
□ Set appropriate max_examples (100+)
□ Configure CI profile with more examples
□ Use composite strategies for complex types
□ Use stateful testing for APIs
□ Trust the shrinking—don't manually minimize
□ Check deadline settings for slow tests

Signature MacIver Moves

  • Integrated shrinking (choice sequence reduction)
  • Example database (never forget a failure)
  • Composite strategies (@st.composite)
  • Stateful testing (RuleBasedStateMachine)
  • Settings profiles (CI vs dev)
  • Type-based inference (st.from_type)
  • Recursive strategies (st.recursive)
  • Health checks for performance issues

平台分布

Codex

35.7%
按下载量换算25

Claude

28.34%
按下载量换算20

Cursor

18.29%
按下载量换算13

Gemini CLI

9.38%
按下载量换算7

安全审计

Gen Agent Trust Hub

未通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在提醒或未通过项,安装前请自行复核。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills