[java] 如何在JUnit4中按特定順序運行測試方法?


Answers

Junit 4.11附帶@FixMethodOrder註釋。 使用FixMethodOrder(MethodSorters.NAME_ASCENDING)升級junit版本並註釋測試類,而不是使用自定義解決方案。 查看發行說明了解詳細信息。

這是一個示例:

import org.junit.runners.MethodSorters;

import org.junit.FixMethodOrder;
import org.junit.Test;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SampleTest {

    @Test
    public void firstTest() {
        System.out.println("first");
    }

    @Test
    public void secondTest() {
        System.out.println("second");
    }
}
Question

我想執行由@Test按特定順序註釋的測試方法。

例如:

public class MyTest {
    @Test public void test1(){}
    @Test public void test2(){}
}

我希望確保每次運行MyTest時在test2() test1()之前運行test1() ,但我找不到像@Test(order=xx)這樣的註釋。

我認為這對JUnit來說非常重要,如果JUnit的作者不想要訂單功能 ,為什麼?




我已經閱讀了幾個答案,並且認為它不是最佳實踐,但是最簡單的方式來定購測試 - 以及JUnit默認運行測試的方式是通過字母名稱升序。

所以,只需按照您想要的字母順序命名您的測試。 還要注意,測試名稱必須以單詞test開頭。 只要注意數字

test12將在test2之前運行

所以:

testA_MyFirstTest testC_ThirdTest testB_ATestThatRunsSecond




看一下JUnit報告。 JUnit已經按照包來組織。 每個軟件包都有(或可以有)TestSuite類,每個類又運行多​​個TestCases。 每個TestCase可以有多種形式的測試方法public void test*() ,每個測試方法實際上將成為它們所屬的TestCase類的一個實例。 每個測試方法(TestCase實例)都有一個名稱和一個通過/失敗標準。

我的管理要求的是單個TestStep項目的概念,每個項目都報告自己的通過/失敗標準。 任何測試步驟的失敗都不能阻止後續測試步驟的執行。

過去,測試開發人員將TestCase類組織到與測試產品部件相對應的軟件包中,為每個測試創建一個TestCase類,並將每個測試方法作為測試中的一個單獨“步驟”在JUnit輸出中完成其自己的通過/失敗標準。 每個TestCase都是獨立的“測試”,但TestCase中的各個方法或測試“步驟”必須按特定順序進行。

TestCase方法是TestCase的步驟,測試設計人員在每個測試步驟中都有單獨的通過/失敗標準。 現在測試步驟混亂了,測試(當然)失敗了。

例如:

Class testStateChanges extends TestCase

public void testCreateObjectPlacesTheObjectInStateA()
public void testTransitionToStateBAndValidateStateB()
public void testTransitionToStateCAndValidateStateC()
public void testTryToDeleteObjectinStateCAndValidateObjectStillExists()
public void testTransitionToStateAAndValidateStateA()
public void testDeleteObjectInStateAAndObjectDoesNotExist()
public void cleanupIfAnythingWentWrong()

每個測試方法都會聲明並報告自己單獨的通過/失敗標準。 為了排序而將其折疊為“一個大測試方法”會丟失JUnit總結報告中每個“步驟”的合格/不合格標準粒度。 ......這讓我的經理感到不安。 他們目前正在要求另一種選擇。

任何人都可以解釋一下,如何使用混雜的測試方法排序的JUnit支持每個順序測試步驟的單獨通過/失敗標準,如上面所示和管理層要求的那樣?

無論文檔如何,我都認為這是JUnit框架中的一個嚴重倒退,正在使許多測試開發人員陷入困境。




如果訂單很重要,您應該自己下訂單。

@Test public void test1() { ... }
@Test public void test2() { test1(); ... }

尤其是,如果需要,您應列出一些或所有可能的排列順序以進行測試。

例如,

void test1(); 
void test2(); 
void test3(); 


@Test
public void testOrder1() { test1(); test3(); }

@Test(expected = Exception.class)
public void testOrder2() { test2(); test3(); test1(); }

@Test(expected = NullPointerException.class)
public void testOrder3() { test3(); test1(); test2(); }

或者,對所有排列組合進行全面測試:

@Test
public void testAllOrders() {
    for (Object[] sample: permute(1, 2, 3)) {
        for (Object index: sample) {
            switch (((Integer) index).intValue()) {
                case 1: test1(); break; 
                case 2: test2(); break; 
                case 3: test3(); break; 
            }
        }
    }
}

這裡, permute()是一個簡單的函數,它將所有可能的permuations迭代到數組的Collection中。







它是我在Junit工作時遇到的主要問題之一,並提出了以下解決方案,適用於我:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;

public class OrderedRunner extends BlockJUnit4ClassRunner {

    public OrderedRunner(Class<?> clazz) throws InitializationError {
        super(clazz);
    }

    @Override
    protected List<FrameworkMethod> computeTestMethods() {
        List<FrameworkMethod> list = super.computeTestMethods();
        List<FrameworkMethod> copy = new ArrayList<FrameworkMethod>(list);
        Collections.sort(copy, new Comparator<FrameworkMethod>() {

            @Override
            public int compare(FrameworkMethod f1, FrameworkMethod f2) {
                Order o1 = f1.getAnnotation(Order.class);
                Order o2 = f2.getAnnotation(Order.class);

                if (o1 == null || o2 == null) {
                    return -1;
                }

                return o1.order() - o2.order();
            }
        });
        return copy;
    }
}

還可以創建如下的界面:

 @Retention(RetentionPolicy.RUNTIME)


@Target({ ElementType.METHOD})

public @interface Order {
public int order();
}

現在假設你有類A,你已經寫瞭如下的幾個測試用例:

(@runWith=OrderRunner.class)
Class A{
@Test
@Order(order = 1)

void method(){

//do something

}

}

所以執行將從名為“method()”的方法開始。 謝謝!




不知道我是否同意,如果我想測試'文件上傳',然後測試'通過文件上傳插入的數據',為什麼我不希望這些相互獨立? 完全合理的我認為能夠單獨運行它們,而不是在Goliath測試案例中都有。




Links