13 个让 TDD 真正发挥作用的步骤






4.71/5 (11投票s)
下面列出了 13 个让 TDD 真正发挥作用的步骤
为什么TDD对你不起作用?
这是一种需要对自己狠一点的情况。测试驱动开发 (TDD) 不起作用是因为你没有这样做。就这么简单。你放弃了TDD,因为它听起来不错,但很难。
什么是 TDD?
从根本上讲,TDD是在编写实现代码之前考虑你的单元测试。当你编写代码时,你可能会首先关注一个快乐路径的最终结果,并编写代码来尝试生成该结果。这会让你对所有可能的结果、所有可能的输入场景以及所有可能出错的事情都闭上眼睛。因此,在TDD中,你首先考虑测试,这样你才不会对超出代码快乐路径的场景视而不见。
TDD有什么吸引人的地方?
当你第一次接触TDD时,你可能会被展示一个类似“hello world”的功能。然后,你被告知如何为它编写测试,然后展示如何编写代码来让你的测试一点一点地通过。这很棒。改进测试的解决方案就是先编写你的测试!你的测试可以通过考虑所有事情而不仅仅是快乐路径来变得更好。这是一个如此简单的概念,你可以做到!没问题。更少的错误意味着更多的时间去做有趣的编码,更少的时间去做支持工作。
那么,你现在为什么不做TDD呢?
你跑到你的项目基础代码中,尝试使用TDD来实现该功能,但它不像那个“hello world”例子那么容易。你的测试需要模拟对象,你必须猜测它们,因为你不确定你将如何实现代码。经过一些挣扎后,你要么放弃了,因为你有一个截止日期,而这很慢,要么你艰难地编写了一些测试,然后开始“真正”的功能编码。在你写了一些真正的代码后,你发现你猜测的测试仍然没有通过,因为你对模拟对象和服务调用的猜测只差一点点,所以你需要修复这些才能让你的某些测试通过。多么令人沮丧!你花了所有的时间先写这些测试,但它们并没有真正增加价值,你也没有“先写你的测试”。所以你放弃了TDD。这很难。它不像你被告知的那样是你问题的解决方案,它所做的只是让你慢下来。
你为什么应该给TDD另一次机会?
因为你正在用困难的方式做,你甚至不知道。做TDD是一种心态,你不会仅仅因为你观看了一次关于它的演示文稿并尝试了一次就发展出来。你被这个概念吸引了,但它的实践很难。TDD不像你被告知的那样是黑白分明的,不是全部或一无所有。
你应该如何进行TDD
- 从Jira、便利贴或其他任何地方获取你的功能任务
- 不要打开你的IDE
- 思考这个功能,并在你的脑海中或在白板上快速设计它
- 写下一些测试场景
- 现在打开你的IDE
- 创建你的“真实代码”类和方法签名
- 创建你的单元测试类
- 创建一个单元测试,但不要编写测试用例,只需将单元测试存根出来,并创建关于你想要涵盖的测试场景的注释(见下例)
- 包括输入和预期结果
- 如果可能,为这些预期结果编写断言语句
- 重复步骤8和9,直到你涵盖了你能想到的所有场景
- 去写你的“真实代码”
- 如果你想到一个新的场景并更新单元测试类以包含它,请偶尔暂停
- 现在填写单元测试以涵盖这些测试场景,包括所有输入、模拟对象,甚至更好的断言语句
- 告诉你的同事你实际上是如何进行TDD的,并且它使你的代码更好
示例存根测试类
public class AdditionHelperTest {
/**
* test basic addition
*
* input: 1, 2
*
* expected: output 3
*
*/
@Test
public void testAdditionHappyPath() {
fail("Not yet implemented");
}
/**
* test null input
*
* input: null, 2
*
* expected: output illegal argument exception
*
*/
@Test
public void testAdditionNullFirstArg() {
fail("Not yet implemented");
}
/**
* test null input
*
* input: 1, null
*
* expected: output illegal argument exception
*
*/
@Test
public void testAdditionNullSecondArg() {
fail("Not yet implemented");
}
/**
* test negative numbers addition
*
* input: 1, -2
*
* expected: output -1
*
*/
@Test
public void testAdditionNegative() {
fail("Not yet implemented");
}
/**
* test addition large numbers
*
* input: Integer.MAX_VALUE, Integer.MAX_VALUE
*
* expected: exception
*
*/
@Test
public void testAdditionLargeNumbers() {
fail("Not yet implemented");
}
}
下一步?
当你越来越擅长思考TDD时,你可能能够为某些功能先创建更多的测试代码,并且你将更快地生成这些测试场景。你的代码中会减少错误。然后你将有更多的时间来做有趣的新开发,并减少做无聊的生产支持的时间。
其他测试魔术