Skip to content

Commit c9ee4bd

Browse files
CodeCasterXclaude
andcommitted
test: 简化 NPE 复现策略 - 只重复运行原始失败测试
优化原因: - 之前运行了太多测试(1004 个),包括人工延迟的测试 - 更高效的方式:只重复运行历史上真正失败过的测试 新策略: - 只运行 shouldOkWhenAiFlowWithExampleSelector 1000 次 - 使用真实的 ExampleSelector 配置(不添加人工延迟) - 移除了模拟测试,更接近真实失败场景 预期: - 运行更快(无人工延迟) - 只运行 1003 个测试(原 3 个 + 1000 次重复) - 根据 0.5% 失败率,1000 次应该触发约 5 次 NPE 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
1 parent ade73bd commit c9ee4bd

File tree

1 file changed

+2
-58
lines changed
  • framework/fel/java/fel-flow/src/test/java/modelengine/fel/engine/operators

1 file changed

+2
-58
lines changed

framework/fel/java/fel-flow/src/test/java/modelengine/fel/engine/operators/PatternTest.java

Lines changed: 2 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ void shouldOkWhenAiFlowWithNormalRunnableParallel() {
8181
assertThat(answer1.toString()).isEqualTo("answer question1 from context with my history");
8282
}
8383

84-
@Test
85-
@DisplayName("测试 ExampleSelector")
84+
@RepeatedTest(1000)
85+
@DisplayName("测试 ExampleSelector - 重复运行以复现 NPE")
8686
void shouldOkWhenAiFlowWithExampleSelector() {
8787
Example[] examples = {new DefaultExample("2+2", "4"), new DefaultExample("2+3", "5")};
8888
Conversation<String, Prompt> converse = AiFlows.<String>create()
@@ -98,62 +98,6 @@ void shouldOkWhenAiFlowWithExampleSelector() {
9898
assertThat(converse.offer("1+2").await().text()).isEqualTo("2+2=4\n2+3=5\n1+2=");
9999
}
100100

101-
@RepeatedTest(500)
102-
@DisplayName("【复现测试】强制触发 runnableParallel 的竞态条件 NPE")
103-
void shouldReproduceNPEInRunnableParallel() {
104-
// 慢分支:模拟 fewShot() 的延迟,增大竞态窗口
105-
modelengine.fel.engine.operators.patterns.SyncTipper<String> slowBranch = arg -> {
106-
try {
107-
Thread.sleep(200); // 200ms 延迟
108-
} catch (InterruptedException e) {
109-
Thread.currentThread().interrupt();
110-
}
111-
return Tip.from("slow", "slow-value");
112-
};
113-
114-
// 快分支:模拟 question() 的快速返回
115-
modelengine.fel.engine.operators.patterns.SyncTipper<String> fastBranch = arg -> {
116-
return Tip.from("fast", "fast-value");
117-
};
118-
119-
// 执行并发聚合
120-
Conversation<String, Prompt> converse = AiFlows.<String>create()
121-
.runnableParallel(fastBranch, slowBranch)
122-
.prompt(Prompts.human("{{fast}} {{slow}}"))
123-
.close()
124-
.converse();
125-
126-
// 在修复前:这里应该偶发抛出 NullPointerException
127-
// 在修复后:这里应该稳定通过
128-
String result = converse.offer("test").await().text();
129-
130-
assertThat(result).contains("fast-value", "slow-value");
131-
}
132-
133-
@RepeatedTest(500)
134-
@DisplayName("【复现测试】使用原测试配置重复运行")
135-
void shouldReproduceOriginalTestFailure() {
136-
// 使用原始失败测试的完全相同配置
137-
Example[] examples = {new DefaultExample("2+2", "4"), new DefaultExample("2+3", "5")};
138-
139-
Conversation<String, Prompt> converse = AiFlows.<String>create()
140-
.runnableParallel(
141-
question(),
142-
fewShot(ExampleSelector.builder()
143-
.template("{{q}}={{a}}", "q", "a")
144-
.delimiter("\n")
145-
.example(examples)
146-
.build()))
147-
.prompt(Prompts.human("{{examples}}\n{{question}}="))
148-
.close()
149-
.converse();
150-
151-
// 在修复前:偶发 NPE
152-
// 在修复后:稳定通过
153-
assertThat(converse.offer("1+2").await().text())
154-
.isEqualTo("2+2=4\n2+3=5\n1+2=");
155-
}
156-
157101
@Test
158102
@DisplayName("测试 Retriever")
159103
void shouldOkWhenAiFlowWithRetriever() {

0 commit comments

Comments
 (0)