好消息是,測試驅動開發不僅僅適合于新代碼。即使是程序員維護老代碼時也可以利用它編寫、運行以及通過測試。對于已經在生產中的遺留系統,測試確實更加 重要。只有通過測試,您才能確信您對于系統中的某一部分所做的改變不會中斷其他地方的另外一部分。當然,您可能沒有時間或者經費為一個規模龐大的代碼基礎達到 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);
}
}
}
}