propagate
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePropagation
测试生成(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:
- An Allium spec — the file describing the system's behaviour
.allium - A target codebase — the implementation to test
- Test obligations — from (JSON listing every required test)
allium plan <spec> - Domain model — from (JSON describing entity shapes, constraints, state machines)
allium model <spec>
If the CLI tools are not available, derive test obligations manually from the spec using the test-generation taxonomy in .
references/test-generation.md在生成测试前,您需要准备:
- Allium规范 —— 描述系统行为的文件
.allium - 目标代码库 —— 待测试的实现代码
- 测试义务 —— 来自(列出所有必填测试的JSON文件)
allium plan <spec> - 领域模型 —— 来自(描述实体形态、约束、状态机的JSON文件)
allium model <spec>
如果CLI工具不可用,可参考中的测试生成分类法,手动从规范推导测试义务。
references/test-generation.mdModes
生成模式
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:
- Exposure tests — verify each item in is accessible to the specified actor, including
exposesiteration over collectionsfor - Provides tests — verify operations appear when their conditions are true and are hidden otherwise, including when the corresponding rule's
whenclauses are not metrequires - Actor restriction tests — verify the surface is not accessible to other actor types
- Actor identification tests — verify only entities matching the actor's predicate can interact; for actors with
identified_by, verify interaction is scoped to the declared contextwithin - Context scoping tests — verify the surface instance is absent when no entity matches the predicate
context - Contract obligation tests — verify are satisfied by the counterpart,
demandsare supplied by this surface, including all typed signaturesfulfils - Guarantee tests — verify annotations hold across the boundary
@guarantee - Timeout tests — verify referenced temporal rules fire within the surface's context
- Related navigation tests — verify navigation to related surfaces resolves to the correct context entity
从边界声明生成边界测试。适用于用户需要测试API、UI契约或集成边界的场景。
针对规范中的每个边界:
- 暴露测试 —— 验证中的每个项对指定角色是否可访问,包括对集合的
exposes遍历for - 提供测试 —— 验证操作在条件为真时显示,否则隐藏,包括对应的规则
when子句未满足时的情况requires - 角色限制测试 —— 验证其他角色类型无法访问该边界
- 角色识别测试 —— 验证只有符合角色谓词的实体可交互;对于带有
identified_by的角色,验证交互范围限定在声明的上下文内within - 上下文范围测试 —— 验证当没有实体匹配谓词时,边界实例不存在
context - 契约义务测试 —— 验证对方满足要求,当前边界提供
demands内容,包括所有类型签名fulfils - 保证测试 —— 验证注解在边界范围内始终有效
@guarantee - 超时测试 —— 验证引用的时间规则在边界上下文内按时触发
- 关联导航测试 —— 验证跳转到关联边界时能解析到正确的上下文实体
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,
?-clause state-dependent presence, relationships, join lookups, equalitywhen - Enum tests — comparability across named enums, membership tests, inline enum isolation
- Sum type tests — variant fields, type guards, exhaustiveness, creation via variant name, base trigger narrowing
.created - Derived value and projection tests — computation, filtering, extraction, parameterised derived values,
-> fieldvolatility, collection operationsnow - 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 guards read resulting state), entity creation, removal, bulk updates, rule-level
ifiteration,forbindings, chained triggerslet - State transition tests — valid/invalid transitions, terminal states, vs
transitions_tosemanticsbecomes - Temporal tests — deadline boundaries, re-firing prevention, optional field null behaviour
- Surface tests — exposure, availability, actor identification with scoping, context scoping, related navigation
within - Contract tests — signature satisfaction, honouring,
@invariant/demandsdirectionfulfils - 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 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 valuewheninference via input intersectionwhen - 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:
| Language | Framework | Discovery |
|---|---|---|
| TypeScript | fast-check | |
| Python | Hypothesis | |
| Rust | proptest | |
| Go | rapid | |
| Elixir | StreamData | |
Fall back to assertion-based tests if no PBT framework is present.
针对不变量和规则属性。每个带表达式的不变量都会成为PBT属性:
- 使用生成器规范生成有效的实体状态
- 应用一系列规则(已声明转换图时遵循图,否则从规则推导有效序列)
- 检查不变量在每一步都成立
使用项目的PBT框架:
| 语言 | 框架 | 发现方式 |
|---|---|---|
| TypeScript | fast-check | |
| Python | Hypothesis | |
| Rust | proptest | |
| Go | rapid | |
| Elixir | StreamData | |
如果没有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 clauses
when - 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:
- For each edge in the transition graph, find the witnessing rule in the spec
- Find the code implementing that rule (the implementation bridge)
- Write a test action that sets up the preconditions (clauses), invokes the code, and returns the entity in the target state
requires - Register the action under the key
(from_state, to_state)
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 - 验证每个状态下不变量都成立
状态机测试需要动作映射:每个转换边对应一个函数,接收源状态的实体,通过调用实际实现代码将其转换为目标状态的实体。没有此映射的话,测试框架只能描述图中的有效路径,但无法执行。
构建动作映射的步骤:
- 针对转换图中的每条边,在规范中找到对应的见证规则
- 找到实现该规则的代码(实现桥接)
- 编写测试动作:设置前置条件(子句)、调用代码、返回目标状态的实体
requires - 在键下注册该动作
(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:
- Find the code implementing the rule (service method, event handler, state machine transition)
- Determine how to instantiate the entities involved (factories, builders, fixtures)
- Determine how to invoke the rule (API call, method call, event dispatch)
- Determine how to assert postconditions (database queries, return values, event assertions)
针对规范中的每个规则:
- 找到实现该规则的代码(服务方法、事件处理器、状态机转换)
- 确定如何实例化涉及的实体(工厂、构建器、测试夹具)
- 确定如何调用规则(API调用、方法调用、事件分发)
- 确定如何断言后置条件(数据库查询、返回值、事件断言)
For temporal tests
时间测试的映射
Temporal triggers (deadline-based rules) need a controllable time source in the test. If the implementation uses wall-clock time (, ), the test cannot reliably position itself before, at or after a deadline.
Instant.now()System.currentTimeMillis()Before attempting temporal tests, check whether the component accepts an injected clock or time parameter. Common patterns: a parameter on the constructor, an epoch-millisecond argument on the method, a 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.
ClockTimeProvider时间触发器(基于截止期限的规则)在测试中需要可控的时间源。如果实现使用系统时钟时间(、),测试无法可靠地定位到截止期限之前、之时或之后的状态。
Instant.now()System.currentTimeMillis()在尝试生成时间测试前,检查组件是否接受注入的时钟或时间参数。常见模式:构造函数的参数、方法的毫秒级时间戳参数、接口。如果存在这样的接口,注入可控时间源;如果不存在,标记为测试基础设施缺口:在组件支持时间注入前,无法生成时间测试。不要通过休眠或与系统时钟竞速来测试时间行为。
ClockTimeProviderFor cross-module trigger chains
跨模块触发链的映射
When a rule emits a trigger that another spec's rule receives (e.g. the Arbiter emits , the Clerk handles it), testing the chain requires multiple components wired together.
ClerkReceivesEventBefore generating cross-module tests:
- Trace the trigger emission graph from the plan output: which rules emit triggers, and which rules in other specs receive them
- 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)
- If a fixture exists, reuse it. Cross-module tests should compose existing wiring, not rebuild it
- 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发出,Clerk处理该事件),测试此链需要将多个组件连接在一起。
ClerkReceivesEvent生成跨模块测试前:
- 从计划输出中追踪触发器发射图:哪些规则发射触发器,哪些其他规范的规则接收它们
- 检查代码库是否有现有的集成测试夹具可连接参与的组件(管道测试、端到端测试助手、测试工具类)
- 如果存在夹具,复用它。跨模块测试应组合现有连接,而非重新构建
- 如果没有夹具,仅生成测试骨架,用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 obligations and the end-to-end scenario.
rule_successWhen 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
流程
- Read the spec — understand entities, rules, surfaces, invariants, transition graphs, state-dependent fields, contracts, config, defaults
- Read test obligations — from output or manual derivation
allium plan - Read domain model — from output or manual derivation
allium model - Explore the codebase — find existing tests, test framework, entity implementations, rule implementations
- Map constructs to code — correlate spec entities/rules/surfaces with implementation classes/functions/endpoints
- Generate tests — produce test files following the project's conventions
- Verify tests compile/run — ensure generated tests are syntactically valid
- 阅读规范 —— 理解实体、规则、边界、不变量、转换图、状态依赖字段、契约、配置、默认值
- 阅读测试义务 —— 来自输出或手动推导
allium plan - 阅读领域模型 —— 来自输出或手动推导
allium model - 探索代码库 —— 找到现有测试、测试框架、实体实现、规则实现
- 将结构映射到代码 —— 将规范的实体/规则/边界与实现类/函数/端点关联
- 生成测试 —— 按照项目约定生成测试文件
- 验证测试可编译/运行 —— 确保生成的测试语法有效
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__/, etc.)tests/ - 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 clauses (e.g. a
whenOrder hasshippedandtracking_numberpopulated; ashipped_atOrder does not)pending - For invariants, generate states that exercise boundary conditions
- For config parameters, use declared defaults unless testing overrides
当生成器规范可用时,使用它们生成有效的测试数据:
- 遵守字段类型和约束
- 对于带有转换图的实体,生成处于特定生命周期状态的实体,并根据子句确保字段存在性正确(例如
when状态的Order需填充shipped和tracking_number;shipped_at状态的Order则不需要)pending - 对于不变量,生成能覆盖边界条件的状态
- 对于配置参数,使用声明的默认值,除非测试覆盖场景
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介导,复杂或特殊的代码库可能需要手动指导映射关系
- 暂不支持跨模块测试生成,每个规范独立生成测试
- 运行时跟踪验证和模型检查属于单独的工作流