从单元测试基本概念来看为什么我还是要支持TDD-测试驱动开发

单元测试就是常说的Unit Test
而TDD其实是uTDD - unit Test Driven Development

unit-test.jpg

在我现在的日常工作中,其中一个很重要职责就是保证新人快速成长。这里的“成长”不是应试教育下的快速成长,更不是通过填鸭式教育、题海战术来达到的成长。而是以理解公司文化的为前提,“素质教育”为基础的健康成长。

我们公司的创始人是《敏捷宣言》提出者之一,哪怕在这样一家敏捷绝对拥趸的科技公司里,也一样会有关于TDD的一些常见问题。我在和新人Pair、带团队和
客户参观的过程中都无一幸免的被问到了如下TDD的问题:

  • 为什么我们要TDD ?
  • 任何时候都要TDD吗?什么情况下不用TDD?
  • TDD怎么衡量她的价值?实践她的都是开发人员,她到底有没有价值因该开发人员说了算。

这些问题的提出者以及提出时间,总结起来看还挺有意思。有的完全没有接触实践过敏捷;有的相信敏捷,但还没有付之实践;还有的拥抱后坚持实践了一段时间,思考然后,最终提出反问。

有这些问题其实很正常,回答起来也不难。我们大可以把TDD的好处罗列一翻,把一些正确的大道理再叙述一遍,但我们前面可是标榜过我们自己是“素质教育”,我们更希望对一些基础知识认真打磨,让大家根据这些基础知识结合自身的环境,给出自己的判断。学以致用,融汇贯通。


我们这里说的TDD(测试驱动开发),实际上更准确的描述为单元测试驱动开发。先不谈怎么驱动开发,我们一起来掀开单元测试的外衣,看看到底本尊长什么样?怎么就可以驱动开发了?他能解决什么问题?又对什么问题有心无力?

Unit testing is when you write test code to verify units of code.

翻译起来就是:单元测试就是用来验证代码单元正确性所写的测试代码

我们下面站在 先实现后测试 的原生视角来回答几个问题

“单元”到底怎么定义?

  • 在尺寸上并没有清晰的定义。
  • 一小段展现出某些“有用的行为”的代码
  • 一个单元自身 通常 不表示完整的端对端(end-to-end)行为,它只表示这个端对端行为中的一个子部分。

可以看出这里的“单元”,并没有固定和清晰的定义,比较容易接受的定义是把“单元”和函数划上等号。项目管理中所有的实践,最终都是为了保证项目的按时交付及
质量保证。而且明确说明单元测试不因该表示完整的端对端行为,因为在项目的测试体系里,比如金字塔原理,越接近用户的测试往往是最费时的,所以从成本和质量平衡的角度来看,因该是越精简越好,这其实就是对单元测试提出了明确的要求-集成测试和端到端测试没有覆盖到的,那么单元测试你就给我保证好,至于你用函数分还是以行为分,没有统一的标准。这里借助绝对正确的一句废话-对项目合适的才是最好的。

何时、何故需要写单元测试?

  • 刚刚 完成了一个特性(Feature)的编码并且想确保它能够按照预期工作。
  • 你想用文档记录一个代码中的修改,以便你或其他人能够在以后明白相关的意图。
  • 你需要修改代码,同时希望确保这些即将来临的修改不会破坏任何已经存在的行为。
  • 你希望了解当前系统中的行为。
  • 你希望知道第三方代码的行为在什么时候会与你的期望不符。

简单来说也就是对测试特性的另一种描述,通常我们可以把测试当成文档,因为单元测试要足够的简单,不然就会有人问这样的问题:我们用什么来保证测试本身的正确性呢?是不是得为我们的测试再写测试呢,显然不是,不然不就死循环了嘛。但这不意味着我们就不用保证测试本身的正确性了,简洁性其实就是这个目的,你一眼就能看出来正确与否,那么我们大家都有信心相信我们测试代码的质量,以及功能模块的稳定性也可以通过测试得到了因有的保障。

推荐的测试结构

  • AAA (Arrange - Act - Assert)
  • GWT (Given - When - Then)

需要注意的是,通常我们建议从结果开始(Then/Assert),明确我们希望得到的结果,再设置好测试环境并触发相应的动作。

推荐的测试原则 - FIRST

  • Fast : 好的测试因该足够快 - 因为单元测试的价值在于持续、全面、快速的反馈系统的健康程度
  • Isolated: 好的测试因该相互隔离 - 你应当能够在任何时间,以任何顺序,运行任何一个测试。
  • Repeatable:好的测试应该可复验 - 每一个测试应当在每一次运行时产生与之前一样的结果。
  • Self-Validating - 好的测试应该能够自认证!- 写测试是为了节省时间而不是为了花费更多的时间。所以,测试应当能够自排列、及时、恰到好处的自动化运行,并且能够快速、准确的确认结果,尽可能的不需要手动操作或设置。
  • Timely - 好的测试应该足够及时!- 单元测试是一个好习惯,你越是推迟利用单元测试来验证你的代码,就越是需要付出更多的代价。同理,一旦你将代码提交进了代码库,你专门找时间回过头来补测试的机会也就很小了。

推荐的测试边界原则 - CORRECT

  • Conformance - 一致性 (值是否符合预期的格式?)
  • Ordering - 有序性 (一组值的顺序是否符合预期?)
  • Range - 区间性 (值是否在一个合理的最大值和最小值的范围内?)
  • Reference - 引用性 / 耦合性 (代码是否引用了一些不受其直接控制的外部因素,由这些外部因素所引入的前置条件或后置条件所造成的影响是否符合预期?)
  • Existence - 存在性 (值是否存在(例如:非 null,非零,存在于某个集合中等)? )
  • Cardinality - 基数性 : 计数性 (是否恰好有足够的值?(重点关注 0-1-n 原则,问题往往发生在这三个边界上。))
  • Time - 时间性(绝对时间及相对时间)- (所有事情是否按顺序发生?是否在正确的时间?是否及时?)

结束语

从单元测试的基本概念可以看出来,更多的情况下,并没有严格意义上的定义,更应该坚持原则,看清形势,找到最适合项目团队的。

TDD也可以简单的看作基于单元测试,所采用的敏捷实践之一,持续改进也是他们不谋而合的地方,也是我推荐TDD的原因之一。

下一篇会以TDD实例从代码实践来讲解因该怎么做TDD。

欢迎更多的讨论,更浩渺的思维!

discussion.jpeg

可通过以下方式联系我们(You can contact us the ways below):


微博
微博

Tweet
Tweet

NPM
NPM

GitHub
GitHub

简书
简书

Youtube
Youtube

优酷
优酷

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 本文结构: 什么是 TDD 为什么要 TDD 怎么 TDD FAQ 学习路径 延伸阅读 什么是 TDD TDD 有...
    李浪溪_WaterLee阅读 72,651评论 16 166
  • 一 当幼稚的小孙儿 看着慈祥的老奶奶 把一枚金黄的太阳 在铁锅里 炒了一番又一番 直到炒起了香烟弥漫的傍晚...
    嗨一休阅读 813评论 1 4
  • 我曾用力走近你 我弹会了小星星 我学做了牛肉饭 我甚至逼迫自己看书只为予你一封情书 可是,可是 怎么你一见他就笑了...
    杨杨杨树子阅读 154评论 0 0