考虑以下黄瓜情景: -
Scenario: Test payment
Given I login to terminal
When POS token is generated asynchronously
Then user generates mobile token
And payment is successful
“异步生成POS令牌”步骤需要异步执行,不应阻止后续步骤的执行。我能够用Java中的FutureTask完成它。但是如果出现故障,我无法断言失败。以下是代码段
@When("^POS token is generated asynchronously$")
public void gs_Consumer() throws Throwable {
HashMap<String, Object> m = DataContainer.getDataMap();
ExecutorService executor = Executors.newFixedThreadPool(2);
FutureTask<Object> futureTask1 = null;
futureTask1 = new FutureTask<Object>(new Callable<Object>() {
public Object call() throws Exception {
DataContainer.setDataMap(m);
try {
retrieve_consumer_information();
} catch (Throwable e) {
DataContainer.getDataMap().put("exception", e);
throw new Exception(e);
}
return null;
}
});
executor.execute(futureTask1);
DataContainer.getDataMap().put("response", futureTask1);
// Shutdown the ExecutorService
executor.shutdown();
}
然后我在After方法中得到响应,因为我不能在此方法中执行futureTask1.get(),因为它将阻止执行执行其他下游步骤。
public void afterAsynchMethod() {
try {
((FutureTask<Object>) DataContainer.getDataMap().get("response")).get();
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
Assert.fail(e.getMessage());
}
}
现在,如果After方法中发生异常,则方案仍未反映为失败方案。在这种情况下,或者以其他方式执行此操作时,如何使方案失败?
答案 0 :(得分:2)
这个场景中有很多细节。我会考虑在堆栈中向下推送细节。在步骤将要使用的辅助类中尽可能多地隐藏。
可能是
Scenario: Thomas pays for a yearly support subscription
Given Thomas has payed 150 EUR with his credit card
When the payment is confirmed
Then he should get a receipt
更多地谈论预期的行为而不是实施。托马斯并不关心服务是否异步。
但那么实施呢?实现应该关心问题的异步性质。但不是情景。该场景应该只描述所需的行为。
对我来说,这听起来像是在连接外部服务。该程序无法控制的服务。可能是一个网络电话。
我会创建一个存根,作为给定调用的真实服务响应。存根将立即响应,并且永远不会有破坏的网络阻止它。这将消除在此处理异步行为的需要。
然后,我将实现一个集成测试,该调试使用与调用存根相同的参数调用实际服务。并且期望来自外部服务的原因相同,因为存根被硬编码以响应。这不是面向测试的业务,因此我不会使用Gherkin描述。我可能会使用JUnit或类似的测试框架来实现它。这可能需要更多工作,但它会提供更可靠的测试设置。您可以使用Gherkin中描述的场景作为开发和业务利益相关者之间的沟通工具。如果付款是异步的,利益相关者可能并不关心。他们关心托马斯可以付款并获得收据这一事实。