PHPUnit袖珍指南 第十二章 測試的其他用途

 
一旦你開始寫自動測試,你就會想要發掘更多用途。以下是一些例子。
 
12-1. 敏捷文檔
通常來說,在採用敏捷方法作爲開發流程的項目中,如極限編程,文檔很難和迅速變化的項目設計和代碼同步。極限編程要求集體擁有代碼,應此,每個開發人員都熟悉整個系統。如果你嚴格按照規定,編寫的類具有自說明能力,你就可以用PHPUnit的TextDox功能根據測試來自動生成文檔。這種文檔給開發人員對每個類的用途描繪了一個概貌。
 
PHPUnit的TestDoc功能查找測試類的所有方法的名字,把它們轉換成句子,如:testBalanceIsInitiallyZero( )變成“Balance is initially zero。”如果有幾個測試方法名字的不同只在於前綴或數字,如testBalanceCannotBecomeNegative( ) 和 testBalanceCannotBecomeNegative2( ),轉換過的句子“Balance cannot become negative”只會出現一次,其他這樣的測試都會成功。
 
以下代碼顯示用PHPUnit 生成的關於銀行帳號(Bank Account)類的敏捷文檔,命令是:
phpunit --testdox-text BankAccountTest.txt BankAccountTest
結果顯示:
BankAccount
 - Balance is initially zero
 - Balance cannot become negative
 
也可以用--testdox-html BankAccountTest.htm選項生成HTML格式的敏捷文檔。
 
敏捷文檔也用以用於爲項目中的第三方包的假定條件來記錄文檔。當你使用一個外部包的時候,你也在冒一定的風險。外部包可能不想你預期的那樣工作,或在未來版本中有微妙變化,導致你的代碼不可運行。你也通過對外部包的假定條件編寫測試來解決這個問題。如果你的測試成功了,你的假定條件還是有效。如果你對所有假定條件的測試都作了文檔,那麼,外部包的版本問題將不再是個問題:如果測試成功了,你的系統還會正常運行。
 
 
12-2.跨團隊測試
當你將測試的假定條件文檔化後,你就要爲你的測試負責。你和包的提供者一起確定這些假設,你要記住,包的提供者對你的測試一無所知。如果你想要與包的提供者形成更密切的關係,你可以使用測試來溝通協調相關活動。
當你同意和包的供應商協調活動時, 你們可以一起寫測試。 這樣做,測試會顯露出儘可能許多的假定。隱藏假定條件會導致合作失敗。通過測試,你可以在提供的包中地將你的期望準確記入文檔。當所有的測試運行完畢時,包的供應商就知道它正常運行了。
使用殘根(參見本書前面的“殘根”一章),你能進一步減弱和包供應商之間的耦合。供應商的工作是測試能夠運行在包的真正實現上。你的工作是測試運行在自己的代碼上。在你得到供應商的包的真正的實現之前,你使用殘根工作。用這種方法,兩個團隊能夠獨立工作。
 
12-3 調試測試
當你得到一份缺陷報告時,你的第一衝動也許是趕快修復它。經驗表明,這種衝動效果不好:修復此缺陷可能會導致其它缺陷。
你應該通過檢查如下列表來控制衝動:
-          再次覈實一下,確信你能重現缺陷。
-          發現最小範圍的出現缺陷的代碼。例如,輸出時如果數字不正確,找到計算那個數字的對象。
-          寫一個自動化的測試,如果該缺陷被修復,此測試會通過,反之會失敗。
-          修復缺陷。
發現缺陷的最小可靠再現部分提供了一個發現缺陷真正原因的機會。你寫的測試將會提高正確修復缺陷的機會,因爲新的測試減少了當未來代碼改變時取消本次修復的可能性。
前面所寫的所有測試都會減少因疏忽而造成其它問題的可能性。
 
12-4 重構
重構是一種改進現有的代碼的設計的受控技術,只有當你有一套測試套件時才能被安全的應用。否則,你也許沒有注意到當你修改結構時系統崩潰了。 重構可以分解爲一系列行爲保留的小的改進,這種改進不會改變程序的行爲。
以下情況將幫助你改進項目的代碼和設計,使用單位測試驗證重構的變革步奏是行爲保留的,不會引入其它錯誤:
-          所有單位測試運行正確。
-          代碼傳達它的設計意圖。
-          代碼沒有冗餘。
-          代碼只包含最小數量的類和方法。
 
--------------------------------------------------------------------------------------------------------------------
原文:
Chapter 12. Other Uses for Tests
Once you get used to writing automated tests, you will likely discover more uses for tests. Here are some examples.
 
12-1. Agile Documentation
Typically, in a project that is developed using an agile process, such as Extreme Programming, the documentation cannot keep up with the frequent changes to the project's design and code. Extreme Programming demands collective code ownership, so all developers need to know how the entire system works. If you are disciplined enough to use "speaking names" for your tests that describe what a class should do, you can use PHPUnit's TestDox functionality to generate automated documentation for your project based on its tests. This documentation gives developers an overview of what each class of the project is supposed to do.
 
PHPUnit's TestDox functionality looks at a test class and all the test method names and converts them from camel case PHP names to sentences: testBalanceIsInitiallyZero( ) becomes "Balance is initially zero." If there are several test methods whose names differ only by a suffix of one or more digits, such as testBalanceCannotBecomeNegative( ) and testBalanceCannotBecomeNegative2( ), the sentence "Balance cannot become negative" will appear only once, assuming that all of these tests succeed.
 
The following code shows the agile documentation for the Bank Account class (in Example 10) generated by running phpunit --testdox-text BankAccountTest.txt BankAccountTest:
 
    BankAccount
     - Balance is initially zero
     - Balance cannot become negative
 
 
 
Alternatively, the agile documentation can be generated in HTML format by using --testdox-html BankAccountTest.htm.
 
Agile documentation can be used to document the assumptions you make about the external packages in your project. When you use an external package, you are exposed to the risks that the package will not behave as you expect, and that future versions of the package will change in subtle ways that will break your code, without you knowing it. You can address these risks by writing a test about how the external package works every time you make an assumption. If your test succeeds, your assumption is valid. If you document all your assumptions with tests, future releases of the external package will be no cause for concern: if the tests succeed, your system should continue working.
 
12-2. Cross-Team Tests
When you document assumptions with tests, you own the tests. The supplier of the packagewho you make assumptions aboutknows nothing about your tests. If you want a closer relationship with the supplier of a package, you can use the tests to communicate and coordinate your activities.
 
When you agree on coordinating your activities with the supplier of a package, you can write the tests together. Do this in such a way that the tests reveal as many assumptions as possible. Hidden assumptions are the death of cooperation. With the tests, you document exactly what you expect from the supplied package. The supplier will know the package is complete when all the tests run.
 
By using stubs (see the section "Stubs," earlier in this book), you can further decouple yourself from the supplier. The job of the supplier is to make the tests run with the real implementation of the package. Your job is to make the tests run for your own code. Until such time as you have the real implementation of the supplied package, you use stub objects. Following this approach, the two teams can develop independently.
 
12-3. Debugging Tests
When you get a defect report, your impulse might be to fix the defect as quickly as possible. Experience shows that this impulse will not serve you well; it is likely that the fix for the defect will cause another defect.
 
You can hold your impulse in check by doing the following:
 
Verifying that you can reproduce the defect.
 
Finding the smallest-scale demonstration of the defect in the code. For example, if a number appears incorrectly in an output, find the object that is computing that number.
 
Writing an automated test that fails but will succeed when the defect is fixed.
 
Fixing the defect.
 
Finding the smallest reliable reproduction of the defect gives you the opportunity to really examine the cause of the defect. The test you write will improve the chances that when you fix the defect, you really fix it, because the new test reduces the likelihood of undoing the fix with future code changes.
 
All the tests you wrote before reduce the likelihood of inadvertently causing a different problem.
 
12-4. Refactoring
Refactoring, the controlled technique for improving the design of an existing code base, can be applied safely only when you have a test suite. Otherwise, you might not notice the system breaking while you are carrying out the restructuring. Refactoring can be broken down into a series of small behavior-preserving transformations.
 
The following conditions will help you to improve the code and design of your project, while using unit tests to verify that the refactoring's transformation steps are, indeed, behavior- preserving and do not introduce errors:
 
All unit tests run correctly.
 
The code communicates its design principles.
 
The code contains no redundancies.
 
The code contains the minimal number of classes and methods.
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章