单位测试篇2-TDD三大法则解密

打印 上一主题 下一主题

主题 843|帖子 843|积分 2529

弁言

在我们上一篇文章了解了单位测试的基本概念和用法之后,本日我们来聊一下 TDD(测试驱动开发)
测试驱动开发 (TDD)

测试驱动开发英文全称是Test Driven Development 简称 TDD。
根据 UncleBob 的 TDD 描述总结
我们先创建一个测试项目

直接在 VS 创建即可,可以参考上一篇文章的创建过程
The Three Laws of TDD.

  • You are not allowed to write any production code unless it is to make a failing unit test pass.
  • You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
  • You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
这是本文的描述的三个 TDD 开发的原则,它确保了代码的质量和可维护性。
下面对这三条内容做详细的表明

  • 第一条规则指出 不允许编写任何的生产代码,除非是在让单位测试通过期。

    • 简单理解就是在编写任何实际的业务逻辑代码之前,必须先编写一个或者多个单位测试,这些单位测试因为没有实现所以会失败,有了失败的单位测试之后我们才可以去在生产代码中实现业务逻辑



  • 第二条规则指出 不允许编写比失败所需更多的单位测试代码;编译失败也是失败:

    • 这可以理解为 在编写单位测试时,应该只编写足够使测试失败的最小代码量。这样,可以立即知道新写的生产代码是否解决了题目。编译失败同样被视为测试失败,因为编译不通过意味着代码无法运行。

那一个我们上一章节的一个数学计算类的例子
  1. namespace dotNetParadise_TDD.Test;
  2. public class MathCalculatorTests
  3. {
  4.     [Fact]
  5.     public void Add_TwoNumbers_ReturnSum()
  6.     {
  7.         // Arrange
  8.         var calculator = new MathCalculator();
  9.         // Act
  10.         var result = calculator.Add(3, 5);
  11.         // Assert
  12.         Assert.Equal(8, result);
  13.     }
  14. }
复制代码
因为我们没有 MathCalculator 这个类的实现所以,代码会编译失败。

在这个示例中,我们展示了如何编写一个简单的单位测试,测试 Calculator 类的 Add 方法是否能够正确地将两个数字相加并返回正确的结果。根据 TDD 原则,我们只编写了必要部门的代码来测试这个功能,而且在这个阶段测试应该会失败,因为 Add 方法还未实现。编译失败也会被视为测试失败,这强调了编写足够简洁和精确的单位测试的重要性,符合第二条准则。

  • 第三条规则指出 不允许编写比通过单个失败单位测试所需更多的生产代码
    可以理解为在编写生产代码时,只需编写足够让失败的单位测试通过的代码,而不是一次性编写完整的功能。这有助于保持代码的小步进步,而且每次更改都有明确的测试验证。
现在把MathCalculator类中增长一个参数*2 即翻倍的一个功能
第一步编写一个单位测试方法,
  1.     [Fact]
  2.     public void DoubleNumber_WhenGivenSingleNumber_ReturnsDouble()
  3.     {
  4.         // Arrange
  5.         var calculator = new MathCalculator();
  6.         // Act
  7.         var result = calculator.DoubleNumber(2);
  8.         // Assert
  9.         Assert.Equal(4, result);
  10.     }
复制代码
第二步 编写足够让失败的单位测试通过的代码
  1. namespace dotNetParadise_TDD.Test;
  2. public class MathCalculator
  3. {
  4.     public int DoubleNumber(int number)
  5.     {
  6.         throw new NotImplementedException();
  7.     }
  8. }
复制代码
接下来运行单位测试
  1.  dotNetParadise_TDD.Test.MathCalculatorTests.DoubleNumber_WhenGivenSingleNumber_ReturnsDouble
  2.    源: MathCalculatorTests.cs 行 20
  3.    持续时间: 371 毫秒
  4.   消息: 
  5. System.NotImplementedException : The method or operation is not implemented.
  6.   堆栈跟踪: 
  7. MathCalculator.DoubleNumber(Int32 number) 行 7
  8. MathCalculatorTests.DoubleNumber_WhenGivenSingleNumber_ReturnsDouble() 行 26
  9. RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
  10. MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
复制代码
结果和预期一样,测试没有成功

现在来重构一下这个方法
  1.     public int DoubleNumber(int number)
  2.     {
  3.         //throw new NotImplementedException();
  4.         return 2 * number;
  5.     }
复制代码
再次运行单位测试

可以看到单位测试成功了!
TDD 开发流程图

末了

通常我们举行单位测试的时间都是先写业务逻辑,然后再单位测试,当体系业务逻辑变复杂之后可能会遗漏一些测试 Case。TDD 的出现就是解决这个题目,通过测试 Case 来写重构业务代码的模式。
这三个规则确保了 TDD 的核心循环:红(测试失败)、绿(测试通过)、重构。通过不断地重复这个过程,开发者能够编写出高质量、可测试、易于维护的代码。
本文完整源代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

冬雨财经

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表