单元测试实施解惑(一)

在刚过去的一个月中,我完成了一个小软件框架的设计与实现。期间由于并行开发的需要,在没有对代码完成单元测试的情形下我将之check in到了SVN的主干上,随后的心情很是忐忑。因为我知道我一定会犯错(事实也证明在单元测试完成之前就发现了两个缺陷),害怕给他人带来麻烦并影响自己的形象。

  另外,由于对刚加入项目的单元测试环境完全不了解,所以在该框架的前期开发工作中我并没有运用单元测试渐进地保证软件质量。其结果可想而知,我花了不少时间去修复编码过程中遗留下来的低级错误。需要指出的是,所在项目是一个大型嵌入式系统,项目编译一次就得20分钟左右,调试效率可以想象。与之不同的是,单元测试可以在Linux/Cygwin这样的环境中完成,加上可以使用gdb进行调试,开发效率提高一个数量级应不是问题。

  由于我深刻地体会到了单元测试对工作与生活质量的重要性,所以持“真正高质高效的软件开发工程师,一定是那些深刻理解并切实实施单元测试的人”这一观点。然而,就我过去几年的工作见闻来看,发现身边绝大多数的工程师并没有真正用心去拥抱单元测试。出现这样的状况,我认为存在一定的原由,因此想借本文谈谈一些认识。

  有相当一部分工程师是因为并不了解什么是单元测试而没能尝到单元测试的好处。一部分人认为,平时开发工作中的调试其实就是单元测试(参见《明析单元测试》),有的则因为没有花时间学习单元测试而对之不了解。对于这些新手,我并不打算在本文对之“扫盲”,请下载ClearRTOS源码(点击下载)和本文的附件自行学习。 ClearRTOS 是我为《专业嵌入式软件开发》一书所设计的、可在Cygwin和Linux环境中运行的“实时”操作系统,其中涵盖有单元测试方面的内容,更具体的信息见文后。

  另外的一部分人尽管实施过单元测试,但却没能从中受益,甚至得出“单元测试无用”的结论。这部分人的困惑是我最想在这里加以指出的。归结起来,我认为实施过程中的“缝太大”是其中一大主因。

  不少团队将项目的产品代码与单元测试代码加以区别对待,这是产生“缝”的第一大根源。表现之一是,编译产品代码与编译单元测试代码采用完全不同的编译环境,程序员在日常工作中需要不停地在两个编译环境中进行切换。这种方式很容易让工程师感到麻烦,甚至因此遭到抵制或弃用。好的方式是,将单元测试代码的编译环境与产品代码进行无缝整合。比如,在嵌入式系统项目中做到运行“make release”或“make debug”实现产品代码编译,运行“make unitest”完成单元测试代码编译(ClearRTOS项目就是这么做的)。做到编译环境的无缝整合需要团队中存在精通编译环境构建语言(比如Makefile)的专家。很不幸的是,这方面的专家少得可怜,团队对这方面知识的精进也因为没有意识到其重要性而缺乏动力。

  表现之二是,产品代码与单元测试代码区别维护。采用这种方式的团队,很容易在工作中将单元测试摆到更低的位置,开发过程会先以产品代码为主,然后(有时间时)再补上单元测试代码。这种方式很容易降低实施单元测试的效果,且容易因为产品代码与单元测试代码的不同步而带来更大的维护成本。实际上,实施单元测试的一大好处就是在对产品代码进行变更时,通过及时实施单元测试保证软件质量。及时维护单元测试代码从短期和长期都具有很好的经济性,而非象我们想象的那样成本高昂。

  产生“缝”的第二大根源,是因为工程师在单元测试过程中不能方便地获得代码覆盖报告。以我的观点,代码覆盖报告应在开发环境中运行象“make creport”这样的命令而轻松获得(ClearRTOS项目同样实现了这一点)。我看到过一些项目,工程师为了获得覆盖报告,需要登录到一个Web服务器上才能查看,而非在工程师的工作机器上随手获取。

  产生“缝”的另一大根源与单元测试的“打桩”方法有关。被广为采用的方法是通过使用象Cmockery这样的单元测试框架以打桩的形式,将被测模块独立出来。这种方式尽管被广泛采用,但我觉得所需付出的成本还是很高的。因为“桩的世界”与“产品代码世界”存在很大的“缝隙”,维护期间需要不停地在两个“世界”进行切换,更好的方式是将桩代码融入到产品代码中(细节我想通过另一篇文章给出)。

  尽管我认为单元测试是一种有效的质量保障方法,但其有效性在工程界和学术界都存在一定的争议。

  关于ClearRTOS

  ClearRTOS现在是一个开源项目,读者可以通过SVN获取将来的新版本。为了能在ClearRTOS项目中获得HTML格式的代码覆盖报告,读者需在Linux/Cygwin中安装LCOV(链接)。

  在ClearRTOS项目中获取代码覆盖报告的步骤如下:

  1)运行“tar xzvf ClearRTOS.tar.gz”解压。

  2)运行“cd ClearRTOS/build”进入编译目录。

  3)运行“make unitest”编译单元测试程序。

  4)运行“make test”执行单元测试程序。

  5)运行“make creport”获取单元测试报告。报告可用IE、Chrome等浏览器打开ClearRTOS/build/coverage/index.html文件进行浏览。通过点击网页中的相关链接可以查看到每个源文件的代码覆盖情况。

====================================分割线================================

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-10-03 13:37:47

单元测试实施解惑(一)的相关文章

如何激励同事编写单元测试?

从管理人员到开发者,每个人都在说单元测试,但是却很少有人执行.有关单元测试的好处相信大家也能例举出一二,但很多时候,开发者面对自己的项目代码却无从下手. Lurkerbelow在公司里是唯一执行单元测试的一名开发者,他深知单元测试带来的好处,也积极提倡单元测试.他甚至与公司的管理层人员.开发者都讨论过单元测试,但却无人对此感兴趣. 为了与开发人员形成一条战线,Lurkerbelow甚至"被迫"提交了代码审查(Gerrit)和持续集成开发(Jenkins). 无奈之下,Lurkerbel

先“解惑”后实施 CIO需全面了解ERP[2]

首先,实施ERP应该认真采纳" 整体规划,分步实施,关注试点,持续优化"的实施策略.有些企业做到了"整体规划,分步实施",但 忽略了"关注试点,持续优化".在某一阶段工作完成后,并未就ERP对管理的促进和需要持续优化方面进行总结,并坚定不移地全面地进行后续推动. 其次,在具体每一阶段的实施中,我们可以归纳出以下重要的http://www.aliyun.com/zixun/aggregation/6364.html">控制风险的因素

iOS单元测试1

iOS单元测试1 iOS单元测试分为两种类型的测试: 应用测试.应用程序测试可以检查app的代码组件,比如计算机的算术运算的例子.你可以利用应用程序测试来确保你的UI空间控件保持原有位置,并且你的控件和控制器对象能够和对象模型正确地工作. 逻辑测试(库测试).逻辑测试可以检查独立代码的行为是否正确.利用逻辑测试,你可以将整个库的组件放在一起进行测试,通常测试对象是对象和方法. 性能测试:所谓性能测试,主要是评估一段代码运行的时间.(自己添加的,个人觉得应该也属于一类测试把).性能测试的格式:-

JUnit和单元测试入门简介

JUnit和单元测试入门简介 1.几个相关的概念 白盒测试--把测试对象看作一个打开的盒子,程序内部的逻辑结构和其他信息对测试人员是公开的. 回归测试--软件或环境的修复或更正后的"再测试",自动测试工具对这类测试尤其有用. 单元测试--是最小粒度的测试,以测试某个功能或代码块.一般由程序员来做,因为它需要知道内部程序设计和编码的细节. JUnit --是一个开发源代码的Java测试框架,用于编写和运行可重复的测试.他是用于单元测试框架体系xUnit的一个实例(用于java语言).主要

WinUnit:简化的本机C++应用程序单元测试

本文讨论: 单元测试原理 设置 WinUnit 构建测试装置 实施和自定义 本文使用了以下技术: C++和Visual Studio 目录 立即开始测试 WinUnit 入门 装置:设置和清除 运行 WinUnit 实现详细信息 深入学习... 目前,要想让本机代码开发人员一点也感觉不到压力可能是非常困难的- 好像使用 Microsoft .NET Framework的开发人员拥有所有出色的工具! 我一直以来都对丰富的工程实践经验感兴趣,但所谓的"工程专家"却屡屡让我失望,他们只会赞扬

自动化单元测试的实践之路

自动化单元测试并不是什么新鲜事物,它应该是团队持之以恒的事情,可能有很多团队知道如何去做,但是还做得不够好:还有不少团队不知道如何去做,甚至有一些旧系统还不敢去重构,还在坚持着Java中的main方法调用的方式来执行,在漫长等待构建结果. 本文主要讲基于Java项目如何做自动化单元测试的实践. 1 是否值得 关于单元测试的意义,详细参考stackoverflow这篇文章: http://stackoverflow.com/questions/67299/is-unit-testing-worth

单元测试:在您的数据库项目中应用测试驱动的开发

本文讨论: TDD 的优点 在数据库开发中应用单元测试 组合 T-SQL 与 .NET 兼容的语言 连接.测试条件和事务 本文使用了以下技术: Visual Studio 2008, SQL Server LMicrosoft 于 2006 年 11 月发布了 Visual Studio Team System Database Edition,也称为 DBPro 或 Data Dude,它向产品生命周期方法中引入了数据库开发.DBPro 还引进了数据库单元测试设计 器,使用它可以轻松地生成或编

如何做好单元测试

前言 单元测试是对软件基本组成单元进行的测试,是属于白盒测试的范畴,它主要通过对代码的逻辑结构进行分析来设计测试用例.在动态测试手段中,单元测试是一种非常高效的测试方法,并且是软件测试周期中第一个进行的测试.从成本角度考虑,缺陷发现越早越好,加强单元测试力度有利于降低缺陷定位和修复难度,从而降低缺陷解决成本,同时加强单元测试也减轻了后续集成测试和系统测试的负担.根据业界的统计,一个 BUG 在单元测试阶段发现花费是 1 的话,到集成测试就变为 10 ,到系统测试就高达 100 ,到实际推向市场量

实践单元测试(3)-Using NUnit

NUnit是.net平台上使用得最为广泛的测试框架之一,本文将通过示例来描述NUnit的使用方法,并提供若干编写单元测试的建议和技巧,供单元测试的初学者参考. 继续下文之前,先来看看一个非常简单的测试用例(TestCase): 1 [Test]2 public void AdditionTest()3 {4 int expectedResult = 2;5 6 Assert.AreEqual(exptectedResult, 1 + 1);7 } 你肯定会说这个TestCase也太白痴了吧!这也