Java 什么';这是存储RESTAPI响应的最佳方法

Java 什么';这是存储RESTAPI响应的最佳方法,java,spring,rest,cucumber,e2e-testing,Java,Spring,Rest,Cucumber,E2e Testing,我将为我的RESTful API构建e2e测试,并为此使用Cucumber。 我还将使用cucumber spring在stepdef之间共享状态 让我们假设restfulapi是关于zoo的。下面是一些场景 客户使用登录/密码在动物园网站注册。我需要在该州存储客户ID。我还需要存储完整的http响应以进行注册,因为我希望能够检查,如果客户提供的密码太弱,http响应是否包含正确的http状态代码 顾客买了一张去动物园的票。出于同样的原因,我需要存储票据ID和响应 好的,到目前为止很容易。但

我将为我的RESTful API构建e2e测试,并为此使用
Cucumber
。 我还将使用
cucumber spring
在stepdef之间共享状态

让我们假设restfulapi是关于zoo的。下面是一些场景

  • 客户使用登录/密码在动物园网站注册。我需要在该州存储客户ID。我还需要存储完整的http响应以进行注册,因为我希望能够检查,如果客户提供的密码太弱,http响应是否包含正确的http状态代码
  • 顾客买了一张去动物园的票。出于同样的原因,我需要存储票据ID和响应
好的,到目前为止很容易。但如果:

  • 顾客又买了一张票。如果我使用与第一个票证相同的定义,它将重用相同的状态变量,并且第一个将不再可用。如果我创建另一个定义,我将有重复的代码,这将造成混乱

  • 另一位顾客登记并买票,所以我想确保动物园不会过于拥挤。这里的问题和上面的一样-我应该使用什么定义和什么状态变量

该框架使这成为一个单例类生命()

可以使用此机制在上下文中存储变量。然后可以在每个场景中重置上下文(或者在场景大纲中的每个
示例

在cucumber代码中,可用于编写:

Context.saveValue(targetKey, targetStringValue);
在cucumber代码中,可用于读取:

String value = Context.getValue(textOrKey) != null ? Context.getValue(textOrKey) : textOrKey;
该框架使这成为一个单例类生命()

可以使用此机制在上下文中存储变量。然后可以在每个场景中重置上下文(或者在场景大纲中的每个
示例

在cucumber代码中,可用于编写:

Context.saveValue(targetKey, targetStringValue);
在cucumber代码中,可用于读取:

String value = Context.getValue(textOrKey) != null ? Context.getValue(textOrKey) : textOrKey;

简单的解决方案是不要尝试和重复使用步骤定义太多。人们在Cucumber上犯的最大错误之一是试图通过步骤定义获得大量重用。只要步骤定义共享帮助器方法,那么有多少步骤定义就根本不重要了

下面是ruby,但我相信你可以翻译

When 'I buy a ticket' do 
  @ticket = buy_ticket
end

When 'I buy a second ticket' do
  @second_ticket = buy_ticket
end

When 'I buy a discounted ticket' do
  @discount_ticket = buy_ticket
end 

When 'I buy a family ticket' do
  @family_ticket = buy_ticket
end
现在,您的场景的其余部分可以讨论第二张票或家庭票


注意:这里没有重复,所有步骤都调用相同的方法来创建票据(您可以使用参数来处理,购买票据可能需要支持额外的复杂性)

简单的解决方案是不要尝试过多地重复使用步骤定义。人们在Cucumber上犯的最大错误之一是试图通过步骤定义获得大量重用。只要步骤定义共享帮助器方法,那么有多少步骤定义就根本不重要了

下面是ruby,但我相信你可以翻译

When 'I buy a ticket' do 
  @ticket = buy_ticket
end

When 'I buy a second ticket' do
  @second_ticket = buy_ticket
end

When 'I buy a discounted ticket' do
  @discount_ticket = buy_ticket
end 

When 'I buy a family ticket' do
  @family_ticket = buy_ticket
end
现在,您的场景的其余部分可以讨论第二张票或家庭票



注意:这里没有重复,所有步骤都调用相同的方法来创建票据(您可以使用参数来处理,购买票据可能需要支持额外的复杂性)

谢谢,但黄瓜春天也一样。问题是关于一些不同的东西-当一个请求被多次调用时,如何编写定义和存储响应。您可以在字符串的上下文实例中注册任何列表(在本示例中),我可以肯定地将任何类放入上下文中,而不仅仅是集合。您是否建议始终编写在集合中存储值的步骤定义?像
@When(“I register”){customerRegistrationResponses.add(response);}
?米哈伊尔科皮洛夫(MikhailKopylov),是的,汉克斯,但黄瓜之春(cucumber spring)实际上也是如此。问题是关于一些不同的东西-当一个请求被多次调用时,如何编写定义和存储响应。您可以在字符串的上下文实例中注册任何列表(在本示例中),我可以肯定地将任何类放入上下文中,而不仅仅是集合。您是否建议始终编写在集合中存储值的步骤定义?像
@When(“I register”){customerRegistrationResponses.add(response);}
?米哈伊尔科皮洛夫,是的,看起来你对黄瓜很有经验。因此,所有场景都可能使用second_ticket或family_ticket变量,因为它们在范围内。这难道不污染整体范围吗?Cucumber有一个世界的概念,这就是全球范围。这是基于这样一种理念设计的,即在这个全局范围内,任何模棱两可的东西在您对业务领域的理解中都是模棱两可的,解决这一问题的最佳方法是通过命名消除模棱两可,而不是通过名称空间来允许模棱两可。在使用这项技术时,你必须非常严格——没有30行多变量场景。我的规则是>7行恶臭,>5行恶臭,超过3个变量恶臭。注意,helper方法在全局范围内(至少在ruby中是这样)。因此,真正的艺术是尽可能少地使用辅助方法,同时保持它们的简单性,并且使用NamingHanks进行精确和严格的训练,我喜欢这个想法。你提到这是一个简单的解决方案。还有其他不那么优雅的方法吗?有很多种方法可以让我呕吐得很厉害,在我的时间里,我可能已经做了很多,但现在仍然会犯错误。但是我不打算告诉你关于他们的事情,原因有两个。1) 我最近没有太多的经验,所以我不是很合格。2) 我不想推荐不好的做法。谢谢,看来你对黄瓜很有经验。因此,所有场景都可能使用second_ticket或family_ticket变量,因为它们在scop中