我正在使用 Cucumber 7.18 和 Java 21。我的测试工程师非常乐意编写测试场景。我回来了,我希望错误消息尽可能可读。
当错误消息发生在
DataTable
转换中时,我无法显示错误消息。
例如,假设测试包含下表。第 3 行的第
CODE
列有错误,因为它应该始终是整数:
Given My system produces the following entries:
| NAME | ORC | CODE | EPT | EFL | TIME |
| AFR89YB | A | 4455 | DEP | 100 | -00:10 |
| AFR89YC | B | 4455 | DEP | 100 | -00:10 |
| AFR89YD | C | Illegal value | DEP | 100 | -00:10 |
| ... | ... | ... | ... | ... | ... |
为了解码表格,我注册了一个
@DataTableType
:
@DataTableType
public MySystemEntry mySystemEntry(Map<String, String> entry) {
return MySystemEntry.builder()
.entry(entry)
.build();
}
而且,在构建器中,我有很多验证规则,就像这样:
public class MySystemEntry {
...
public static Builder builder() {
return new Builder();
}
...
public static Builder {
...
public Builder entry(Map<String, String> entry) {
...
...
String value = entry.get("CODE");
if (notANumber(value)) {
throw new IllegalArgumentException("Value " + value + " is illegal for Column 'CODE'.");
}
...
}
...
}
}
当价值观正确时,一切都好。当值不正确时,我可以通过在
throw new IllegalArgumentException
中设置断点来看到我的特殊异常启动。在调用堆栈的较高位置,它变成了 InvocationTargetException
,仍然保留原因。往上看,它变成了 CucumberInvocationTargetException
,但原因被放置在一个特殊的 invocationTargetException
属性中。最后,它变成了 CucumberDataTableException
,并且特殊属性 invocationTargetException
被忽略(因此丢失)。
正如预期的那样,测试失败了。我的问题是错误日志非常无用,因为它没有显示专门为我制作的详细错误消息:
Step failed
io.cucumber.datatable.CucumberDataTableException: 'java.util.List<com.my-application.MySystemEntry>' could not transform
| NAME | ORC | CODE | EPT | EFL | TIME |
| AFR89YB | A | 4455 | DEP | 100 | -00:10 |
| AFR89YC | B | 4455 | DEP | 100 | -00:10 |
| AFR89YD | C | Illegal value | DEP | 100 | -00:10 |
| ... | ... | ... | ... | ... | ... |
at io.cucumber.datatable.DataTableType.transform(DataTableType.java:158)
...
...
at ✽.Given My system produces the following entries: (file:///D:/dev/java/my-application/src/test/resources/features/my-system-works.feature:26)
Caused by: io.cucumber.core.backend.CucumberInvocationTargetException
at io.cucumber.java.Invoker.doInvoke(Invoker.java:73)
...
...
对我来说,这有点烦人 - 如果我看不到问题,我会设置一个断点并准确找出问题所在。但我的测试工程师完全被错误消息迷惑了。他必须检查每一列和每一行中的每个值,直到找到不匹配的地方。
在
Cucumber中解码
DataTable
时报告自定义异常的正确方法是什么?
编辑
根据@m-p-korstanje的建议,我分叉了
cucumber-java-skeleton
并在这里做了一个工作示例:
maven/src/test/java/io/cucumber/skeleton/StepDefinitions.java
:在那里你会看到一个用 @DataTableType
注释的方法,它只会抛出异常。maven
文件夹maven clean test
如果你让 Cucumber 通过在步骤定义方法中声明你想要的类型来为你完成转换,你将获得一个很好的堆栈跟踪。
@When("I mix the following ingredients")
public void i_wait_hour(List<Ingredient> ingredients) {
// use ingredients here
}