propagate

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Propagation

测试生成(Propagation)

This skill generates tests from Allium specifications. Propagation is how plants reproduce from cuttings of the parent: the spec is the parent, the tests are the offspring.
Deterministic tools guarantee completeness (every spec construct maps to a test obligation). You handle the implementation bridge: correlating spec constructs with code, generating tests in the project's conventions.
此技能可从Allium规范生成测试。Propagation(传播)一词类比植物通过母株扦插繁殖的过程:规范是母本,测试是后代。
确定性工具可保证测试完整性(每个规范结构都对应一项测试义务)。您需要负责实现桥接:将规范结构与代码关联,按照项目约定生成测试。

Prerequisites

前置条件

Before propagating tests, you need:
  1. An Allium spec — the
    .allium
    file describing the system's behaviour
  2. A target codebase — the implementation to test
  3. Test obligations — from
    allium plan <spec>
    (JSON listing every required test)
  4. Domain model — from
    allium model <spec>
    (JSON describing entity shapes, constraints, state machines)
If the CLI tools are not available, derive test obligations manually from the spec using the test-generation taxonomy in
references/test-generation.md
.
在生成测试前,您需要准备:
  1. Allium规范 —— 描述系统行为的
    .allium
    文件
  2. 目标代码库 —— 待测试的实现代码
  3. 测试义务 —— 来自
    allium plan <spec>
    (列出所有必填测试的JSON文件)
  4. 领域模型 —— 来自
    allium model <spec>
    (描述实体形态、约束、状态机的JSON文件)
如果CLI工具不可用,可参考
references/test-generation.md
中的测试生成分类法,手动从规范推导测试义务。

Modes

生成模式

Surface mode

边界模式

Generates boundary tests from surface declarations. Use when the user wants to test an API, UI contract or integration boundary.
For each surface in the spec:
  1. Exposure tests — verify each item in
    exposes
    is accessible to the specified actor, including
    for
    iteration over collections
  2. Provides tests — verify operations appear when their
    when
    conditions are true and are hidden otherwise, including when the corresponding rule's
    requires
    clauses are not met
  3. Actor restriction tests — verify the surface is not accessible to other actor types
  4. Actor identification tests — verify only entities matching the actor's
    identified_by
    predicate can interact; for actors with
    within
    , verify interaction is scoped to the declared context
  5. Context scoping tests — verify the surface instance is absent when no entity matches the
    context
    predicate
  6. Contract obligation tests — verify
    demands
    are satisfied by the counterpart,
    fulfils
    are supplied by this surface, including all typed signatures
  7. Guarantee tests — verify
    @guarantee
    annotations hold across the boundary
  8. Timeout tests — verify referenced temporal rules fire within the surface's context
  9. Related navigation tests — verify navigation to related surfaces resolves to the correct context entity
从边界声明生成边界测试。适用于用户需要测试API、UI契约或集成边界的场景。
针对规范中的每个边界:
  1. 暴露测试 —— 验证
    exposes
    中的每个项对指定角色是否可访问,包括对集合的
    for
    遍历
  2. 提供测试 —— 验证操作在
    when
    条件为真时显示,否则隐藏,包括对应的规则
    requires
    子句未满足时的情况
  3. 角色限制测试 —— 验证其他角色类型无法访问该边界
  4. 角色识别测试 —— 验证只有符合角色
    identified_by
    谓词的实体可交互;对于带有
    within
    的角色,验证交互范围限定在声明的上下文内
  5. 上下文范围测试 —— 验证当没有实体匹配
    context
    谓词时,边界实例不存在
  6. 契约义务测试 —— 验证对方满足
    demands
    要求,当前边界提供
    fulfils
    内容,包括所有类型签名
  7. 保证测试 —— 验证
    @guarantee
    注解在边界范围内始终有效
  8. 超时测试 —— 验证引用的时间规则在边界上下文内按时触发
  9. 关联导航测试 —— 验证跳转到关联边界时能解析到正确的上下文实体

Spec mode

全规范模式

Walks the full test obligations document. Use when the user wants comprehensive test coverage for the entire specification.
Categories from the test-generation taxonomy:
  • Entity and value type tests — fields, types, optional (
    ?
    ) null handling,
    when
    -clause state-dependent presence, relationships, join lookups, equality
  • Enum tests — comparability across named enums, membership tests, inline enum isolation
  • Sum type tests — variant fields, type guards, exhaustiveness, creation via variant name, base
    .created
    trigger narrowing
  • Derived value and projection tests — computation, filtering,
    -> field
    extraction, parameterised derived values,
    now
    volatility, collection operations
  • Default instance tests — unconditional existence, field values, cross-references between defaults
  • Config tests — defaults, overrides, mandatory parameters, expression-form defaults, qualified references, config chains
  • Invariant tests — post-rule verification, edge cases, implication logic, entity-level invariants
  • Rule tests — success/failure/edge cases, conditionals (ensuring
    if
    guards read resulting state), entity creation, removal, bulk updates, rule-level
    for
    iteration,
    let
    bindings, chained triggers
  • State transition tests — valid/invalid transitions, terminal states,
    transitions_to
    vs
    becomes
    semantics
  • Temporal tests — deadline boundaries, re-firing prevention, optional field null behaviour
  • Surface tests — exposure, availability, actor identification with
    within
    scoping, context scoping, related navigation
  • Contract tests — signature satisfaction,
    @invariant
    honouring,
    demands
    /
    fulfils
    direction
  • Cross-module tests — qualified entity references, external trigger responses, type placeholder substitution
  • Cross-rule interaction tests — duplicate creation guards, provides availability
  • Transition graph tests — every declared edge is reachable via its witnessing rule, undeclared transitions are rejected, terminal states have no outbound rules, non-terminal states have at least one exit, exact correspondence between enum values and graph edges
  • State-dependent field tests — presence when in qualifying state, absence when outside, presence obligations on entering the
    when
    set, absence obligations on leaving, no obligation when moving within or outside, convergent transitions all set the field, guard required to access
    when
    -qualified fields, derived value
    when
    inference via input intersection
  • Scenario tests — happy path, edge cases, order independence
遍历完整的测试义务文档。适用于用户需要为整个规范生成全面测试覆盖的场景。
测试生成分类法中的类别:
  • 实体与值类型测试 —— 字段、类型、可选(
    ?
    )空值处理、
    when
    子句的状态依赖存在性、关联关系、关联查询、相等性
  • 枚举测试 —— 命名枚举的可比性、成员测试、内联枚举隔离
  • 求和类型测试 —— 变体字段、类型守卫、穷尽性、通过变体名称创建、基础
    .created
    触发窄化
  • 派生值与投影测试 —— 计算、过滤、
    -> field
    提取、参数化派生值、
    now
    易变性、集合操作
  • 默认实例测试 —— 无条件存在性、字段值、默认值之间的交叉引用
  • 配置测试 —— 默认值、覆盖值、必填参数、表达式形式的默认值、限定引用、配置链
  • 不变量测试 —— 规则后验证、边缘情况、隐含逻辑、实体级不变量
  • 规则测试 —— 成功/失败/边缘情况、条件判断(确保
    if
    守卫读取结果状态)、实体创建、删除、批量更新、规则级
    for
    遍历、
    let
    绑定、链式触发
  • 状态转换测试 —— 有效/无效转换、终端状态、
    transitions_to
    becomes
    语义差异
  • 时间测试 —— 截止期限边界、重复触发预防、可选字段空值行为
  • 边界测试 —— 暴露性、可用性、带
    within
    范围的角色识别、上下文范围、关联导航
  • 契约测试 —— 签名满足性、
    @invariant
    遵守情况、
    demands
    /
    fulfils
    方向
  • 跨模块测试 —— 限定实体引用、外部触发响应、类型占位符替换
  • 跨规则交互测试 —— 重复创建守卫、提供可用性
  • 转换图测试 —— 每个声明的边都可通过其见证规则到达、未声明的转换被拒绝、终端状态没有出站规则、非终端状态至少有一个出口、枚举值与图边完全对应
  • 状态依赖字段测试 —— 在符合条件的状态下存在、不符合时不存在、进入
    when
    集合时的存在义务、离开时的不存在义务、在集合内/外移动时无义务、收敛转换都设置字段、访问
    when
    限定字段需要守卫、通过输入交集推导派生值的
    when
    条件
  • 场景测试 —— 快乐路径、边缘情况、顺序无关性

Test output kinds

测试输出类型

1. Assertion-based tests

1. 基于断言的测试

For deterministic obligations: field presence, enum membership, transition validity, surface exposure, state-dependent field presence and absence. These are standard unit/integration tests.
针对确定性义务:字段存在性、枚举成员资格、转换有效性、边界暴露性、状态依赖字段的存在与缺失。这些是标准的单元/集成测试。

2. Property-based tests

2. 基于属性的测试(PBT)

For invariants and rule properties. Each expression-bearing invariant becomes a PBT property:
  • Generate a valid entity state using the generator spec
  • Apply a sequence of rules (following the transition graph when declared, or deriving valid sequences from rules alone)
  • Check the invariant holds at every step
Use the project's PBT framework:
LanguageFrameworkDiscovery
TypeScriptfast-check
package.json
PythonHypothesis
pyproject.toml
Rustproptest
Cargo.toml
Gorapid
go.mod
ElixirStreamData
mix.exs
Fall back to assertion-based tests if no PBT framework is present.
针对不变量和规则属性。每个带表达式的不变量都会成为PBT属性:
  • 使用生成器规范生成有效的实体状态
  • 应用一系列规则(已声明转换图时遵循图,否则从规则推导有效序列)
  • 检查不变量在每一步都成立
使用项目的PBT框架:
语言框架发现方式
TypeScriptfast-check
package.json
PythonHypothesis
pyproject.toml
Rustproptest
Cargo.toml
Gorapid
go.mod
ElixirStreamData
mix.exs
如果没有PBT框架,则退回到基于断言的测试。

3. State machine tests

3. 状态机测试

For entities with status enums. When a transition graph is declared, walk every path through the graph. When no graph is declared, derive valid transitions from rules.
  • Verify transitions succeed via witnessing rules
  • Verify rejected transitions fail
  • Verify state-dependent fields are present or absent at each state per their
    when
    clauses
  • Verify invariants hold at each state
State machine tests require an action map: a function per transition edge that takes the entity in the source state and produces it in the target state by calling the actual implementation code. Without this map, the test framework can describe valid paths through the graph but cannot execute them.
To build the action map:
  1. For each edge in the transition graph, find the witnessing rule in the spec
  2. Find the code implementing that rule (the implementation bridge)
  3. Write a test action that sets up the preconditions (
    requires
    clauses), invokes the code, and returns the entity in the target state
  4. Register the action under the
    (from_state, to_state)
    key
Once the map is built, the PBT framework can walk random valid paths: start at any non-terminal state, pick a random outbound edge, apply its action, check all entity-level invariants, repeat. The path length and starting state are generated randomly. This is the fullest expression of the spec's transition graph as a test.
针对带有状态枚举的实体。当声明转换图时,遍历图中的所有路径;未声明转换图时,从规则推导有效转换。
  • 验证转换通过见证规则成功执行
  • 验证被拒绝的转换执行失败
  • 验证每个状态下状态依赖字段是否符合其
    when
    子句的存在/缺失要求
  • 验证每个状态下不变量都成立
状态机测试需要动作映射:每个转换边对应一个函数,接收源状态的实体,通过调用实际实现代码将其转换为目标状态的实体。没有此映射的话,测试框架只能描述图中的有效路径,但无法执行。
构建动作映射的步骤:
  1. 针对转换图中的每条边,在规范中找到对应的见证规则
  2. 找到实现该规则的代码(实现桥接)
  3. 编写测试动作:设置前置条件(
    requires
    子句)、调用代码、返回目标状态的实体
  4. (from_state, to_state)
    键下注册该动作
映射构建完成后,PBT框架可随机遍历有效路径:从任意非终端状态开始,随机选择出站边,应用其动作,检查所有实体级不变量,重复此过程。路径长度和起始状态随机生成。这是将规范转换图转化为测试的最完整方式。

The implementation bridge

实现桥接

You correlate spec constructs with implementation code, the same way the weed skill correlates for divergence checking.
您需要将规范结构与实现代码关联,就像weed技能用于差异检查时的关联方式一样。

For surface tests

边界测试的映射

Map surfaces to their implementation:
  • API surfaces map to endpoints (REST routes, GraphQL resolvers, gRPC services)
  • UI surfaces map to components or pages
  • Integration surfaces map to message handlers or SDK methods
Discover the mapping by reading the codebase. Look for naming patterns, route definitions and handler registrations.
将边界映射到其实现:
  • API边界映射到端点(REST路由、GraphQL解析器、gRPC服务)
  • UI边界映射到组件或页面
  • 集成边界映射到消息处理器或SDK方法
通过阅读代码库发现映射关系,寻找命名模式、路由定义和处理器注册信息。

For internal tests

内部测试的映射

For each rule in the spec:
  1. Find the code implementing the rule (service method, event handler, state machine transition)
  2. Determine how to instantiate the entities involved (factories, builders, fixtures)
  3. Determine how to invoke the rule (API call, method call, event dispatch)
  4. Determine how to assert postconditions (database queries, return values, event assertions)
针对规范中的每个规则:
  1. 找到实现该规则的代码(服务方法、事件处理器、状态机转换)
  2. 确定如何实例化涉及的实体(工厂、构建器、测试夹具)
  3. 确定如何调用规则(API调用、方法调用、事件分发)
  4. 确定如何断言后置条件(数据库查询、返回值、事件断言)

For temporal tests

时间测试的映射

Temporal triggers (deadline-based rules) need a controllable time source in the test. If the implementation uses wall-clock time (
Instant.now()
,
System.currentTimeMillis()
), the test cannot reliably position itself before, at or after a deadline.
Before attempting temporal tests, check whether the component accepts an injected clock or time parameter. Common patterns: a
Clock
parameter on the constructor, an epoch-millisecond argument on the method, a
TimeProvider
interface. If the seam exists, inject a controllable time source. If it does not, flag this as a test infrastructure gap: the temporal tests cannot be generated until the component supports time injection. Do not attempt to test temporal behaviour by sleeping or racing against wall-clock time.
时间触发器(基于截止期限的规则)在测试中需要可控的时间源。如果实现使用系统时钟时间(
Instant.now()
System.currentTimeMillis()
),测试无法可靠地定位到截止期限之前、之时或之后的状态。
在尝试生成时间测试前,检查组件是否接受注入的时钟或时间参数。常见模式:构造函数的
Clock
参数、方法的毫秒级时间戳参数、
TimeProvider
接口。如果存在这样的接口,注入可控时间源;如果不存在,标记为测试基础设施缺口:在组件支持时间注入前,无法生成时间测试。不要通过休眠或与系统时钟竞速来测试时间行为。

For cross-module trigger chains

跨模块触发链的映射

When a rule emits a trigger that another spec's rule receives (e.g. the Arbiter emits
ClerkReceivesEvent
, the Clerk handles it), testing the chain requires multiple components wired together.
Before generating cross-module tests:
  1. Trace the trigger emission graph from the plan output: which rules emit triggers, and which rules in other specs receive them
  2. Check whether the codebase has an existing integration test fixture that wires the participating components (a pipeline test, an end-to-end test helper, a test harness class)
  3. If a fixture exists, reuse it. Cross-module tests should compose existing wiring, not rebuild it
  4. If no fixture exists, generate only the test skeleton with TODOs marking where component wiring is needed
Cross-module tests are integration tests by nature. They verify that the spec's trigger chains are faithfully implemented across component boundaries, but the setup cost is high. Prioritise them after single-component tests are passing.
当一个规则发出的触发器被另一个规范的规则接收时(例如Arbiter发出
ClerkReceivesEvent
,Clerk处理该事件),测试此链需要将多个组件连接在一起。
生成跨模块测试前:
  1. 从计划输出中追踪触发器发射图:哪些规则发射触发器,哪些其他规范的规则接收它们
  2. 检查代码库是否有现有的集成测试夹具可连接参与的组件(管道测试、端到端测试助手、测试工具类)
  3. 如果存在夹具,复用它。跨模块测试应组合现有连接,而非重新构建
  4. 如果没有夹具,仅生成测试骨架,用TODO标记需要组件连接的位置
跨模块测试本质上是集成测试,它们验证规范的触发链在组件边界间是否被忠实地实现,但设置成本较高。应在单组件测试通过后再优先处理它们。

Reusing existing tests

复用现有测试

When exploring the codebase, note which spec obligations are already covered by existing tests. An existing integration test that exercises the happy path from event submission through to acknowledged output already covers multiple
rule_success
obligations and the end-to-end scenario.
When an existing test covers a spec obligation, reference it rather than generating a duplicate. The propagate skill's value at the integration level is verifying that coverage is complete against the spec's obligation list, identifying gaps, and generating tests to fill them. Replacing working hand-written tests with generated equivalents adds no value.
探索代码库时,记录哪些规范义务已被现有测试覆盖。例如,一个从事件提交到确认输出的快乐路径集成测试,已经覆盖了多个
rule_success
义务和端到端场景。
当现有测试覆盖了某项规范义务时,引用该测试而非生成重复测试。传播技能在集成层面的价值是验证覆盖率是否符合规范的义务列表,识别缺口并生成测试填补缺口。用生成的测试替换有效的手写测试没有任何价值。

For deferred specs

延迟规范的处理

Deferred specifications are fully specified in separate files. When the target codebase doesn't include the deferred spec's module, generate a test stub with a placeholder:
typescript
// TODO: deferred spec — InterviewerMatching.suggest
// This behaviour is specified as deferred. Provide a mock or skip.
延迟规范在单独文件中完整定义。当目标代码库不包含延迟规范的模块时,生成带占位符的测试桩:
typescript
// TODO: 延迟规范 — InterviewerMatching.suggest
// 此行为被指定为延迟实现。请提供模拟实现或跳过测试。

Process

流程

  1. Read the spec — understand entities, rules, surfaces, invariants, transition graphs, state-dependent fields, contracts, config, defaults
  2. Read test obligations — from
    allium plan
    output or manual derivation
  3. Read domain model — from
    allium model
    output or manual derivation
  4. Explore the codebase — find existing tests, test framework, entity implementations, rule implementations
  5. Map constructs to code — correlate spec entities/rules/surfaces with implementation classes/functions/endpoints
  6. Generate tests — produce test files following the project's conventions
  7. Verify tests compile/run — ensure generated tests are syntactically valid
  1. 阅读规范 —— 理解实体、规则、边界、不变量、转换图、状态依赖字段、契约、配置、默认值
  2. 阅读测试义务 —— 来自
    allium plan
    输出或手动推导
  3. 阅读领域模型 —— 来自
    allium model
    输出或手动推导
  4. 探索代码库 —— 找到现有测试、测试框架、实体实现、规则实现
  5. 将结构映射到代码 —— 将规范的实体/规则/边界与实现类/函数/端点关联
  6. 生成测试 —— 按照项目约定生成测试文件
  7. 验证测试可编译/运行 —— 确保生成的测试语法有效

Discovery checklist

发现清单

Before generating tests, establish:
  • Test framework and runner (Jest, pytest, cargo test, etc.)
  • PBT framework if present (fast-check, Hypothesis, proptest, etc.)
  • Test file location conventions (co-located,
    __tests__/
    ,
    tests/
    , etc.)
  • Entity/model location and patterns (classes, interfaces, structs)
  • Factory/fixture patterns for test data
  • How state transitions are implemented (methods, events, state machines)
  • How surfaces are implemented (routes, controllers, resolvers)
  • Existing test helpers or utilities
  • Whether components accept injected time sources for temporal tests
  • Whether an integration test fixture exists for cross-module trigger chains
  • Which spec obligations are already covered by existing tests
生成测试前,需确认:
  • 测试框架和运行器(Jest、pytest、cargo test等)
  • 是否存在PBT框架(fast-check、Hypothesis、proptest等)
  • 测试文件位置约定(与代码同目录、
    __tests__/
    tests/
    等)
  • 实体/模型的位置和模式(类、接口、结构体)
  • 测试数据的工厂/夹具模式
  • 状态转换的实现方式(方法、事件、状态机)
  • 边界的实现方式(路由、控制器、解析器)
  • 现有测试助手或工具
  • 组件是否接受注入的时间源用于时间测试
  • 是否存在用于跨模块触发链的集成测试夹具
  • 哪些规范义务已被现有测试覆盖

Generator awareness

生成器感知

When generator specs are available, use them to produce valid test data:
  • Respect field types and constraints
  • For entities with transition graphs, generate entities at specific lifecycle states with correct field presence per
    when
    clauses (e.g. a
    shipped
    Order has
    tracking_number
    and
    shipped_at
    populated; a
    pending
    Order does not)
  • For invariants, generate states that exercise boundary conditions
  • For config parameters, use declared defaults unless testing overrides
当生成器规范可用时,使用它们生成有效的测试数据:
  • 遵守字段类型和约束
  • 对于带有转换图的实体,生成处于特定生命周期状态的实体,并根据
    when
    子句确保字段存在性正确(例如
    shipped
    状态的Order需填充
    tracking_number
    shipped_at
    pending
    状态的Order则不需要)
  • 对于不变量,生成能覆盖边界条件的状态
  • 对于配置参数,使用声明的默认值,除非测试覆盖场景

Interaction with other tools

与其他工具的交互

  • distill produces specs from code. Those specs feed propagate.
  • weed checks alignment. After propagating tests, weed verifies spec-code match.
  • tend evolves specs. After spec changes, run propagate again to update tests.
  • elicit builds specs through conversation. Once a spec is ready, propagate generates tests.
  • distill 从代码生成规范,这些规范可作为propagate的输入
  • weed 检查一致性,生成测试后,weed可验证规范与代码是否匹配
  • tend 演进规范,规范变更后,重新运行propagate更新测试
  • elicit 通过对话构建规范,规范就绪后,propagate生成测试

Limitations

局限性

  • Generated tests are a starting point. They may need adjustment for project-specific patterns.
  • The implementation bridge is LLM-mediated. Complex or unusual codebases may need manual guidance on the mapping.
  • Cross-module test generation is not yet supported. Each spec generates tests independently.
  • Runtime trace validation and model checking are separate workstreams.
  • 生成的测试只是起点,可能需要根据项目特定模式调整
  • 实现桥接由LLM介导,复杂或特殊的代码库可能需要手动指导映射关系
  • 暂不支持跨模块测试生成,每个规范独立生成测试
  • 运行时跟踪验证和模型检查属于单独的工作流