困惑:单元测试该在什么时候写?

来源:互联网 发布:淘宝商家运作流程图 编辑:程序博客网 时间:2024/06/05 03:56

原文:http://www.codinghorror.com/blog/2005/04/good-test-bad-test.html

作者: Jeff Atwood


很多年以来,用于随机测试(ad-hoc test)的工具我都是自己开发的。但在最近的一个项目中,我终于采用了NUnit和TestRunner来做正式的单元测试。下面是我编写的第一个单元测试,看起来很简单,而且轻轻松松就通过了:

<TestFixture()>_

PublicClass UnitTests

 

  Private _TargetString As String

  Private _TargetData As Encryption.Data

 

  <TestFixtureSetUp()> _

  Public Sub Setup()

    _TargetString = "an enigma wrapped ina mystery slathered in secret sauce"

    _TargetData = NewEncryption.Data(_TargetString)

  End Sub

 

  <Test(),Category("Symmetric")> _

  Public Sub MyTest()

    Dim s As New Encryption.Symmetric(Encryption.Symmetric.Providers.DES)

    Dim encryptedData As Encryption.Data

    Dim decryptedData As Encryption.Data

 

    encryptedData = s.Encrypt(_TargetData)

    decryptedData = s.Decrypt(encryptedData)

   

    Assert.AreEqual(_TargetString, decryptedData.ToString)

  End Sub

 

EndClass

 

这个测试系统真是太棒了,因为我一眼就能看出这块代码在测什么,以及它是如何工作的。这不禁让人感叹:简单就是美!于是,实现单元测试的框架已经不成问题。问题在于,要决定测什么,以及如何去测。或者再把问题理论化一点:怎样才算是好的测试?

单元测试的价值是毋庸置疑的!跟大多数开发人员所做的测试比起来,即使是最最基本的单元测试(就像上面给出的例子那样),也是巨大的进步。也就是说,大部分开发人员根本就不做测试!他们只是随意输入一些数据,然后点几个按钮。如果在这个过程中没有发现尚未处理的异常,他们就觉得代码已经够好了,可以交付给测试团队了……

单元测试的真正价值在于,它迫使你停下来,为测试思量一番。跟漫无计划的随机测试比起来,单元测试让你为你刚刚写下的代码思考一连串艰难但又不得不考虑的问题:

  • 我该怎样测试这块代码?
  • 我该执行何种测试?
  • 通常的情况是怎样的?
  • 可能碰到的异常情况有哪些?
  • 我有多少外部依赖关系?
  • 我可能会碰到哪些系统故障?

单元测试并不会保证软件最终能正确工作。我觉得抱有那种期望也是不合理的。但编写单元测试确实保证了开发人员想过了那些相当棘手的测试问题,哪怕他们只是粗略地想了一下。不用怀疑,只要做了单元测试,我们就已经在正确的方向上前进了一步。

关于单元测试,我也确实有一些其他的纠结。比如,如何在单元测试与大规模的代码重构之间找到平衡——在我做过的所有项目中,在开发的早期阶段大都要进行重构。其实,Unicode Andy也有同样的纠结:

在单元测试方面,我当前遇到的主要问题是,当我修改设计的时候,就会有一大堆测试通不过。这意味着,我要么少写一点测试,要么尽量少做大的设计修改。但两者都是不理想的。

为了避免这个问题,我只能退而求其次——测试晚一点再介入——但这又跟新潮的“测试驱动开发”模式背道而驰。编写单元测试是必要的,积极地重构代码也是必要的。你是如何来平衡的呢?先写测试的方式可以减少代码重构的负担吗?或者在设计稳固之后再增加单元测试?