《测试驱动的嵌入式C语言开发》——第1章测试驱动开发

第1章 测试驱动开发
我们都做过这样的事——写一大堆代码然后艰难地使它工作起来。也就是先建造再修正。测试是在代码写完之后的事情。测试总是一件后面加上来的事情,这也是我们过去唯一所知的方法。
这种很难预料的过程被亲切地称为“调试”(debugging),我们可能会在其中花掉半个小时。调试的过程在我们的进度中被“测试”和“集成”粉饰起来。它总是风险和不确定的来源。修改一个bug可能导致产生另一个,有时是一系列其他的bug。我们往往会统计这些数据来预测把bug全部修改掉还需要花多少时间。然后我们会去关注曲线的拐点,拐点上的趋势表明我们修改bug的速度终于超过了新引入并报出bug的速度。拐点说明我们几乎就要完成了——但我们永远不能确切地知道在代码的某个黑暗的角落里是否还躲着一个杀手级bug。
开发人员在瀑布模型开发的最后阶段往往忙作一团,与其等到那时才发现问题,质检部门不如在开始时就写一些回归测试以尽快发现那些问题。可我们还是经常会遇到意外:一个小小的错误可能要花上几天、几个星期甚至几个月才能发现。有些错误从未找到。
一些有远见的人看到了这里的潜在问题,他们发现短的开发周期产生的问题会少一些。他们发现积极的测试自动化可以节省时间和精力。这样就不再需要继续重复冗长乏味且错误百出的工作了。测试不一定非要花费出动一小队手工测试人员这样昂贵的代价。很快人们就发现了其中的边际效应(side effect):可以避免调试了。解决了项目进度变化的一个根本原因,那么就会出现更靠谱的项目计划。

著名的嵌入式大师Jack Ganssle提出集成和测试是软件开发的脉络。不过还不能这么说,起码在目前广泛流行的开发方式中还不是,但它们以后必须是。测试驱动开发(Test-Driven Development,TDD)就是其中一种方式—一种有效的方式,它可以把测试贯穿到软件开发的脉络中去,它是你代码的“Kevlar”防弹衣。
把TDD应用于嵌入式C语言开发有很多值得关注的地方,这就是本书的目的。在这一章里,你将从“万米高空鸟瞰”TDD。然后我们将把TDD应用到一个简单的C模块中。当然,这会引发很多疑问。这些疑问将在第2章回答。在开始之前,我们先来看一个著名的bug。如果用了TDD,这个bug可能就可以避免了。

时间: 2024-09-10 06:19:56

《测试驱动的嵌入式C语言开发》——第1章测试驱动开发的相关文章

《测试驱动的嵌入式C语言开发》——第3章开始一个C语言模块

第3章 开始一个C语言模块在本章里,我会带你浏览用测试驱动来开发一个新的C模块首先要经历的那些步骤.在第4章里,我们则会全速前进来完成这个模块.从这一章开始并且贯穿本书,我们会关注到底能不能实现Dijkstra的不引入bug的愿景.我们所用的工具就是TDD.

《测试驱动的嵌入式C语言开发》——3.5节先测试驱动接口再测试驱动内部实现

3.5 先测试驱动接口再测试驱动内部实现好的接口对于设计良好的模块来讲很关键.前面几个测试会驱动接口设计.关注于接口意味着我们是从外向内开发代码的.测试作为接口的首个用户,从调用者(或客户端代码)的角度给出了开发代码的使用方式.从使用者的角度出发会产生可用性更强的接口.我通常也会让前面的几个测试来检验一些产品代码的边界条件.选择一个带边界检查的简单用例. 为了消除这个编译错误,在模块的接口声明头文件中增加这个接口函数原型: 写出并且通过这些测试能帮助我们实现以下目标:它定义了驱动程序的一个接口函

《测试驱动的嵌入式C语言开发》——3.3节写一个测试列表

3.3 写一个测试列表在开发新功能之前先创建一个测试列表会很有帮助.测试列表由需求衍生而来.测试列表定义了你对将需要完成的功能的最好的理解.这个列表不需要很完美.它只是个临时的文档,可能只记在一张卡片上或者笔记本上.你也可以直接把它当做注释输入到测试文件中.随着每个测试的添加,对应的注释将被删除.不要在写作这个列表上花太多时间,对于LED驱动程序来讲,花几分钟即可.我的初始测试列表如图3-1所示.在我们开始之前,先列出我们都需要测试什么. 请当心在创建测试列表时的报酬递减(diminishing

《测试驱动的嵌入式C语言开发》——2.6节我们到哪里了

2.6 我们到哪里了到这里,你应当对Unity和CppUTest的概况有了很好的了解,并且明白了如何用测试夹具和测试用例来定义测试.到目前为止你还没有看到测试驱动开发(TDD),为sprintf()写的那些测试并不是TDD,因为sprintf()是已经存在的代码.请你把新学到的知识运用到接下来的练习中.在接下来的两章中我们会用测试驱动来开发一些新代码.学以致用 在开发平台上建立一个测试环境.你可以从附录A中得到一些帮助.下载书中的代码,并运行makefile.可以访问本书的主页找到书中的代码:

《测试驱动的嵌入式C语言开发》——3.6节增量式前进

3.6 增量式前进 刚刚接触TDD的人往往为这样的早期版本代码而感到困惑."我们什么也没有测到(你可能这样想),这只是些硬编码的返回值":"或者测试太小了,我们只是在各种活动间跳来跳去".让我来进一步解释. DTSTTCPW:先仿冒再建造 回首我刚刚学习极限编程时,Kent Beck在黑板上写下了这个很到位的缩写:DTSTTCPW.它读起来还蛮押韵的:我希望我也能找到那么押韵的一组词.它是Do The Simplest Thing That Could Possib

《测试驱动的嵌入式C语言开发》——2.2节Unity:一个全部用C实现的自动化测试框架

2.2 Unity:一个全部用C实现的自动化测试框架Unity是一个简单且直接的自动化单元测试框架.它由很少的几个文件构成.让我们通过几个示例单元测试用例来认识一下Unity和单元测试.如果你是一个长期的Unity用户,你会发现如果不用Unity所提供的脚本来生成测试运行容器,那么额外的几个宏可能会很有帮助.用Unity写的sprintf()测试用例 测试要写得短并且有重点.可以把它想象成一个安检过程,通过时保持安静,失败时就要发出警报声.下面这个测试让sprintf()处理一个没有格式操作的格

《测试驱动的嵌入式C语言开发》——3.8节测试要做到FIRST

3.8 测试要做到FIRST在Agile in a Flash[OL11]一书中,Tim Ottinger和Jeff Langr给我们讲述了5个单元测试的关键属性.高效的测试需要做到FIRST.F Fast(快速的): 测试要快速,快到程序员可以在每个微小的改动后都运行它们而且不会打断工作流.I Isolated(独立的): 测试用例要是独立的.一个测试不会为另一个测试创建环境.测试中的失败也要分离开.R Repeatable (可重复的): 测试要可以重复地去运行.可重复意味着自动化.一个循环

《测试驱动的嵌入式C语言开发》——3.4节写第一个测试

3.4 写第一个测试现在测试列表已经有了,我们可以开始了.很自然,第一个测试是去测试初始化是否正确.LED在初始化后应当全部关闭.首先我们要建立LedDriver测试文件.按照惯例,可以将它命名为LedDriverTest.c.我通常把测试代码放在一个与产品代码不同的目录里.我会把这些代码放在unity/LedDriver目录中,并调整makefile从而让它能编译和链接这个新的测试文件.给测试起个合适的名字来反映我们要实现的目标,这个文件看起来如下所示: 现在让测试检查一些有意义的东西.看一下

《测试驱动的嵌入式C语言开发》——1.2节什么是测试驱动开发

1.2 什么是测试驱动开发测试驱动开发(TDD)是一种增量式软件开发技术.简单地说,就是在没有失败的单元测试的前提下不可以写产品代码.这些测试要很小,而且要自动化.用测试来驱动其实很合理.相对于直接工作在产品代码上,TDD的实践者们会先用测试来表达他们希望产品代码会有什么样的行为.然后这个测试显然会失败.只有在这时,他们才开始写产品代码,以便让测试通过.测试自动化是TDD的关键.在TDD的进程中,首先会生成新的自动化测试,紧跟着是满足这些测试的产品代码.一套单元测试伴随着产品代码同时不断增长,它