单元测试的两种方式

简介:

在单元测试中,可通过两种方式来验证代码是否正确地工作。一种是基于结果状态的测试,一种是基于交互行为的测试。

测试结果与测试行为之间有什么区别呢?

基于结果状态的测试,也就意味着我们需要验证被测试代码需要返回正确的结果。

复制代码
 1     [TestMethod]
 2     public void TestSortNumberResult()
 3     {
 4       IShellSorter<int> shellSorter = new ShellSorter<int>();
 5       IBubbleSorter<int> bubbleSorter = new BubbleSorter<int>();
 6 
 7       NumberSorter numberSorter = new NumberSorter(shellSorter, bubbleSorter);
 8       int[] numbers = new int[] { 3, 1, 2 };
 9       numberSorter.Sort(numbers);
10 
11       // 验证返回值是否已经被正确排序。
12       // 只要返回值正确即可,并不关心使用了哪个算法。
13       CollectionAssert.AreEqual(new int[] { 1, 2, 3 }, numbers);
14     }
复制代码

基于交互行为的测试,也就意味着我们需要验证被测试代码是否正确合理地调用了某些方法。

复制代码
 1     [TestMethod]
 2     public void TestUseCorrectSortingAlgorithm()
 3     {
 4       IShellSorter<int> mockShellSorter = Substitute.For<IShellSorter<int>>();
 5       IBubbleSorter<int> mockBubbleSorter = Substitute.For<IBubbleSorter<int>>();
 6 
 7       NumberSorter numberSorter = new NumberSorter(mockShellSorter, mockBubbleSorter);
 8       int[] numbers = new int[] { 3, 1, 2 };
 9       numberSorter.Sort(numbers);
10 
11       // 验证排序器是否使用冒泡排序算法。
12       // 如果排序器未使用冒泡排序算法,或者使用了该算法但传递了错误的参数,则验证失败。
13       mockBubbleSorter.Received().Sort(Arg.Is<int[]>(numbers));
14     }
复制代码

第二种测试方法可能会得出较好的代码覆盖率,但它却没有告诉我们排序结果是否正确,而只是确认调用了 bubbleSorter.Sort() 方法。所以交互行为测试并不能证明代码可以正确工作。这也就是在大多数情况下,我们需要测试结果和状态,而不是测试交互和行为。

通常来说,如果程序的正确性不能仅仅靠程序的输出结果来决定,而还需要判断结果是怎么产生的,在这种条件下,我们就需要对交互和行为进行测试。在上面的示例中,你可能想在得到正确测试结果的前提下,额外的再测试下交互行为,因为可能确认正确地使用了某种算法非常重要,例如某些算法在给定条件下运行速度更快,否则的话测试交互行为的意义并不大。

通常在什么条件下需要对交互行为进行测试呢?

这里给出两种较适合的场景:

  • 假设被测试代码需要调用了一个方法,但可能由于其被调用的次数不同,或者被调用的顺序不同,而导致产生了不同的结果,或者出现了其他类似时间延迟、多线程死锁等副作用。例如该方法负责发送邮件,我们需要确认只调用了一次邮件发送函数。或者例如该方法的不同调用顺序会产生不同的线程锁控制,导致死锁。在类似这些情况下,测试交互行为可以有效地帮助你确认方法调用是否正确。
  • 假设我们在测试一个UI程序,其中已经通过抽象将UI渲染部分与UI逻辑部分隔离,可以考虑是某种MVC或MVVM模式。那么在我们测试 Controller 或 ViewModel 层时,如果有的话,可能只关心 View 上的哪些方法被调用了,而并不关系具体该方法内部是如何渲染的,所以此处测试与 View 的交互就比较合适。类似的,对于 Model 层也一样。

完整代码

  View Code

关于单元测试 mocking 技术,请参考《NSubstitute完全手册》





本文转自匠心十年博客园博客,原文链接:http://www.cnblogs.com/gaochundong/archive/2013/06/05/ut_test_state_or_test_interaction.html,如需转载请自行联系原作者

目录
相关文章
单元测试问题之测试不够如何解决
单元测试问题之测试不够如何解决
单元测试问题之单元测试处理与时间相关问题如何解决
单元测试问题之单元测试处理与时间相关问题如何解决
139 2
5个编写技巧,有效提高单元测试实践
本文作者详细讲解了关于单元测试的相关知识,做好单元测试能有效地保障代码质量,本文将手把手教你学会应用单元测试并附有案例、测试插件。
单元测试编写可测试代码
单元测试编写可测试代码
48 2
测试需要做单元测试吗?
我的回答:测试需要做单元测试,但要综合评估团队成员技能、个人意愿、项目迭代周期以及协作默契程度等很多因素,用合适的方法和手段在合适的时机切入,而不是一味强推。
测试需要做单元测试吗?
前端单元测试那些事
很长一段时间以来,单元测试并不是前端工程师应具备的一项技能,但随着前端工程化的发展,项目日渐复杂化及代码追求高复用性等,促使单元测试愈发重要,决定整个项目质量的关键因素之一
503 0
前端单元测试那些事
Testify Pythoinc的单元测试框架
Testify 是Python的一款测试框架,可以替代unittest和nose。
191 0
Testify Pythoinc的单元测试框架
单元测试,只是测试吗?
推广单元测试,仅仅达到单测覆盖率是远远不够的,我们还要学习写&quot;易于测试&quot;的代码,以及&quot;好&quot;的测试,这样才能让单测真正发挥作用。本文将分享作者关于单元测试的思考与实践。
2395 0
单元测试,只是测试吗?
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等