2016-02-02 39 views
3

考虑以下黄瓜情形: -异步步骤执行与黄瓜-JVM

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(); 
} 

然后我得到的响应的方法,因为我不能做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

当使用黄瓜创建系统集成测试时,我们有非常相似的用例,因此我们创建了一个小型库,使得测试中对异步事件的反应更容易:https://github.com/zalando/switchboard –

+0

@JörnHorstmannyour ghthub链接现在是404,你可以检查项目是否已经移到其他地方了吗? – Eddy

+0

@Eddy最初的开发者仍然在https://github.com/whiskeysierra/switchboard上的github帐户中有一个分支 - 看起来该项目对于更广泛的观众来说并不那么有趣,因此被删除以减少混乱。 –

回答

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 

这更多地谈论预期的行为,而不是执行。托马斯并不关心该服务是否是异步的。

但是那么执行呢?实施应该关心问题的异步性。但不是这种情况。该方案只应描述所需的行为。

对我来说,这听起来像你连接到外部服务。这个程序不能控制的服务。可能是网络电话。

我会创建一个作为给定调用的实际服务响应的存根。存根将立即作出回应,并且永远不会有破损的网络阻止它。这将消除在这里处理异步行为的需要。

然后,我会实现一个集成测试,该测试使用与存根调用相同的参数来调用真实服务。并且期望与外部服务非常相似的原因,因为存根被硬编码为响应。这不会是一个面向业务的测试,因此我不会使用小黄瓜来描述。我可能会使用JUnit或类似的测试框架来实现它。

这可能有点多些工作,但它会提供更可靠的测试设置。你也可以使用Gherkin中描述的场景作为开发和业务利益相关者之间的沟通工具。如果付款是异步的,利益相关者可能不在乎。他们关心托马斯可以付款并获得收据的事实。

+0

谢谢托马斯的答案!我在这里要做的是在POC上将SOAPUI测试转换为一个更灵活的框架。我选择黄瓜的原因是我们需要一种更好的方式来表示测试案例的流程,这些测试案例在Soapui中不是很清楚,甚至测试案例的可重用性似乎还有很多工作要做,更不用说新的ReadyApi软件了。一场噩梦导致了很多崩溃。 – Ani

+0

嗨,托马斯,我同意你对黄瓜文本的分析,但是如果我不想将外部服务剔除,但将其包含在验证中(我们是否使用了正确和当前的API进行通信?是否有任何改变? ) – Eddy