每个步骤都有单独的测试方法是一个好主意吗?


10

我正在测试REST API。假设它返回JSON结构。什么是测试服务器的最佳方法?如果所有先前的步骤都成功,则每个测试步骤都只能成功。

结构A:一次测试所有内容

- Test method 1:
    - make server request
    - assert http response code was 200
    - assert returned file is not empty
    - assert returned file has valid JSON syntax
    - assert returned JSON contains key X

这似乎是最好的解决方案。

优点:

  • 仅一个服务器请求
  • 我正在整体测试行为“服务器是否使用键X返回JSON?”

结构B:向每个测试逐渐添加断言

 - Test method 1:
     - make server request
     - assert http response code was 200
 - Test method 2:
     - make server request
     - assert returned file is not empty
 - Test method 3:
     - make server request
     - assert returned file has valid JSON syntax
 - Test method 4:
     - make server request
     - assert returned JSON contains key X

这是我开始出来做,我相信,这应该是去,因为每一个方法只测试方式单一的事情,这创造了更好的分离。但是现在我认为,既然这些不是单元测试,那么我的分离是不合适的,我应该测试整个行为。

结构C:发出请求一次,并对缓存的响应运行单独的测试方法

- make server request and cache it (allow read-only access)

 - Test method 1:
     - assert http response code was 200 on cached server request
 - Test method 2:
     - assert returned file is not empty on cached server request
 - Test method 3:
     - assert returned file has valid JSON syntax on cached server request
 - Test method 4:
     - assert returned JSON contains key X on cached server request

优点:

  • 没有重复的(昂贵的)服务器请求
  • 仍有单断言测试方法

使用哪种最明智的测试结构?


之后请停止更改您的问题,以使现有答案无效!谢谢。
布朗

造成您的不便,我们深表歉意,但您会建议其他方式吗?
mrplow

首先,如果您真的需要以这种方式更改您的问题,请三思而后行。如果您确实认为必须添加使某些答案无效的内容,则可以通过在其答案下方留下评论,询问他们是否要更改或在文本中添加内容,来告知所有作者这些答案。
布朗

2
实际上,我假设如果问题已更改,则会通知答案的作者。这就是为什么我不想用脱机主题语句来垃圾评论。我将来会通知作者。并感谢您为我的问题提供答案。
mrplow

Answers:


3

最佳做法总有目的,这是背后的原因。在设计中考虑这些原因总是一个好主意-尤其是当您试图决定如何以及如何遵循这些最佳实践时。

在这种情况下,使每项测试都成为一项测试的主要原因是,如果第一项测试失败,则第二项测试将不会被测试。由于太多的舆论制定者似乎发现可以将所有内容分解为最小的部分,并尽可能地将所有内容包起来,因此产生了这样的思想,即每个测试都应包含一个断言。

不要盲目跟随。即使每个测试都可以测试一件事,您仍然应该考虑一下每个“事物”的大小,为此,您必须记住为什么要每个测试都测试一件事-确保第一件事中的错误不会使第二件事未经测试。

因此,您需要问自己-“我真的需要这个保证吗?”

假设第一个测试用例中有一个错误-HTTP响应代码不是200。因此,您开始研究代码,弄清楚为什么没有获得应有的响应代码,然后解决问题。现在呢?

  • 如果您再次手动运行测试,以验证您的修复程序确实解决了问题,则应该遇到首次故障隐藏的任何其他问题。
  • 如果您不手动运行它(可能是因为它花费的时间太长?),而只是推送您的修订以等待自动化测试服务器运行所有内容,那么您可能希望将不同的断言放在不同的测试中。在这种情况下,周期非常长,因此值得在每个周期中发现尽可能多的错误。

还有几件事要考虑:

断言依赖

我知道您描述的测试只是一个例子,您的实际测试可能会更复杂-因此,我要说的可能在真实测试中没有足够的优势,但是它可能仍然有效,因此您可以可能要考虑一下。

如果您有一个REST服务(或任何其他HTTP协议)以JSON格式返回响应,则通常会编写一个简单的客户端类,该类可让您使用REST方法,如返回常规对象的常规方法。假设客户进行了单独的测试以确保其正常工作,那么我将放弃前三个断言,仅保留4个断言!

为什么?

  • 第一个断言是多余的-如果HTTP响应代码不是200,则客户端类应引发异常。
  • 第二个断言是多余的-如果响应为空,则结果对象将为null或某个空对象的其他表示形式,并且您将无处放置键X。
  • 第三个断言是多余的-如果JSON无效,则在尝试解析它时会出现异常。

因此,您不需要运行所有这些测试-只需运行第四个测试,并且如果前三个尝试检测到的任何错误都发生了,则该测试将以适当的异常失败,甚至没有获得实际的断言。

您想如何接收报告?

假设您没有从测试服务器收到电子邮件,但是质量检查部门运行测试并通知您测试失败。

质量检查部门的杰克敲门。他说第一个测试方法失败了,REST方法返回了错误的响应代码。您感谢他,并开始寻找根本原因。

然后来自QA的Jen,说第三个测试方法失败了-REST方法未在响应正文中返回有效的JSON。您告诉她您已经在查看该方法,并且您认为导致该方法返回错误退出代码的原因还导致该方法返回的结果不是有效的JSON,并且看起来更像是异常堆栈跟踪。

您重新开始工作,但随后来自QA的Jim表示,第四个测试方法失败了,响应中没有X键。

您甚至都找不到原因,因为当您没有计算机屏幕时很难查看代码。如果吉姆足够快,他本可以及时躲开...

从测试服务器的电子邮件更容易解雇,但还是-你会不会,而只是被通知ONCE的东西是错误的测试方法,并期待在相关的测试日志自己吗?


3

如果可以安全地假设使用相同的参数发出服务器请求的行为总是相同的,则方法B几乎没有意义-为什么一次调用就足够,您应该调用四次相同的方法以获得四次相同的响应数据?

而且,如果您不能安全地假设这一点并希望使其成为测试的一部分,则最好进行多次A测试。

我看到B可能有好处的唯一假设情况是,当您的测试框架只允许打开和关闭显式测试方法时,并且您期望有必要针对测试的各个步骤执行此操作。

备选方案C似乎将A与我上面提到的B的好处结合在一起。如果您的测试框架允许您像这样轻松地构造代码,而在B之上没有太多开销,那么这是一种可行的方法。但是,这给A增加了一些额外的复杂性,因此,仅当我想打开和关闭各个测试时才使用它,否则应用YAGNI原理并坚持最简单的解决方案(A)。

TLDR:如果您确定始终希望所有断言都在一个测试中运行,则从A开始,如果您发现需要从外部对单个断言进行更轻松的控制,则重构为C。


0

像任何代码一样,避免过早优化。首先编写您的测试,以使其易于阅读且易于维护。当测试开始变得太慢时,请对其进行优化。在您的简单示例中,A和B都将易于阅读和维护,因此请选择所需的对象,直到事情变得太慢(结构B)或过于复杂(结构A)为止。

如果服务器是无状态的,则可以通过将实际响应与预期响应进行比较来进行优化,以一次性检查整个消息。显然,这将以可读性为代价。

如果您的服务器是全状态的,并且您需要进行多个缓慢的api调用以使服务器处于测试状态,那么您可以采用其他方法,否则测试可能需要几分钟才能运行。例如,您可以运行数据库更新以将数据注入到测试数据库中,以便您可以快速获取处于适当状态的对象以进行测试。该测试快速且易读,但维护起来更加困难。或者,您也许可以在api前面编写外观,这样多个api调用就变成了一个与您正在测试的业务流程更加匹配的单个api调用。


0

测试不应共享任何东西-从头开始,您要避免一项测试对另一项测试的影响。这也使您能够以随机顺序运行测试。
因此,不应接受C方式


在编写任何代码(甚至可能创建其他任何代码)时,请始终问自己:“为什么要进行这种练习?”
为什么我们说应该对所有事物进行不同的测试?

有两种情况需要时:

  1. 当您不能依靠“每个测试步骤只有在所有先前步骤都成功的情况下才能成功”
  2. 当您的测试没有描述性断言消息时

您遇到这些情况的原因有两个:

  1. “每个测试步骤只有在所有先前步骤都成功的情况下才能成功”,这实际上不适用于您的产品功能
  2. 您由于缺乏经验或时间或产品过于复杂而没有足够的产品知识

如果你因为某些原因不能在这些原因至少一个声明有地方只是一味地采取结构B


否则,(我希望你能在这里)你选择一个


您也可以在软件质量保证和测试 Stackexchange网站上询问此问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.