JUnit3.81的設計

來源:互聯網
上載者:User

以上是類圖結構,可以先瀏覽一下有個直觀的印象。

1. 功能設計

    要實現的功能很簡單,如下

    第一,我寫我的測試代碼,framework執行我的測試代碼,同時framework應該提供回到讓我去準備環境和銷毀環境。

    第二,在我的測試的代碼中,可以檢查運行結果,對檢查的結果(測試成功/測試失敗)framework需要記錄。

 

2. 類設計

    2.1 Assert類,在此類中包括各種斷言操作。測序代碼當檢查運行結果時,只需要調用這些方法,他會自動記錄檢查結果。

    2.1 TestCase類,使用者寫測試代碼時繼承的基類. 為了方便將TestCase設計成可以執行多個測試代碼(也叫測試案例,英文TestCase,後面統一叫測試案例),而不是只用於一個測試案例。所以在預設情況下TestCase子類中所有public void testXxxx()風格的名字作為一個測試案例對待。在執行一個測試案例是調用setUp()方法去初始化環境,當一個測試案例執行完成後調用tearDown()方法銷毀測試環境。

          framework會自動解析TestCase子類中方面簽名為public void testXxxx()風格的測試案例,並建立每個測試案例相應的TestCase對象。如果不想framework來完成這個工作你可以添加static suite方法,自己完成這個過程。

          然後framework會對每個TestCase對象依次調用setUp()->public void
testXxxx()->tearDown()。如果你想改變對setUp()->public void
testXxxx()->tearDown()的調用(runTest方法預設邏輯)可以覆寫runTest方法,自己執行測試代碼。

          為了檢查結果方便,TestCase繼承了Assert類,雖然他們不應該不是is a關係

    2.3 TestSuite類,架構的一部分用例存放多個TestCase對象。上面討論的”自動解析TestCase子類中方面簽名為public void testXxxx()風格的測試案例,並建立每個測試案例相應的TestCase對象“就是由該類的構造方法完成(將TestCase子類名作為參數)

    2.4 TestResult 用來存在Assert類斷言操作的結果。

    2.5 TestRunner類。運行測試案例的起點,他的描述類類圖。

    2.6 Test介面。將TestSuite和TestCase統一到Test介面,出於以下考慮

          其一,出於可擴充性和靈活性考慮,在將來TestSuite中也可以放TestSuite類型的對象,這樣需要統一的介面來操作這個兩個類。

          其二,還是出於可擴充性和靈活性考慮,給TestRunner一個統一才操作介面,雖然在BaseTestRunner中getTest方法中返回的Test都是TestSuitle。這樣TestRunner直接運行TestCase就很容易實現。

 

3. 參數收集模式的使用

    3.1 參數收集模式
        在此模式中,重複的將一個collection (例如list, map.)作為參數傳遞給一些方法,這些方法向此collection中新增內容。
範例代碼:
 String[] userFiles = ...
 List userList = new ArrayList();
 for ( String userFile : userFiles ) {
   addUsersTo(userFile , userList);
 }

 public void addUsersTo(String userFileName, List userList) {
           ...
 }

    3.2 JUnit3.8中此模式的使用
        在JUnit3.8中, 此模式中的collection被封裝成TestResult類。在執行測試案例的過程中,framework建立一個TestResult對象,
然後用他作為參數去調用Test的run(TestResult)方法。值得注意的是,在TestCase類中,run(TestResult)方法又調用TestResult的
run(TestCase)方法。
        為什麼要這麼處理呢?如果不這樣那麼,需要在下面兩個情況之中選擇。
        1. 在TestCase代碼中需要捕捉斷言操作的結果,然後手動添加到TestResult中,例如
        public TestCaseA extends TestCase{
            ...................
            public void testXxxx(){
            try {
             ........
             assertTrue(...);
             ........
            } catch (AssertionFailedError e) {
                testResult.addFailure(test, e);
            } catch (Throwable e)  {
                testResult.addError(test, e);
            }
            ........................ 
        }
            這個情況下對TestCase之類的編寫者很不友好。而且為了在testXxx方法內部訪問當前TestResult變數也需要作出相應的處理。
也許作為testXxx方法的參數傳遞進來,也許作為TestCase的property。       
        2. 將“捕捉斷言操作的結果,然後手動添加到TestResult”的邏輯即
        try {
            ........
        } catch (AssertionFailedError e) {
             testResult.addFailure(test, e);
        } catch (Throwable e)  {
             testResult.addError(test, e);
        }
           放入斷言方法(例如assertTrue)內部。
           這樣需要調整所有的assert方法,同樣的也要採取相應的方式讓assert方法能夠訪問當前TestResult變數。

           上面兩個情況都不是很優雅,我們需要在一個地方統一的捕捉斷言操作的結果,然後添加到TestResult中,有了這個地方
還可以做一些類似的事情(例如TestCase執行觸發事件)而不至於讓邏輯侵入TestCase內部。JUnit3.8將這個地方選擇在TestResult
內部,即TestResult的run(TestCase)方法。在這個地方,統一的捕捉斷言操作的結果,然後添加到自己內部。
           這樣也很優雅的就解決了TestResult變數訪問問題。在此方法內部在TestCase執行前後都會觸發相應事件。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.