ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 迈出单元测试的第一步

迈出单元测试的第一步

原创 Linux操作系统 作者:q77585214 时间:2012-07-28 14:20:48 0 删除 编辑
单元测试不仅是软件行业的最佳实践,在敏捷方法的推动下,它也成为了可持续软件生产的支柱。根据最新的年度敏捷调查,70% 的参与者会对他们的代码进行单元测试。 单元测试和其他敏捷实践密切相关,所以开始编写测试是组织向敏捷转型的踏脚石。道路漫长,但值得去做。我将在本文介绍符合要求的小技巧,以及在开发周期里进行单元测试的步骤。 有效的单元测试默认要能自动化。没有自动化,生产力就会下降。没有自动化,单元测试的习惯也不会持续太久。依靠手工测试(由测试人员或开发人员完成)并不能持续太长时间;在有压力的情况下,没人会记得去运行所有的测试,或者去覆盖所有的场景。自动化是我们的朋友,所有的单元测试框架都支持自动化,而且集成了其他自动化系统。 单元测试对现代开发来说至关重要 有代码相关的测试,我们就有一个天然的安全保障。我们修改的代码要是带来了什么问题,测试会告诉我们。这个安全保障越健全,我们对代码正常运行的信心就越大,对按需修改代码的能力也就越有信心。 和其他类型的测试相比,单元测试的主要优点是反馈迅速。在几秒钟内运行数百个成套的测试,这对开发流程很有帮助。我们会形成“添加一些代码,添加测试,测试运行通过,前进”的节奏。小步前进、确保一切正常也意味着调试时间会大大减少。测试能提高生产力也就不足为奇了——在 Bug 上少花时间,把更多的时间用到新功能的推出上。 依赖关系的壁垒 给新建项目添加测试相当容易——毕竟代码不会阻碍测试。不过这种情况绝对不常见。大多数人都是在处理遗留代码,这些代码不太容易测试,有时候甚至运行不起来——它需要的数据或配置可能只存在于生产服务器上。我们或许要为不同的场景创建不同的设置,这也许会花费过多的精力。在很多情况下,我们可能还会为了测试修改代码。这让人无法理解:我们编写测试就是为了能有修改代码的信心,还没有测试又该如何去稳妥地修改代码呢? 代码可测性是语言和工具的功能。大家认为 Ruby 等动态语言是可测的。对于测试的内部代码,我们可以改变其依赖关系的行为,而不用修改生产代码。C#或 Java 等静态类型语言则不太容易去测试。 下面有个例子:一个 C# 的过期检查方法,检查是否超过了特定日期:
public class ExpirationChecker
{
    private readonly DateTime expirationDate = new DateTime (2012, 1, 1);

    public bool IsExpired ()
    {

        if (DateTime.Now > expirationDate)
        {
            return true;
        } 
        return false;
    }
}
在这个例子里,IsExpired 方法的 DateTime 属性对测试运行时间有强依赖。Now 返回的是实际时间。这个方法有两种情况,它会根据日期返回不同的值。修改计算机时间是绝对不行的,因为我们要在任何时候到任何计算机上去测试场景,并且不能带来任何副作用。 要测试到两种情况,一种可能的解决方案是修改代码。比如说,我们可以把代码修改成:
public bool IsExpired (DateTime now)
{
    if (now > expirationDate)
    {
        return true;
    }
    return false;
}
这样,测试可以注入不同、可控的 DateTime 值,而不用在生产代码里写定一个值。我们要是不能修改代码,可以利用 Typemock Isolator 等 Mocking 框架,模拟静态属性和方法。针对先前的代码,测试可以写成:
[TestMethod]
public void IsExpired_BeforeExpirationDate_ReturnFalse ()
{
    Isolate.WhenCalled (() => DateTime.Now)
        .WillReturn (new DateTime (2000, 1, 1));

    ExpirationChecker checker = new ExpirationChecker ();
    var result = checker.IsExpired ();

    Assert.IsFalse (result);
}
现有的遗留代码不能轻易修改,因为我们没有针对它的测试。开始测试遗留代码之后,我们就能明白:代码越丑陋,测试越困难。工具可以减轻一些痛苦,但我们要努力去构建安全的环境。 依赖关系并不是唯一的内容…… 我们很快会遇到的另一个问题是测试维护:测试和被测试代码耦合在一起。有耦合关系,修改生产代码就有可能破坏测试。要是代码修改引起测试失败,我们就需要回去解决这些问题。很多开发人员害怕维护两个代码库,这种恐惧甚至会让他们干脆不进行单元测试。真正的维护工作既取决于工具,也取决于技巧。 编写好的测试是通过实践获得的技能。编写的测试越多,我们就越精于此,同时会提升测试质量,维护也越来越少。有了测试,我们就有机会重构代码,这反过来又会让测试更简洁、更易读、更健壮。 工具对实践的难易程度有极大的影响。在基础层,我们需要一个测试框架和一个 Mocking 框架。在 .Net 领域,两种框架的选择都很丰富。 编写第一个测试的准则 开始的时候,我们通常会试用不同的工具,来理解他们的工作原理。我们往往不会在实际的工作代码上开始编写测试。但很快就要给代码编写真正的测试。有一些小提示届时会有用: ●从哪里开始:一般来说,我们编写测试是针对工作代码的,无论代码是 Bug 修复还是新功能。对 Bug 修复来说,编写的测试要检查修复。对功能来说,测试应检查正确的行为。 ●支架:以我们掌握的知识来看,明智的做法是先添加能确保当前实现运行的测试。添加新的代码之前先写测试,因为我们希望在修改现有代码之前,能有安全的保障。这些测试被称为“特征测试”,这个术语来自

Link URL: http://blog.jobbole.com/24303/?utm_source=rss&utm_medium=rss&utm_campaign=%25e8%25bf%2588%25e5%2587%25ba%25e5%258d%2595%25e5%2585%2583%25e6%25b5%258b%25e8%25af%2595%25e7%259a%2584%25e7%25ac%25ac%25e4%25b8%2580%25e6%25ad%25a5

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/27207730/viewspace-737981/,如需转载,请注明出处,否则将追究法律责任。

下一篇: 我的个人收藏
请登录后发表评论 登录
全部评论

注册时间:2012-07-28

  • 博文量
    16
  • 访问量
    7890