測試驅動開發 測試前移
有關如何更有效地應用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/
測試驅動開發 測試前移