TCR究竟是个什么鬼?
TCR全称test && commit | revert,即执行测试,然后自动提交(测试通过)或者自动回退(测试失败)。该方法由Kent Beck于2018年9月提出:[test && commit | revert](https://medium.com/@kentbeck_7670/test-commit-revert-870bbd756864)。 |
先从TDD说起
TDD(全称为Test-driven development,测试驱动开发)是一种软件开发过程中的应用方法,由极限编程中倡导,以其倡导先写测试程序,然后编码实现其功能得名。测试驱动开发始于20世纪90年代。测试驱动开发的目的是取得快速反馈并使用“illustrate the main line”方法来构建程序。
测试驱动开发是戴两顶帽子思考的开发方式:先戴上实现功能的帽子,在测试的辅助下,快速实现其功能;再戴上重构的帽子,在测试的保护下,通过去除冗余的代码,提高代码质量。测试驱动着整个开发过程:首先,驱动代码的设计和功能的实现;其后,驱动代码的再设计和重构。
上图展示了TDD如何应用于整体功能交付周期。 此图为将设计作为单独的活动。由于编码活动就包含了设计。 实际TDD的一个关键点是:当在设计测试用例或者编写代码时都是在开展设计活动。
由于版本控制软件的普及,TDD逐渐出现了一些变种,例如:由Mike Hill2011年提出将集成也添加到TDD循环中,具体可参见How TDD Works Its Magic(5): Beating A Rhythm
他称其为“四步循环”,该循环体现了持续集成的思想:
- Red:写一个失败的测试用例令代码测试执行失败。
- Green:编写代码使之执行成功。
- Refactor:改变设计,直至代码尽可能简单明了。
- Integrate:将变更(包括新写的测试)提交到源代码管理库。
主要变化点就在Integrate这步上,频繁的集成必须基于频繁的提交。
换个角度看TDD
下面让我们从提交的角度来思考TDD的过程:
从版本N开始,可能的流程是:
- 编写失败的测试,编写代码,测试全过,提交代码
- 重构代码,测试全过,提交代码
进入版本N+1,通过这种方法,红、绿、重构循环导致两次提交,一次用于红绿,第二次用于重构。
如果整个过程不顺利的话,会发生什么呢?
图中虚线表示意外发生时的流程。
情况1:让从“编写测试(预期失败)”开始。如果该测试结果通过,意味着系统意外地已经具有计划添加的行为。这通常意味着两种可能的情况:
- 我们不了解系统的行为
- 我们的测试是错误的,并且没有正确测试预期的新行为
情况2:编写了希望通过测试的生产代码,但是某些测试失败了。这很可能是由于新编写代码是错误的导致。如果是这样,我们可以恢复这些更改(可能通过“撤消”)。
情况3:可能新编写的代码是正确的,而新编写的测试本身有问题。我们可以返回到原始版本N(回到编写测试前的状态)并尝试编写正确的测试 。
情况4:重构导致的测试不过,原因可能是重构实际上改变了行为(由失败的测试检测到)。修复方式还原重构内容,再进行测试。
TCR的方式
TCR同样是一种编写代码的方式,是一种与TDD相关的方法。
如TDD流程图所示,正常的TDD工作流程并非对称的。有时期望测试通过,有时会失败;有时想要提交代码,有时又不想提交代码。
TCR意味着:编写一些测试和(或)代码,然后运行测试。如果测试成功,则提交代码。如果测试失败,则还原代码。通过该方法推进代码的小步提交:没人想由于一个小错误而回退大量代码。流程如下:
相较于TDD,TCR拥有一个非常漂亮且对称的流程,不同的分支其行为均是一致的:
采取行动;如果失败则回退,如果成功则提交。
因此TCR是一个更简单的开发工作流程,驱动开发人员采取小而安全的步骤进行编码。
参考文献
- https://xp123.com/articles/tdd-tcr-commits/
- http://www.cs.unh.edu/~charpov/teaching-cs745_845-example.html
- http://jbazuzicode.blogspot.com/2014/09/getting-started-in-legacy-code.html
- http://arlobelshee.com/
- https://www.youtube.com/watch?v=aWiwDdx_rdo
- http://wiki.c2.com/?TestDrivenDevelopment
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!