这是有关测试系列的第二篇文章。 在第一部分中,我解释了在进行测试开发时需要具备的心态。 或者,换句话说,开发可测试的代码。 在这一部分中,我将介绍一些测试方法的技术。 我将描述的技术可以看作是如何将思维定势转化为行动。
技术技巧
测试类型
测试的类型是我们测试的层次 。 最明显的一个是单元测试 。 使用JUnit(或TestNG或任何其他工具),您将测试代码的行为。 每个测试应检查被测类/方法的一种行为。 我通常称集成测试为另一层测试,通常由开发人员完成。 这种类型的测试通常将是代码的一部分(在测试目录下)。 集成测试可以一起测试几个类。 他们可能会测试部分流量。
我喜欢测试Spring接线,并验证上下文文件是否正确。 例如,如果我注入了bean列表,则顺序很重要。 测试接线可以视为集成测试。 另一个示例是检查DAO类和使用它的类的集成。 有时,这些部分存在“意外”。 作为更高级别的测试,您将需要测试请求和响应(REST)。 如果您有GUI,也可以为此创建一个自动化测试服。
自动化
自动执行整个开发周期。 使用CI服务,例如Hudson / Jenkins。 将您的JUnit,Selenium,JMeter,JBehave添加到您的CI环境中。
我建议以下内容:
- CI,用于检查SCM的更改并在发生更改时运行。
- 每晚(或每隔几个小时)。 较慢的自动化测试服,可以检查更多内容,例如集成测试。
每晚会变慢。 如果进行连续部署,则设置可能会有所不同。
环境
有专用的测试环境。 可以清除并重新填充的数据库。 如果您使用REST服务,请为您的测试和自动化环境配备一台服务器。 如果可以,请尝试使其与生产环境尽可能相似。
存根,模拟
有用于存根和模拟的框架。 但是首先要了解它的含义。 存根和嘲笑之间略有不同。 基本上,它们都伪造了一个真实的对象(或接口)。 您可以告诉伪造对象在某些输入中表现出所需的行为。 您还可以验证是否使用预期参数调用了它(在下一篇文章中有更多关于它的信息)。
外部资源的使用
您可以伪造数据库,也可以使用某种嵌入式数据库。 嵌入式数据库可帮助您隔离包括数据库的测试。 外部服务也是如此。
描述性测试
- 添加message参数。
assertTrue("Cache pairs is not size 2", cachPairs.size() == 2);
它至少具有两个好处:
- 该测试更具可读性
- 失败时,该消息更加清晰
您有多少次因为没有消息而无法分辨出问题所在? 测试失败是
assertTrue(something)
,没有message参数。 - 用描述性名称测试。 不要害怕具有(非常)长名称的测试方法。 当测试失败时,它确实有帮助。 不要将测试命名为:
public void testFlow(){...}
。 没什么意思 - 有命名约定。 我喜欢命名测试:
public void whenSomeInput_ThenSomeOutput() {...}
。 但是,无论您想为测试命名如何,都应遵循所有测试的约定。
测试结构
尝试遵循: 给定,何时,然后顺序。 给定的部分是您创建测试环境(创建嵌入式DB,设置某些值等)的部分。 这也是告诉模拟对象(如何在下一篇文章中了解更多)行为的部分。 什么时候是运行测试代码的部分。 然后在这里使用断言检查结果。 这是验证方法被调用的部分。 或不。 如果很难保持有序的结构,则可以将其视为测试气味 (请参阅上一篇文章)。
单元测试应快速运行
班级的单元测试应运行1-5秒。 不多。 无论是否失败,您都需要最快的反馈。 您还将希望尽可能多地运行单元测试。 如果一个班级的测试大约需要30-60秒,那么通常我们不会运行它。 在您的所有项目上运行完整的测试服应该不会超过几分钟(超过5分钟太多)。
覆盖范围
测试应涵盖您所有的生产代码。 覆盖率有助于发现未经测试的现货代码。 如果由于某些代码分支(if-else)而难以覆盖某些代码,那么您还是有测试的味道。 如果您练习TDD ,那么您会自动获得很高的覆盖率。
重要:不要将代码覆盖范围作为目标。 代码覆盖率是一种工具。 用它。
TDD
请允许我不要在此处添加任何内容...
结论
在这篇文章中,我给出了关于如何通过测试进行开发的更多方法,更具体。 在下面的文章中,我将提供一些有关如何使用可用工具的指示和技巧。
翻译自: https://www.javacodegeeks.com/2014/11/its-all-about-tests-part-2.html