单元测试和测试驱动开发之间的区别


64

通过阅读说明,我了解到在TDD中测试是在编写函数之前完成的,而在单元测试中则是在编写函数之后进行的。

这是主要区别吗,还是两个术语不能这样比较。也许,单元测试是TDD不可或缺的一部分。

Answers:


104

单元测试是指什么,你正在测试,TDD您正在测试。

两者是正交的。

单元测试意味着测试行为的单个单元。单个行为单位是可以单独进行测试的最小行为单位。(我知道这两个定义是循环的,但是在实践中它们似乎工作得很好。)

您可以在编写代码之前,编写代码之后或编写代码时编写单元测试。

TDD的意思是(同样,很明显)让您的测试驱动您的开发(和您的设计)。您可以通过单元测试,功能测试和验收测试来做到这一点。通常,您同时使用这三个。

TDD的最重要的部分是中间d。您让测试来驱动您。测试告诉您做什么,下一步做什么。他们告诉您API将会是什么,设计是什么。(这很重要:TDD并不是首先编写测试。很多项目首先编写测试,但不练习TDD。首先编写测试只是能够让测试推动开发的前提条件。)


1
好答案。会增加... TDD是当您让测试推动您并推动开发工作的功能时……
马丁

它们不是正交的。没有单元测试,您将无法拥有TDD。
JacquesB 2015年

1
@JacquesB,为什么?我们的测试不是任何定义的单元测试,它们在很大程度上取决于基础架构和其他组件,但是我们仍然具有足够的可观察性,以至于我们(至少我们中的一些人)正在进行TDD。
AProgrammer 2015年

3
@AndrewWillems:TDD意味着测试可以推动开发。测试不会告诉您设计的外观。测试告诉您,您不必决定下一步要做什么。测试不会告诉您何时结束。完全有可能先编写测试,然后忽略它们告诉您的所有内容。例如,您可以先编写测试,但是即使所有测试都变为绿色,然后再继续编写代码。因此,换句话说:您首先编写测试,但是将它们视为测试,并且不要让它们推动开发。
约尔格W¯¯米塔格

1
@JörgWMittag您可能会以一种纯粹的方式看待它,但是您也知道TDD不是黑白的。对TDD的任何合理使用都不会使测试完全驱动开发,并且测试绝对不能总是决定设计的外观(也许单元测试可以部分地做到这一点,但不能在更高的抽象级别进行测试)。重构呢?这是TDD的一个非常重要的方面。在现实世界中,也没有“忽略测试告诉您的一切”之类的东西。根据定义,如果您首先编写测试,则使用“某种形式的TDD”。
NickL

21

单元测试是测试驱动开发的一部分

您可以进行单元测试,而无需进行测试驱动的开发。但是,如果不使用单元测试,就无法进行测试驱动的开发。

在进行传统的单元测试时,您需要编写代码之后编写测试。

测试驱动的开发方法是编写代码之前先编写单元测试。

与简单的单元测试相比,TDD(IMHO)最有趣的优点是:

  • 代码是经过全面测试的代码。这是无痛的测试。
  • 它迫使您正确设计类。
  • 这也迫使您保持简单愚蠢
  • 红绿重构的循环是绝对的拖延杀手!

您是否故意在陈述中错过了“单元”:“但是,如果不使用测试,就无法进行测试驱动的开发。” ?
ratkok 2011年

@ratkok:不,这不是故意的。我来解决这个问题。

我最喜欢这个定义。用言语比其他答案更好。
Tek

2
可以说,您可以使用模块测试或系统测试而不是真正的单元测试来进行TDD。我不建议这样做,因为如果测试花费的时间太长,您会失去很多好处,但这并不是不可能的。
Toby Speight

13

TDD和单元测试是两个非常具体的术语,经常被滥用。

TDD正在编写将失败的测试,然后编写使它运行所需的最少代码量,然后重构代码以使其干净。这是按周期完成的,失败->通过->重构,为每个已知的代码需求添加新的测试。最近,TDD在该周期中已变得更加具体地涉及编写单元测试,以将其与ATDD(BDD的子集)区分开来,后者是在类似周期中编写验收测试。

单元测试是关于在小的隔离单元中测试代码。这里常见的困惑是认为,如果您使用的是单元测试工具(例如xUnit或Rspec)来运行编写单元测试的测试。这不一定是真的。这些工具可用于使用Selenium框架运行测试,在这种情况下,您将使用单元测试运行程序编写验收测试。单元测试是非常专门的测试,它专注于一小部分逻辑,为了提高速度与其他所有事物隔离开来(以便您可以经常运行它们并获得有关新错误的快速反馈)。


1
用于JUnit本身的JUnit测试就是一个很好的例子:尽管它们是用JUnit编写的,但其中有很大一部分是功能测试和验收测试,而不是单元测试。同样,JUnit的创建者也恰好是TDD的创建者,并且JTD是使用TDD通过大量功能测试和验收测试开发的。验收测试是TDD 不可或缺的一部分。
约尔格W¯¯米塔格

6

TDD是您在开发之前就编写测试用例的方法,然后开发人员编写代码以通过测试用例。单元测试是一个术语,用于描述除系统测试,集成测试和验收测试以外的狭窄范围的测试类型。


3

TDD是一种编写代码的哲学方法:首先编写测试。您编写的测试是单元测试。


1

我将两者分开的方式是考虑到TDD的意义不在于测试,而在于设计代码。然后使用单元测试来设置对最终代码的期望。编写完最终代码并通过测试(规范)后,您就有了使用测试设计的代码。


1

所有出色的答案。我只想补充一点,单元测试倾向于将“单元”视为一个很小的组成部分,而TDD会扩大规模以包括集成和验收测试。

(某些TDD变体将“单位”视为实现所需功能的最小增量步骤。)


他们应该,但是根据我的实际经验,他们不是。公司/团体说,他们做TDD时,他们要做的就是迫使程序员先使用jUnit测试进行测试,然后利用开发过程中已经对所有内容进行测试的事实来消除(或大大减少)质量保证和集成测试。
jwenting 2011年

1
@jwenting不会因为声称实践该方法的缺点而怪罪于该方法。任何工具都可能被滥用
Steven A. Lowe

1
我没有,但是您必须意识到,理论上的TDD与实际上的TDD之间存在很大差异。而且由于大多数人(包括OP)可能只看到了现实,因此应该向他们指出差异。
jwenting 2011年

考虑到TDD与设计有关-为什么要包括验收测试?如何“驱动”设计?
Vitalii Isaenko于

@VitaliiIsaenko验收测试为设计提供了最高级别的范围
Steven A. Lowe
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.