測試驅動開發 測試前移_為什么測試驅動的開發有用?

測試驅動開發 測試前移

有關如何更有效地應用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.

謝謝閱讀。 如果您有任何反饋意見,請通過Twitter , Facebook或Github與我聯系。

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

測試驅動開發 測試前移

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/396027.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/396027.shtml
英文地址,請注明出處:http://en.pswp.cn/news/396027.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Anaconda管理多版本的python環境

通過Conda的環境管理功能,我們能同時安裝多個不同版本的Python,并能根據需要自由切換。下面我將給大家分享一下,新增Python版本,切換,再切回主版本的詳細過程。 方法/步驟 1首先確保你的系統里已經安裝了Conda&#xf…

父子滬c轉大牌過戶_機動車異地過戶(轉籍)

最近我家換了一輛車,導航后臺數據統計是去足浴城最多的車主,尬!從想起這個品牌到付定金,也就半天時間,買之前沒了解這么透徹。不過,到手駕駛,還是比之前的車舒適很多的,就是容易在不…

android安卓系統2.3 使用說明書,Android2.3操作界面

Android2.3操作界面摩托羅拉XT882的界面相對于原生的Gingerbread還是有了不小的變化,首先最大的感覺就是主色調亮了很多。默認背景在qHD分辨率下非常的清晰,同時整個界面仍然采用了多分屏界面。下方由中國電信定制,狀態欄加入了全新的單個狀態…

《運營力——微信公眾號 設計 策劃 客服 管理 一冊通》一一1.2 團隊崗位介紹...

本節書摘來自異步社區出版社《運營力——微信公眾號 設計 策劃 客服 管理 一冊通》一書中的第1章,第1.2節,作者: 杭州創博通信技術有限公司 , 施瑤君,更多章節內容可以訪問云棲社區“異步社區”公眾號查看。 1.2 團隊崗位介紹 創…

一切都是關于“ –ilities”的

by George Stepanek通過喬治斯蒂芬內克 都是關于“邪惡”的 (It’s all about the “-ilities”) We were “feature complete.”我們“功能齊全”。 Four weeks into a 10-week Free Code Camp project to build an environmental pledge web application, we had gotten al…

1,滑動驗證,前后臺接口

http://www.geetest.com/install/sections/idx-client-sdk.html 轉載于:https://www.cnblogs.com/yexiangwang/p/5481153.html

Linux 下 nginx反向代理與負載均衡

前面幾篇記錄下nginx的基本運功,代理服務器的訪問,這里來試驗下nginx的反向代理。 反向代理(Reverse Proxy)方式是指以代理服務器來接受internet上的連接請求,然后將請求轉發給內部網絡上的服務器,并將從服…

android 8.1沒聲音,Android 8.1重大改變!耳機孔不見了

原標題:Android 8.1重大改變!耳機孔不見了今天上午,Android Police爆料稱,下一代的Pixel 2將首發Android 8.1。更重要的是,在這個新系統中,谷歌已經做好了放棄3.5mm耳機插口的準備,并將在底層優…

php變量前下滑_PHP變量

變量來源于數學,是計算機語言中能儲存計算結果或能表示值抽象概念。變量可以通過變量名訪問。變量是存儲數據的“容器”。命名規則變量以 $ 符號開始,后面跟著變量的名稱變量名必須以字母或者下劃線字符開始變量名只能包含字母數字字符以及下劃線(A-Z、a…

《計算機科學概論(第12版)》—第0章0.3節學習大綱

本節書摘來自異步社區《計算機科學概論(第12版)》一書中的第0章0.3節學習大綱,作者【美】J. 格倫?布魯克希爾(J. Glenn Brookshear) , 丹尼斯?布里羅(Dennis Brylow),更多章節內容可以訪問云棲…

blued停止郵箱注冊_停止讓我注冊!

blued停止郵箱注冊by Conor Sheehan由Conor Sheehan 停止讓我注冊! (Stop Making Me Sign Up!) Installing a new app can be exciting. When you’ve found one that may be just what you need, opening it is like unboxing a new toy. So why do so many apps …

Android Sutido 編譯速度優化

雖然Android Studio 此時已經更新到了Android Studio 2.1版本,build 版本android-studio-bundle-143.2739321。但是在安裝該版本都是根據自己的標準進行安裝,所以需要在安裝之后進行一系列的調整。下面文章根據3個方面進行講解。分別為Android Studio本身…

卷積神經網絡計算題試題_卷積神經網絡的計算

轉自:https://zhuanlan.zhihu.com/p/631747741. 卷積卷積神經網絡中的卷積是指定義好卷積核(kernel),并對圖像(或者特征圖,feature map)進行滑動匹配,即對應位置相乘再相加。其特點就在于能夠捕捉局部的空間特征。具體過程如下圖所…

html字符串轉換jsx,javascript – 將React.element轉換為JSX字符串

我正在嘗試構建一個組件,>帶孩子和>渲染DOM中的子項,以及>出于文檔的目的,在pre中顯示子DOM一種解決方案是將JSX作為單獨的prop傳遞.這使得它重復,因為我已經能夠通過this.props.children訪問它.理想情況下,我只需要以某種方式將子prop轉換為字符串,以便我可以在pre中…

Leetcode:0002(兩數之和)

LeetCode:0002(兩數之和) 題目描述:給定兩個非空鏈表來表示兩個非負整數。位數按照逆序方式存儲,它們的每個節點只存儲單個數字。將兩數相加返回一個新的鏈表。你可以假設除了數字 0 之外,這兩個數字都不會…

《Excel 職場手冊:260招菜鳥變達人》一第 13 招 利用數據驗證給單元格添加注釋,不用批注...

本節書摘來異步社區《Excel 職場手冊:260招菜鳥變達人》一書中的第1章,第13節,作者: 聶春霞 , 佛山小老鼠 責編: 王峰松,更多章節內容可以訪問云棲社區“異步社區”公眾號查看。 第 13 招 利用數據驗證給單…

招銀網絡筆試java_春招|招銀網絡Java軟件開發 電話面試+一二三面面經

電話面試:1.自我介紹2.介紹項目經歷(我介紹的時候說了用到spring,spring MVC和hibernate框架)3.為什么用spring框架,有什么優點4.詳細說下aop5.解釋下IOC,IOC有什么好處6.spring MVC的運行流程7.spring除了注解注入還有什么方式8.hibernate框…

Numpy and Pandas

安裝 視頻鏈接:https://morvanzhou.github.io/tutorials/data-manipulation/np-pd/ pip install numpy pip install pandas Numpy 學習 Numpy屬性 import numpy as nparray np.array([[1,2,3],[2,3,4]]) print(array) print(number of dim:,array.ndim)//幾維度 pr…

認證android retrofit,Retrofit之項目介紹

項目介紹官網對retrofit介紹是這是一個"類型安全(type-safe)"的Android/Java http客戶端. 目前retrofit的最新正式版本為1.9.0. 2.0版本預計2015年底發布, 相較于之前版本, 2.0版本在架構上做了很大改變, 本文代碼相關的內容都是基于retrofit2.0-beta2.注: 在編程語言…

層次聚類算法 算法_聚類算法簡介

層次聚類算法 算法Take a look at the image below. It’s a collection of bugs and creepy-crawlies of different shapes and sizes. Take a moment to categorize them by similarity into a number of groups.看看下面的圖片。 它是各種形狀和大小的錯誤和令人毛骨悚然的爬…