• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • JUnit源碼解析

    發表于:2016-10-04來源:saymagic作者:saymagic點擊數: 標簽:junit
    JUnit源碼解析JUnit是由 Erich Gamma 和 Kent Beck 編寫的一個回歸測試框架,以Eclipse、IDEA等為代表的Java開發環境都對JUnit提供了非常友善的支持。提到Erich Gamma,他就是大名鼎鼎的《設計模式
    JUnit源碼解析
    JUnit是由 Erich Gamma 和 Kent Beck 編寫的一個回歸測試框架,以Eclipse、IDEA等為代表的Java開發環境都對JUnit提供了非常友善的支持。提到Erich Gamma,他就是大名鼎鼎的《設計模式:可復用面向對象軟件的基礎》一書的作者之一。因此,JUnit當中的設計模式的運用相當得當,所以,JUnit的源碼可謂相當優良的一本武林秘籍,非常值得一看。 本文基于JUnit4.12,將從JUnit的運行流程,Match驗證,兩個方面,來對JUnit的源碼進行整體的分析。
     
    運行流程
     
    JUnit的啟動方式有很多,比如在Android Studio中我們可以直接點擊某個被@Test注解的函數來運行:
     
     
     
    此時,啟動的是JUniteStarter,該類是intellij為我們提供的。感興趣可以查看其源碼: https://github.com/JetBrains/intellij-community/blob/master/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitStarter.java
     
    如果我們使用gradle, 可以執行gradle test運行測試,實際上是在一個線程中執行SuiteTestClassProcessor的processTestClass方法來進行啟動。其源碼可以查看https://github.com/gradle/gradle/blob/master/subprojects/testing-base/src/main/java/org/gradle/api/internal/tasks/testing/SuiteTestClassProcessor.java
     
    如上兩種都是第三方工具為我們提供的便捷方式,實際上JUnit也提供了一個名為JUnitCore的類來供我們方便的運行測試用例。
     
    盡管啟動JUnit的方式有很多,但這都是打開與JUnit對話的一些方式,最終執行的還是JUnit當中的起到核心作用的一些類,為了讓大家對這些核心boss有一個初步了解,我畫了一個類圖:
     
     
     
    上圖中僅是JUnit中的幾個核心的類,也是本分主要分析的對象。這里先給出一些對象的職責,可以有個大體的了解,后面會通過代碼就會更清楚每個對象是如何完成這些職責的:
     
    在類圖的中央,有個叫做ParentRunne的對象很引人注目,它繼承自Runner.
    Runner則表示著JUnit對整個測試的抽象
    Runner實現了Describable接口,Describable接口中唯一的函數getDescription()返回了Description對象,記錄著測試的信息。
    Statement 是一個抽象類,其 evaluate()函數代表著在測試中將被執行的方法。
    ParentRunner 共有兩個子類,BlockJUnit4ClassRunner 用來運行單個測試類,Suite用來一起運行多個測試類
    RunnerBuilder 是生產Runner的策略,如使用@RunWith(Suite.class)標注的類需要使用Suite, 被@Ignore標注的類需要使用IgnoreClassRunner。
    TestClass是對被測試的類的封裝
    綜上,我們先從ParentRunner看起,其構造函數如下:
     
    protected ParentRunner(Class<?> testClass) throws InitializationError {
        this.testClass = createTestClass(testClass);
        validate();
    }
    this.testClass即前文所說的TestClass,我們進入createTestClass方法來查看其如何將class對象轉換為TestClass。
     
    protected TestClass createTestClass(Class<?> testClass) {
            return new TestClass(testClass);
    }
    并沒什么東西,具體的邏輯都寫在TestClass的內部:
     
    public TestClass(Class<?> clazz) {
        this.clazz = clazz;
        if (clazz != null && clazz.getConstructors().length > 1) {
            throw new IllegalArgumentException(
                    "Test class can only have one constructor");
        }
        Map<Class<? extends Annotation>, List<FrameworkMethod>> methodsForAnnotations =
                new LinkedHashMap<Class<? extends Annotation>, List<FrameworkMethod>>();
        Map<Class<? extends Annotation>, List<FrameworkField>> fieldsForAnnotations =
                new LinkedHashMap<Class<? extends Annotation>, List<FrameworkField>>();
        scanAnnotatedMembers(methodsForAnnotations, fieldsForAnnotations);
        this.methodsForAnnotations = makeDeeplyUnmodifiable(methodsForAnnotations);
        this.fieldsForAnnotations = makeDeeplyUnmodifiable(fieldsForAnnotations);

    原文轉自:http://blog.saymagic.cn/2016/09/30/understand-Junit.html

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>