/* I have no idea how this works but it seems to. Whatever you
do, don\'t touch this function, and don\'t break this code!
(雖然我不知道這段代碼起什么作用,但是看上去它似乎是有用的。無論您做什么,一定不要碰這個函數,不要破壞這段代碼。
*/
如果您曾經遇到過帶有此類注釋的代碼,這種情況并不少見。因為沒有人了解這些系統,所以有時候就使用規則約束禁止進入整個系統;但是仍然需要對這些系統進行維護。即使是一個已經完全沒有 bug 的系統(又有哪個系統能夠完全沒有 bug?),外部環境的改變也會使代碼的改變成為必要。Y2K 營業額是一個最大且最明顯的例子。歐元的引入對于某些金融系統來說相當于造成外傷。Sarbanes-Oxley 引入了新的以前不存在的報告要求,而且為了支持這些新規則,必須對遺留軟件進行翻新。這個世界不是靜態的,所以軟件也不能是靜態的,它必須向前發展否則就會被代替。
好消息是,測試驅動開發不僅僅適合于新代碼。即使是程序員維護老代碼時也可以利用它編寫、運行以及通過測試。對于已經在生產中的遺留系統,測試確實更加 重要。只有通過測試,您才能確信您對于系統中的某一部分所做的改變不會中斷其他地方的另外一部分。當然,您可能沒有時間或者經費為一個規模龐大的代碼基礎達到 100% 的測試覆蓋率,但是即使是并不完美的覆蓋率也能減少失敗的風險,加速開發并且產生更加健壯的代碼。
本文使用 jEdit 做為例子,向您展示如何為從未測試過的遺留代碼開發一個單元測試套件。jEdit 是一個流行的開放源碼的文本編輯器,它完全沒有任何測試套件!但是我將馬上開始對其進行修改。在本文中,我著手開發一個測試套件,其目的是為了使將來 jEdit 的開發更加多產、高效并且有趣。
第一次測試
中國有句老話,千里之行始于足下。遺留代碼的測試套件首先開始于一個單獨的測試。重點是做什么和從何做起。不要掉入相信因為不能夠測試每行代碼所以就不能夠測試任何東西的陷阱。只管打開您的 IDE 并且開始編寫測試。使用 JUnit(或者 NUnit,或者 CppUnit,或者任何您喜歡的框架)和一個一般的 IDE,您通常就能夠在 20 分鐘以內編寫出第一個測試。編寫測試要比編寫模型代碼簡單得多。測試很小并且具有獨立的代碼塊。它們不需要很多配置、思考和理解。您不需要 “專業知識” 來艱難地編寫出高質量的測試。
測試套件需要做的第一件事情是直接到達方法的中心。尋找您能夠做的最大范圍、最全面的測試。對于一個獨立的應用程序,可能是 main() 方法。例如,這是我的第一個 jEdit 測試用例。它所做的就是運行應用程序的 main() 方法并且檢驗它是否在屏幕上輸出了正確的窗口:
清單 1. 測試 jEdit 的 main() 方法
import java.awt.Frame;
import junit.framework.TestCase;
public class MainTest extends TestCase {
public void testMain() {
org.gjt.sp.jedit.jEdit.main(new String[0]);
// make sure there\'s a window on the screen
Frame[] allFrames = Frame.getFrames();
for (int i = 0; i < allFrames.length; i++) {
Frame f = allFrames[i];
if (f.isFocused()) {
assertTrue(f instanceof org.gjt.sp.jedit.View);
}
}
}
}
第一個測試的目的不是在邊界條件上費力,也不是為了查看解決了什么問題。第一個測試是一個發煙試驗,目的是為了對于什么可能是錯誤的給您一個清晰的概念。即使最基本的測試也不能揭示出構造系統、運行時環境、已安裝的軟件以及對每件事情進行本質上的破壞的其他主要問題中存在的問題。我的第一個測試用例確實能夠準確地發現 jEdit 代碼基礎的這樣一個問題:在我的類路徑中沒有包含所有可能的目錄。
我并沒有開始測試類路徑配置,但是我尋找到的問題也是重要的,因為它可能導致代碼基礎很難調試。類似這種的全面測試涉及到應用程序的很多方面。很多不同的東西能夠中斷并且導致測試失敗。就這種意義上說,并不是非常統一。在 test-first 編程中,這不是一個問題;但是當測試遺留代碼時,您沒有時間或者預算為每個單獨的方法或者分支編寫獨立的測試。您必須在編寫每個測試時盡量地覆蓋盡可能多的方法和分支。使用一些測試來測試大部分代碼比根本不進行測試要好。
文章來源于領測軟件測試網 http://www.kjueaiud.com/