测试驱动开发 测试前移_为什么测试驱动的开发有用?

测试驱动开发 测试前移

有关如何更有效地应用TDD的技巧,以及为什么它是一种有价值的技术 (Tips on how to apply TDD more efficiently, and why it's a valuable technique)

There's a common pattern we follow when we start a project using TDD. We describe the specifications of what we expect the system to do in the form of a special test. This "special test" can be an end-to-end with the front-end or an integration test that executes an HTTP request to test the back-end.

当使用TDD启动项目时,我们遵循一种常见的模式。 我们以特殊测试的形式描述了我们期望系统执行的操作的规范。 此“特殊测试”可以是前端的端到端,也可以是执行HTTP请求以测试后端的集成测试。

It's the first test we write. We do it before a single line of code is written. That special test will serve as a guideline to make sure we don't break anything that prevents the regular flow from working. If we don't do that and rely solely on unit tests, there's a chance that, eventually, we will have all tests passing but the server will not be starting or the user won’t be able to do anything on the screen.

这是我们编写的第一个测试。 我们在编写一行代码之前就完成了。 该特殊测试将作为准则,以确保我们不会破坏任何阻止常规流程正常运行的内容。 如果我们不这样做,而仅依靠单元测试,则最终有机会通过所有测试,但服务器将无法启动,否则用户将无法在屏幕上执行任何操作。

When starting a project using TDD, there's a common pattern to create a special test to make sure we don’t break anything that prevents the regular flow from working.
使用TDD启动项目时,通常会使用一种模式来创建特殊测试,以确保我们不会破坏任何妨碍正常流程正常工作的内容。

After we make that special test pass with a naive implementation (or we can keep it failing if we are using ATDD to drive the application internals), we start building the units of the system using a similar pattern on a micro level, never breaking any test we created earlier. We describe each unit of the system through a failing test and make it pass with a naive implementation first. Then, we identify smells and refactor it if necessary so that we can keep the cycle going over and over again.

在通过幼稚的实现使特殊测试通过之后(或者如果我们使用ATDD来驱动应用程序内部,我们可以使其保持失败),我们开始在微观级别上使用类似的模式来构建系统的单元,而不会破坏任何单元我们之前创建的测试。 我们通过失败的测试描述系统的每个单元,并使其首先通过幼稚的实现。 然后,我们识别气味并在必要时对其进行重构 ,以便使循环不断进行。

That’s called the Red/Green/Refactor cycle of TDD.

这称为TDD红色/绿色/重构周期

This cycle will drive us to build all the pieces of our application with enough confidence that it will be robust and maintainable. It will also expose problems early if we were to get stuck due to the wrong assumption of how the API is supposed to behave.

这个周期将驱使我们以足够的信心来构建应用程序的所有部分,以确保其健壮和可维护。 如果由于错误地假设API的行为而使我们陷入困境,它也会尽早暴露出问题。

There's one important thing we should be careful about: we should avoid refactoring code or adding a new test while another test is failing. If we do that, there's a high chance we will get stuck because of the unnecessary cognitive load of worrying about another rule we have already covered. To prevent that, we need to fix the failing test before starting anything else.

我们应该注意一件事: 在另一个测试失败时,我们应该避免重构代码或添加新测试。 如果这样做,很有可能由于担心我们已经涵盖的另一条规则而不必要的认知负担而陷入困境。 为防止这种情况,我们需要在开始任何其他操作之前先修复失败的测试。

In TDD, we should avoid refactoring code or adding a new test while another test is failing.

在TDD中,我们应该避免在另一个测试失败时重构代码或添加新测试。

There are circumstances where one would prefer writing tests after writing the code. However, there are some negative effects that come with that approach:

在某些情况下,人们更愿意在编写代码后编写测试。 但是,这种方法会带来一些负面影响:

  • We can miss important functionality because it’s harder to know if the coverage matches our expectation.

    我们可能会错过重要的功能,因为很难知道覆盖范围是否符合我们的期望。
  • It can create false positives because we won’t see a failing test first.

    它会产生误报,因为我们不会首先看到失败的测试。

  • It can make us over-engineer the architecture because we won’t have any guidelines to force us to write the minimum amount of code that fits in our most basic requirements.

    它可能使我们架构进行过度设计 ,因为我们没有任何准则可以迫使我们编写满足我们最基本要求的最少代码量。

  • It's harder to validate if the message for the failing test is clear and pointing to the cause of that failure or not.

    很难验证失败测试的消息是否清晰并指出失败的原因。

One thing to keep in mind is that TDD can be posed as a discipline, but there's no way to create a discipline for writing tests after the production code.

要记住的一件事是,可以将TDD视为一门学科,但是无法创建一种在生产代码之后编写测试的学科

There are cases when there's no value in applying TDD or automated testing at all. It's when we're testing some IO layers, support functions for the tests, or things built using a declarative language like HTML or CSS (we can test the visual in CSS, but not the CSS code). However, testing is a fundamental part of the process that ensures a complex piece of functionality satisfies a set of expectations. That alone allows us to be confident enough that each part of the system works as expected.

在某些情况下,应用TDD或自动测试根本没有价值 。 是在测试某些IO层,测试的支持功能或使用声明性语言(如HTML或CSS)构建的东西的时候(我们可以在CSS中测试外观,但不能测试CSS代码)。 但是,测试是该过程的基本部分,可确保复杂的功能满足一系列期望。 仅凭这一点,我们就足以确信系统的每个部分都能按预期工作。

There are cases when there's no value in applying TDD or automated testing at all, like when testing IO layers, support functions for the tests, or code written with a declarative language.
在某些情况下,应用TDD或自动测试根本没有价值,例如在测试IO层,测试的支持功能或使用声明性语言编写的代码时。

There's a concept called The Transformation Priority Premise. The TL;DR is that there are some transformations we can apply when making the code more generic in the "green" phase of the TDD cycle.

有一个概念称为“转换优先级前提”TL; DR是在使代码在TDD周期的“绿色”阶段更加通用时可以应用一些转换。

"Refactor" is when we change the structure of the code without changing its behavior. The Transformations are not called "refactoring" because they change the structure and the behavior of the code to make it more generic.

重构 ”是指我们在不更改代码结构的情况下更改其结构。 转换不称为“ 重构 ”,因为它们会更改代码的结构和行为以使其更通用。

An example of using the Transformation Priority is when we make a test that forces us from returning a single constant to returning an argument that will contain more than one value. In this case, it's the constant->scalar priority transformation.

使用转换优先级的一个示例是,当我们进行测试以迫使我们从返回单个常量到返回将包含多个值的参数时。 在这种情况下,这是常量->标量优先级转换。

So what are these transformations? Perhaps we can make a list of them:

那么这些转换是什么? 也许我们可以列出它们:

So what are these transformations? Perhaps we can make a list of them:

那么这些转换是什么? 也许我们可以列出它们:

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant)

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant)

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)用变量或参数替换常量

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)用变量或参数替换常量

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)将常量替换为变量或参数 *(statement-> statements)添加更多无条件语句。

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)根本没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)用变量或参数替换常量 *(statement-> statements)添加更多无条件语句。

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)用变量或参数替换常量 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)将常量替换为变量或参数 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)将常量替换为变量或参数 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径 *(标量->数组)

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)用变量或参数替换常量 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径 *(标量->数组)

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)* (array->container)

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)将常量替换为变量或参数 *(statement-> statements)添加更多无条件语句。 *(无条件->如果)分割执行路径 *(标量->数组) *(数组->容器)

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)* (array->container)

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)将常量替换为变量或参数 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径 *(标量->数组) *(array->容器)

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)* (array->container)* (statement->recursion)

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)将常量替换为变量或参数 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径 *(标量->数组) *(数组->容器) *(语句->递归)

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)* (array->container)* (statement->recursion)

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)将常量替换为变量或参数 *(statement-> statements)添加更多无条件语句。 *(无条件->如果)分割执行路径 *(标量->数组) *(数组->容器) *(语句->递归)

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)* (array->container)* (statement->recursion)* (if->while)

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)用变量或参数替换常量 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径 *(标量->数组) *(array->容器) *(语句->递归) *(if-> while)

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)* (array->container)* (statement->recursion)* (if->while)

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)将常量替换为变量或参数 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径 *(标量->数组) *(array->容器) *(语句->递归) *(if-> while)

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)* (array->container)* (statement->recursion)* (if->while)* (expression->function) replacing an expression with a function or algorithm

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)用变量或参数替换常量 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径 *(标量->数组) *(array->容器) *(语句->递归) *(if-> while) *(表达式->函数)用以下表达式替换表达式函数或算法

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)* (array->container)* (statement->recursion)* (if->while)* (expression->function) replacing an expression with a function or algorithm

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)用变量或参数替换常量 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径 *(标量->数组) *(array->容器) *(语句->递归) *(if-> while) *(表达式->函数)用函数或算法

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)* (array->container)* (statement->recursion)* (if->while)* (expression->function) replacing an expression with a function or algorithm* (variable->assignment) replacing the value of a variable.

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)用变量或参数替换常量 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径 *(标量->数组) *(array->容器) *(语句->递归) *(if-> while) *(表达式->函数) 替换变量值的 函数或算法 *(变量->赋值)

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)* (array->container)* (statement->recursion)* (if->while)* (expression->function) replacing an expression with a function or algorithm* (variable->assignment) replacing the value of a variable.

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)用变量或参数替换常量 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径 *(标量->数组) *(array->容器) *(语句->递归) *(if-> while) *(表达式->函数)用以下表达式替换表达式 替换变量值的 函数或算法 *(变量->赋值)

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)* (array->container)* (statement->recursion)* (if->while)* (expression->function) replacing an expression with a function or algorithm* (variable->assignment) replacing the value of a variable.There are likely others.

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)用变量或参数替换常量 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径 *(标量->数组) *(array->容器) *(语句->递归) *(if-> while) *(表达式->函数) 替换变量值的 函数或算法 *(变量->赋值) 可能还有其他人。

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)* (array->container)* (statement->recursion)* (if->while)* (expression->function) replacing an expression with a function or algorithm* (variable->assignment) replacing the value of a variable.There are likely others.

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)根本没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)用变量或参数替换常量 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径 *(标量->数组) *(array->容器) *(语句->递归) *(if-> while) *(表达式->函数)用以下表达式替换表达式 替换变量值的 函数或算法 *(变量->赋值) 可能还有其他人。

So what are these transformations? Perhaps we can make a list of them:* ({}–>nil) no code at all -> code that employs nil* (nil->constant)* (constant->constant+) a simple constant to a more complex constant* (constant->scalar) replacing a constant with a variable or an argument* (statement->statements) adding more unconditional statements.* (unconditional->if) splitting the execution path* (scalar->array)* (array->container)* (statement->recursion)* (if->while)* (expression->function) replacing an expression with a function or algorithm* (variable->assignment) replacing the value of a variable.There are likely others.— Excerpt from The Transformation Priority Premise article

那么这些转换是什么? 也许我们可以列出它们: *({} –> nil)完全没有代码->使用nil的代码 *(nil-> constant) *(constant-> constant +)从简单常量到更复杂的常量 * (constant-> scalar)将常量替换为变量或参数 *(statement-> statements)添加更多无条件语句。 *(无条件-> if)分割执行路径 *(标量->数组) *(array->容器) *(语句->递归) *(if-> while) *(表达式->函数)用以下表达式替换表达式 替换变量值的 函数或算法 *(变量->赋值) 可能还有其他人。 —摘自《转型优先前提》一

In TDD, The Transformation Priority Premise can give us a guideline for the "green" phase.
在TDD中,“转换优先级前提”可以为我们提供“绿色”阶段的指导。

Writing correct software is hard. TDD is a common pattern where we use the tests to help driving the implementation of our system while retaining a huge percentage of test coverage. However, it's not a Silver Bullet.

编写正确的软件非常困难 。 TDD是一种常见的模式,在这种模式下,我们使用测试来帮助推动系统的实施,同时保留很大比例的测试覆盖率。 但是,它不是Silver Bullet

If we are using TDD, we should avoid refactoring the code when the tests are failing. To make it pass in the "green" phase, we use the Transformation Priority Premise to guide us in the most naive implementation approach we can take before refactoring.

如果使用的是TDD,则应在测试失败时避免重构代码。 为了使其通过“绿色”阶段,我们使用“转换优先级前提”来指导我们采用重构之前可以采取的最幼稚的实施方法。

In comparison with other ways of writing tests, TDD can take more time in the beginning. However, as with every new skill, with enough practice we will reach a plateau, and the time it takes to apply TDD will be no different than the time it would take to write tests in a traditional way.

与其他编写测试的方式相比,TDD在开始时可能会花费更多时间。 但是,与每一项新技能一样,如果有足够的实践,我们将达到一个平稳阶段,并且应用TDD所花费的时间与以传统方式编写测试所花费的时间没有什么不同。

The difference now is that your software will be less likely to behave in a way you didn't expect.

现在的区别是您的软件将不太可能以您未曾期望的方式运行。

And for all practical means, that's no different than 100% test coverage.

对于所有实际方法,这与100%的测试覆盖率没有什么不同。

Thanks for reading. If you have some feedback, reach out to me on Twitter, Facebook or Github.

谢谢阅读。 如果您有任何反馈意见,请通过TwitterFacebookGithub与我联系。

翻译自: https://www.freecodecamp.org/news/why-test-driven-development-4fb92d56487c/

测试驱动开发 测试前移

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值