← 返回目录

测试先行

第 59 / 119 卷日期:

我自己造的一些轮子中使用TDD。因为这个花费大量的时间,通常来说测试代码和功能代码的比例可能是 1:1,或者是 2:1 等等。在自己创建的一些个人应用,如博客中,我

不需要与其他人 Share 我的 Content。由于我使用的是第三方框架,框架本身的测试已经足够多,并且没有复杂的逻辑,我就没有对我的博客写测试。而在我写的一些框架里,

我就会尽量保证足够高的测试覆盖率,并且在适当的时候会去 TDD。

通常来说对于单元测试我会采用 TDD 的方式来进行,但是功能测试仍会选择在最后添加进去。主要的缘由是:在写 UI 的过程中,元素会发生变化。这一点和我们在写

Unit 的时候,有很大的区别。div + class 会使得我们思考问题的方式发生变化,我们需要去点击某个元素,并观察某个元素发生的变化。而多数时候,我们很难把握好一个页

面最好的样子。

不得不说明的一点是,TDD需要你对测试比较了解后,你才容易使用它。从个人的感受来说,TDD 是在一开始是一件很难的事。

测试先行

对于写测试的人来说,测试先行有点难以理解,而对于不写测试的人来说,就更难以理解。这里假定你已经开始写测试了,因为对于不写测试的人来说,写测试就是一件

难以理解的事。既然我们都要写测试,那么为什么我们就不能先写测试呢?或者说为什么后写测试存在一些问题?

依据 J.Timothy King 所总结的《测试先行的 12 个好处》:

  1. 测试可证明你的代码是可以解决问题的
  2. 一面写单元测试,一面写实现代码,这样感觉更有兴趣
  3. 单元测试也可以用于演示代码
  4. 会让你在写代码之前做好计划
  5. 它降低了 Bug 修复的成本
  6. 可以得到一个底层模块的回归测试工具
  7. 可以在不改变现有功能的基础上继续改进你的设计
  8. 可以用于展示开发的进度
  9. 它真实的为程序员消除了工作上的很多障碍
  10. 单元测试也可以让你更好的设计
  11. 单元测试比代码审查的效果还要好
  12. 它比直接写代码的效率更高

但是在我个人的感觉里,多比较喜欢的是:写出可以测试的函数。这是一个一直困

越来越大。当我只有一个简单的 IF-ELSE 的时候,我的代码测试起来也很简单:

if (hour < 18) { greeting = "Good day";

} else { greeting = "Good evening";

}

而当我有复杂的业务逻辑时,后写测试就会变成一场恶梦:

if (EchoesWorks.isObject(words)) { var nextTime = that.parser.parseTime(that.data.times)[currentSlide + 1];

if (that.time < nextTime && words.length > 1) { var length = words.length;

var currentTime = that.parser.parseTime(that.data.times)[currentSlide] var time = nextTime - currentTime;

var average = time / length * 1000;

var i = 0;

document.querySelector('words').innerHTML = words[i].word;

timerWord = setInterval(function () { i++;

if (i - 1 === length) { clearInterval(timerWord);

} else { document.querySelector('words').innerHTML = words[i].word;

} }, average);

} return timerWord;

} else { document.querySelector('words').innerHTML = words;

}

我们需要重新理清业务的逻辑,再依据这些逻辑来编写测试代码。而当我们已经忘记具体的业务逻辑时,我们已然无法写出测试。

全站分卷索引 · 119 卷
  1. 1Growth: 全栈增长工程师指南
  2. 2软件开发的核心难题:沟通
  3. 3大公司的专家与小公司的全栈
  4. 4全栈工程师的未来:无栈
  5. 5基础知识篇
  6. 6工具只是辅助
  7. 7语言也是一种工具
  8. 8提高效率的工具
  9. 9IDE
  10. 10终端或命令提示符
  11. 11包管理
  12. 12环境搭建
  13. 13Windows
  14. 14GNU/Linux
  15. 15学好一门语言的艺术
  16. 16输出是最好的输入
  17. 17如何应用一门新的技术
  18. 18Web 编程基础
  19. 19从 HTML 到页面显示
  20. 20HTML
  21. 21中文?
  22. 22其他 HTML 标记
  23. 23小结
  24. 24CSS
  25. 25简介
  26. 26样式与目标
  27. 27更有趣的 CSS
  28. 28JavaScript
  29. 29JavaScriptFul
  30. 30面向对象
  31. 31其他
  32. 32前端与后台
  33. 33后台语言选择
  34. 34PHP
  35. 35Model
  36. 36View
  37. 37Controller
  38. 38后台即服务
  39. 39后台即服务
  40. 40数据库
  41. 41搜索引擎
  42. 42前端框架选择
  43. 43前台与后台交互
  44. 44JSON
  45. 45WebSocket
  46. 46编码过程
  47. 47Web 应用的构建系统
  48. 48Web 应用的构建过程
  49. 49Web 应用的构建实战
  50. 50Git 与版本控制
  51. 51Tasking
  52. 52Tasking 开发任务
  53. 53写代码只是在码字
  54. 54内置索引与外置引擎
  55. 55内置索引与外置引擎
  56. 56如何测试
  57. 57测试替身
  58. 58Mock
  59. 59测试先行
  60. 60可读的代码
  61. 61命名
  62. 62函数长度
  63. 63代码重构
  64. 64提炼函数
  65. 65内联函数
  66. 66查询取代临时变量
  67. 67重构到设计模式
  68. 68上线
  69. 69隔离硬件:虚拟机
  70. 70隔离操作系统:容器虚拟化
  71. 71隔离底层:Servlet 容器
  72. 72隔离依赖版本:虚拟环境
  73. 73隔离语言:DSL
  74. 74GNU/Linux
  75. 75HTTP 服务器
  76. 76数据库端缓存
  77. 77前端缓存
  78. 78运行机制
  79. 79自动化部署
  80. 80依赖与包仓库
  81. 81构建软件包
  82. 82数据分析
  83. 83想法-构建
  84. 84产品-衡量
  85. 85数据分析
  86. 86分析数据
  87. 87用户数据分析:Google Analytics
  88. 88流量获取
  89. 89移动应用
  90. 90网站性能
  91. 91SEO
  92. 92什么样的网站需要 SEO?
  93. 93内容
  94. 94UX 入门
  95. 95什么是简单?
  96. 96进阶
  97. 97认知设计
  98. 98持续交付
  99. 99持续集成系统
  100. 100持续交付
  101. 101持续部署
  102. 102持续阅读
  103. 103遗留系统与修改代码
  104. 104遗留代码
  105. 105修改遗留代码
  106. 106速度优化
  107. 107模块重构
  108. 108Retro
  109. 109三个维度
  110. 110架构模式
  111. 111预设计式架构
  112. 112演进式架构:拥抱变化
  113. 113意图导向
  114. 114重构
  115. 115模式与演进
  116. 116相关阅读资料
  117. 117架构解耦
  118. 118CQRS
  119. 119CQRS 结合微服务