如何设计高效测试用例

在本系列的第一部分中,我们看到了有效测试应满足的一些普遍适用的原则和约束。 在这一部分中,我们将仔细研究代码级单元测试和组件用例测试。

单元测试

单元测试验证单个单元(通常是类)的行为,而忽略或模拟该单元外部的所有问题。 单元测试应测试各个单元的业务逻辑,而不验证其进一步的集成或配置。

根据我的经验,大多数企业开发人员对单元测试的构建方式都有很好的了解。 您可以在我的咖啡测试项目中查看此示例,以了解想法。 大多数项目将JUnit与Mockito结合使用以模拟依赖关系,理想情况下使用AssertJ有效地定义可读的断言。 我一直认为,我们可以执行单元测试而无需特殊的扩展程序或运行程序,即仅使用纯JUnit运行它们。 原因很简单:执行时间; 我们应该能够在几毫秒内运行数百个测试。

单元测试通常执行速度非常快,并且易于执行,并且不会对测试套件的生命周期施加任何约束,因此它们易于支持构建复杂的测试套件或特殊的开发工作流程。

但是,具有许多模拟被测类的依赖关系的单元测试的缺点是,它们将与实现紧密结合,尤其是类结构和方法,这使得重构代码变得困难。 换句话说,对于生产代码中的每个重构动作,测试代码也需要更改。 在最坏的情况下,这会导致开发人员进行较少的重构,这仅仅是因为它们变得太麻烦了,从而Swift导致项目代码质量下降。 理想情况下,开发人员应该能够重构代码并四处移动内容,只要他们不改变应用程序的行为(从用户的角度来看)即可。 单元测试并不总是使重构生产代码变得容易。

根据项目的经验,单元测试对于测试具有简洁逻辑或功能的高密度代码(例如特定算法的实现)非常有效,同时又不会与其他组件发生过多交互。 特定类中的代码密度越小或越复杂,循环复杂性越低,或者与其他组件的交互性越高,则测试该类的单元测试效果就越差。 尤其是在具有少量专业业务逻辑并且与外部系统具有大量集成的微服务中,对许多单元测试的需求减少了。 除了少数例外,这些系统的各个单元通常包含很少的专用逻辑。 在选择权衡时间和精力的地方时,必须考虑到这一点。

用例测试

为了解决将测试与实现紧密耦合的问题,我们可以使用略有不同的方法来扩大测试范围。 在我的书中 ,我描述了组件测试的概念,因为缺少一个更好的术语,我们也可以将其称为用例测试。

用例测试是代码级集成测试,由于测试启动时间的原因,该类测试尚未使用嵌入式容器或反射扫描。 他们验证通常参与单个用例的一致组件的业务逻辑行为,从边界的业务方法一直到所有涉及的组件。 与外部系统(如数据库)的集成已被嘲笑。

在不使用自动连接组件的更先进技术的情况下构建此类方案听起来很费力。 但是,我们定义了可重用的测试组件或test double ,它们通过模拟,接线和测试配置来扩展组件,以最大程度地减少重构变更的整体工作量。 目标是制定单一职责,以将更改的影响限制在测试范围内的单个或几个类中。 以可重复使用的方式执行此操作会限制总体所需的工作量,并且在项目规模变大后会得到回报,因为我们每个组件只需支付一次管道费用,这很快就可以摊销。

为了获得更好的主意,假设我们正在测试订购咖啡的用例,其中包括两个类CoffeeShopOrderProcessor


测试双重类CoffeeShopTestDoubleOrderProcessorTestDouble*TD驻留在项目的测试范围中,而它们扩展了驻留在主范围中的CoffeeShopOrderProcessor组件。 测试双打可能会设置所需的模拟和连线逻辑,并可能使用与用例相关的模拟或验证方法来扩展类的公共接口。

下面显示了CoffeeShop组件的测试double类:

 public class CoffeeShopTestDouble extends CoffeeShop { public CoffeeShopTestDouble(OrderProcessorTestDouble orderProcessorTestDouble) { entityManager = mock(EntityManager. class ); orderProcessor = orderProcessorTestDouble; } public void verifyCreateOrder(Order order) { verify(entityManager).merge(order); } public void verifyProcessUnfinishedOrders() { verify(entityManager).createNamedQuery(Order.FIND_UNFINISHED, Order. class ); } public void answerForUnfinishedOrders(List<Order> orders) { // setup entity manager mock behavior }  } 

测试double类可以访问CoffeeShop基类的字段和构造函数以设置依赖项。 它使用其测试双重形式的其他组件,例如OrderProcessorTestDouble ,以便能够调用用例中包含的其他模拟或验证方法。

测试双重类是可重用的组件,在每个项目范围内编写一次,并在多个用例测试中使用

 class CoffeeShopTest { private CoffeeShopTestDouble coffeeShop; private OrderProcessorTestDouble orderProcessor; @BeforeEach void setUp() { orderProcessor = new OrderProcessorTestDouble(); coffeeShop = new CoffeeShopTestDouble(orderProcessor); } @Test void testCreateOrder() { Order order = new Order(); coffeeShop.createOrder(order); coffeeShop.verifyCreateOrder(order); } @Test void testProcessUnfinishedOrders() { List<Order> orders = Arrays.asList(...); coffeeShop.answerForUnfinishedOrders(orders); coffeeShop.processUnfinishedOrders(); coffeeShop.verifyProcessUnfinishedOrders(); orderProcessor.verifyProcessOrders(orders); }  } 

用例测试验证在入口点(这里为CoffeeShop上调用的单个业务用例的处理。 这些测试变得简短且易于阅读,因为接线和模拟发生在单个测试双打中,并且它们还可以利用特定于用例的验证方法,例如verifyProcessOrders()

如您所见,测试双重扩展了生产范围类,用于设置模拟和验证行为的方法。 尽管这似乎是一些设置工作,但如果我们有多个用例可以在整个项目中重复使用这些组件,则成本将Swift摊销。 我们的项目增长得越多,这种方法的好处就越大,尤其是当我们查看测试执行时间时。 我们所有的测试用例仍然使用JUnit运行,它可以立即执行数百个测试用例。

这是此方法的主要优点:用例测试的运行速度与普通单元测试一样快,但由于仅需对单个或几个组件进行更改,因此可以方便地重构生产代码。 此外,使用针对我们领域的富有表现力的设置和验证方法来增强测试效率,从而使我们的测试代码更具可读性,更易于使用,并避免了测试案例中的样板代码。

不包含任何高级测试上下文运行程序的代码级测试可以非常快速地执行,并且即使在非常复杂的项目中也不会为整体构建增加太多时间。 该系列的下一部分将显示代码级以及系统级集成测试。

翻译自: https://www.javacodegeeks.com/2019/09/efficient-enterprise-testing-unit-use-case.html

如何设计高效测试用例

如何设计高效测试用例_高效的企业测试-单元和用例测试(2/6)相关推荐

  1. 高效的企业测试-单元和用例测试(2/6)

    在本系列的第一部分中,我们看到了有效测试应满足的一些普遍适用的原则和约束. 在这一部分中,我们将仔细研究代码级单元测试以及组件或用例测试. 单元测试 单元测试验证单个单元(通常是类)的行为,而忽略或模 ...

  2. python助你高效办公_高效办公必备:python—— 30分钟帮你干完一天的工作!

    一次每周例行的会议的前一天晚上,加班的小谭 开着七八个窗口,一栏一栏复制粘贴录入数据,对着满屏的数字干瞪眼. 一抬头同事都下班了,实习生也走了. 千算万算,小谭没算到 Excel崩溃闪退了,好几个小时 ...

  3. 怎么设计接口测试用例更好——百度大佬“教你写用例”

    一.简介 在开始接口测试之前,我们想一下,接口测试的流程是什么?说到这里,有些人就会产生好奇和疑问,心里mmp:接口测试要什么流程哈???不就是参考接口文档,直接利用接口测试工具(例如jmeter和p ...

  4. 高效的磁力搜索引擎 -_高效的企业测试-结论(6/6)

    高效的磁力搜索引擎 - 该系列的最后一部分将涵盖其他端到端测试,生产中的测试以及各部分的结论. 进一步的端到端测试和生产中的测试 除了仅验证单个被测应用程序并模拟外部问题的系统测试之外,我们的管道还必 ...

  5. 如何简单设计接口测试用例

    接口测试是项目测试的一部分 ,它测试的主要对象是接口 ,是测试系统组件间接口的一种测试.接口测试主要用于检测外部系统与所测系统之间以及内部各系统之间的交互点.测试的重点是检查数据交互.传递.和控制管理 ...

  6. 玩转用例设计:XMind2TestCase一个高效的测试用例设计解决方案

    XMind2TestCase 工具,提供了一个高效测试用例设计的解决方案(开源) 一.背景 软件测试过程中,最重要.最核心就是测试用例的设计,也是测试童鞋.测试团队日常投入最多时间的工作内容之一. 然 ...

  7. mac 爱普生打印机驱动_高效打印企业首选 爱普生M2178黑白多功能一体机评测

    提到打印机相信每一个公司都配备了一台,因为它是日常办公中不可缺少.尽管现在很多的工作流程都已经可以在线上执行,且提倡无纸化办公,但很多重要的材料还是需要打印出来存档.签字.因此打印机还是一个非常必要的 ...

  8. 测试框架 如何测试私有方法_高效的企业测试–测试框架(5/6)

    测试框架 如何测试私有方法 本系列文章的这一部分将介绍测试框架以及我在何时以及是否应用它们方面的想法和经验. 关于测试框架的想法 我对大多数测试框架不太满意的原因是,按照我的观点,它们大多增加了语法上 ...

  9. 十把快刀:高效免费的十大企业软件

    温习一下这则家喻户晓的寓言吧:从前,有一个老农民,他有两个儿子.一天,他叫来两个儿子,让他们选一把柴刀上山去砍柴.为了让父亲高兴,大儿子早早上了山,而小儿子则将斧头磨锋利后才上山,最后小儿子挑了两担柴 ...

最新文章

  1. VC使用CRT调试功能来检测内存泄漏
  2. Delphi自动提交网页表单和获取框架网页源码
  3. RESTEasy教程第2部分:Spring集成
  4. mysql query cache 关闭_为什么要关闭MySQL query cache-Fun言
  5. 串口发送接收浮点型数据
  6. 【Vjudge】P558E A Simple Task(线段树暴力)
  7. 几种常见的Java排序算法
  8. 4. Python--Scipy库(上/1-6)
  9. 超市商品管理系统(C++)
  10. 周鸿祎:做到这五点,才算是好用户体验
  11. android 拨打电话 发送短信 权限,Android中发送短信和拨打电话
  12. 2022开放原子全球开源峰会OpenAnolis分论坛圆满落幕
  13. java 字符串 哈希值_Java 获取字符串Hash值
  14. 三轴加速度传感器的计步测算法
  15. Linux普通用户su root权限的开启和禁止
  16. Word一部分内容分为两栏或多栏的方法
  17. JQury及其选择器
  18. 微信小程序实现一个可以编辑单元格的表格
  19. 唱歌如何更好听? KTV调音师帮你忙
  20. ViSual Studio美化插件设置背景图片

热门文章

  1. 牛客题霸 最少素数拆分 C++题解/答案
  2. 2020牛客暑期多校训练营(第四场)
  3. CF903G-Yet Another Maxflow Problem【线段树,最大流】
  4. CF1088F Ehab and a weird weight formula(树上最优性问题、贪心+倍增)
  5. P2468 [SDOI2010]粟粟的书架 动态规划,主席树,二分答案
  6. 经典题:poj2104-区间第k小 整体二分学习
  7. SpringCloud Greenwich(七)集成dubbo先启动消费者(check=false),然后启动提供者无法自动发现注册
  8. ThreadLocal的非数据安全用法
  9. Java开发必须掌握的日志分析命令
  10. 【Python】有效资源爬取并集