专栏首页ThoughtWorksTW洞见 | 用TDD影响设计

TW洞见 | 用TDD影响设计

在听过Martin Fowler、Kent Beck和DHH关于TDD的讨论以后,我想也把我关于TDD的想法记录下来——我为什么要遵从它,以及为什么我会发现它做为一种思考过程,在解决设计问题的时候特别有帮助。

直到我完全理解了用户案例(也即测试案例)之前,我无法设计或者编写生产代码。因此,我从思考用户案例开始,我为它编写代码。现在这样的思考方式本身对我来说,就是“测试驱动”的。并且基于已经确认的测试案例,我开始仔细考虑我的设计。我需要在运行代码前编写测试代码;为了确认我的代码能工作,我需要测试它。

While building test cases on the whiteboard or as pending test cases, I identify the design patterns to be implemented. Now should I start writing my test and code, without design pattern abstraction and refactor to the desired design pattern, or jump directly into defining classes and tests using my desired design pattern? Both approaches work for me. I like to start small, so I write my first test case and write code to implement that. However, sometimes I like thinking of design upfront to avoid immediate test cases implementation rework, but will not code for it. And so I draft my test cases with the design already in mind.

Lots of times I don’t have a clue, can’t think of abstraction and design upfront, in that case starting flat is good. And after implementation of a few test cases, my code starts shaping up and I get more insight to find better abstractions. Sometimes it is difficult to write tests without even having a ‘code structure skeleton’ in place. Even though I feel drafting a ‘code structure skeleton’ is OK at times, you can avoid it by avoiding doing a 1-1 mapping of your “test class” with your “code class”. TDD also helps me with good naming, because I started with the use-case. Since I code the client (call) first, that helps me in naming it from the usage perspective and not from implementation perspective.

To get the most out of TDD, don’t be too dogmatic about its implementation; instead use it as a technique to influence the way you design. For instance, TDD is really helpful in identifying smells in design. I have seen code all test driven, but full of switch case constructs without abstractions, which entirely misses the point of TDD. In my view, if I am following TDD, it does not mean my design is good, but rather I should use it as a technique to drive my design. Here are few obvious TDD test smells that help me identify bad design,

  • Difficulty in writing tests: Especially when there are too many dependencies that require too much setup code. In the Rails world for example - ‘Fat Controllers’ without services or helper classes.
  • Excess tests for a single unit: This happens when classes have too much responsibility. In the Rails world, the example would be ‘Fat Models’.
  • Excess assertions: This happens when one method is doing too many things or tests are written at the wrong level. One test is trying to test too many things at once.
  • Excess tests for a component: While the individual tests are very fast, it takes very long to run all tests. This may be an architectural smell of a monolithic application. Break it down into small components. On my last project we had the UI as a separate repo with only Views (templates), CSS and JS, including unit tests for Views and JavaScript.
  • Cascading effects of code modification on unrelated tests: This is the case when a change in code, leads to changes required in other unrelated tests. This happens due to unnecessary mocking or testing at the wrong level. For example a change in the code for the model requires changes in the controller tests without any of the controller code having changed.

Practicing TDD also helps me with slicing and dicing stories, because TDD is a technique that helps one think of the minimal use-case that should be implemented to get started.

What are your thoughts on using TDD?

本文分享自微信公众号 - 思特沃克(ThoughtWorks),作者:Sunit

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2015-01-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • TW洞见 | 改善结对编程体验的十个办法

    从专业和个人的角度出发,你上次体验到既高效又很有收获的结对编程是什么时候的事了?我们也很想知道,为什么很多次我们有一些特殊的结对体验并不是我们预期的那样愉快和有...

    ThoughtWorks
  • TW Insight - Good Practices to Build Your AngularJS Application

    这是来自ThoughtWorks巴西团队分享的一些使用AngularJS的一些技巧和教训。经验内容包括结构、依赖注入、HTML扩展、作用域和模块。这是2014年...

    ThoughtWorks
  • TW洞见 | 敏捷回顾7步法

    Paulo和TC一直在收集整理关于敏捷回顾的任何想法和活动。在这篇内容里面,他们分享了7步法来帮助你组织你的下一次回顾。 Agenda structure: 1...

    ThoughtWorks
  • python实现感知机

    感知机是二类分类的线性分类模型,其输入为实例的特征向量,输出为实例的类别,取+1和-1二值。感知机对应于输入空间中将实例划分为正负两类的分离超平面,属于判别模型...

    绝命生
  • OpenStack in containers

    image.png 目前OpenStack官方项目里,有两个是通过容器来部署OpenStack,Rackspace主导的OpenStack-ansible 和K...

    首席架构师智库
  • WPF TreeView SelectedItemChanged called twice

    How to avoid WPF TreeView SelectedItemChanged being called twice Very often, we...

    hbbliyong
  • kafka Disks and Filesystem(磁盘和文件系统)

    转载请注明来源地址:http://www.cnblogs.com/dongxiao-yang/p/5206631.html

    sanmutongzi
  • 叙事与需求:使用推特话语的分析气旋“安潘”的经验

    人们往往通过社交媒体来评论并分享有关全球重要事件的信息。因此,社交媒体因其作为了解人们对于极端天气事件的社会、政治和经济经验的丰富数据来源而愈发受到关注。在本篇...

    用户7724216
  • 【CodeForces 599A】D - 特别水的题4- Patrick and Shopping

    Today Patrick waits for a visit from his friend Spongebob. To prepare for the vi...

    饶文津
  • 常用正则表达式

      这些正则皆为日常开发总结,一般常用的都用,来源有来自自己总结的,还有的是从网上记录下来的,希望对大家有个帮助,完好正则提高程序性能!

    追逐时光

扫码关注云+社区

领取腾讯云代金券