Jak uruchomić metody testowe w określonej kolejności w JUnit4?

Chcę wykonać metody testowe, które są przypisane przez @Test w określonej kolejności.

Na przykład:

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

Chcę upewnić się, że uruchamiam test1() przed test2() za każdym razem, gdy uruchamiam MyTest, ale nie mogłem znaleźć adnotacji takiej jak @Test(order=xx).

Myślę, że to dość ważna funkcja dla JUnit, jeśli autor JUnit nie chce order feature , dlaczego?

Author: ROMANIA_engineer, 2010-09-12

16 answers

Myślę, że jest to dość ważna funkcja dla JUnit, jeśli autor JUnit nie chce funkcji order, dlaczego?

Nie jestem pewien, czy istnieje na to czysty sposób z JUnit, z mojej wiedzy JUnit zakłada, że wszystkie testy mogą być wykonywane w dowolnej kolejności. Z FAQ:

Jak używać urządzenia testowego?

(...) Kolejność wywołań metody testowej jest nie gwarantowana , więc testOneItemCollection() może zostać wykonane przed testEmptyCollection (). (...)

Dlaczego tak jest? Cóż, uważam, że uzależnianie testów od kolejności jest praktyką, której autorzy nie chcą promować. Testy powinny być niezależne, nie powinny być łączone, a naruszenie tego utrudni utrzymanie, złamie możliwość uruchamiania testów indywidualnie (oczywiście) itp.

To powiedziawszy, jeśli naprawdę chcesz iść w tym kierunku, rozważ użycie TestNG, ponieważ obsługuje on Uruchamianie testów metody w dowolnej kolejności natywnie (i rzeczy takie jak określenie, że metody zależą od grup metod). Cedric Beust wyjaśnia, jak to zrobić w kolejności wykonywania testów w testng .

 207
Author: Pascal Thivent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:29

Jeśli pozbędziesz się istniejącej instancji Junit i pobierzesz JUnit 4.11 lub nowszą w ścieżce budowania, następujący kod uruchomi metody testowe w kolejności ich nazw, posortowanych w kolejności rosnącej:

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SampleTest {

    @Test
    public void testAcreate() {
        System.out.println("first");
    }
    @Test
    public void testBupdate() {
        System.out.println("second");
    }
    @Test
    public void testCdelete() {
        System.out.println("third");
    }
}
 60
Author: Aniket Kulkarni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-19 01:06:04

Jeśli zamówienie jest ważne, należy złożyć zamówienie samodzielnie.

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

W szczególności, należy wymienić niektóre lub wszystkie możliwe permutacje kolejności do przetestowania, jeśli to konieczne.

Na przykład,

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(); }

Lub, pełny test wszystkich permutacji:

@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; 
            }
        }
    }
}

Tutaj, {[3] } jest prostą funkcją, która iteruje wszystkie możliwe permuacje do zbioru tablic.

 49
Author: Xiè Jìléi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-16 08:30:22

Migracja do TestNG wydaje się najlepsza, ale nie widzę tu jasnego rozwiązania dla jUnit. Oto najbardziej czytelne rozwiązanie / formatowanie jakie znalazłem dla jUnit:

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SampleTest {
    @Test
    void stage1_prepareAndTest(){};

    @Test
    void stage2_checkSomething(){};

    @Test
    void stage2_checkSomethingElse(){};

    @Test
    void stage3_thisDependsOnStage2(){};

    @Test
    void callTimeDoesntMatter(){}
}

Zapewnia to wywoływanie metod stage2 po stage1 i przed stage3.

 32
Author: joro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-11 14:20:09

Jest to jeden z głównych problemów, z którymi miałem do czynienia, gdy pracowałem nad Junitem i wymyśliłem następujące rozwiązanie, które działa dobrze dla mnie: {]}

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;
    }
}

Również utworzyć interfejs jak poniżej:

 @Retention(RetentionPolicy.RUNTIME)


@Target({ ElementType.METHOD})

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

Załóżmy, że masz klasę A, w której napisałeś kilka spraw testowych, jak poniżej:

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

void method(){

//do something

}

}

Więc wykonanie rozpocznie się od metody o nazwie"method ()". Dzięki!

 14
Author: Aman Goel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-27 04:21:47

The (as yet unreleased) change https://github.com/junit-team/junit/pull/386 wprowadza @SortMethodsWith. https://github.com/junit-team/junit/pull/293 przynajmniej sprawiło, że kolejność była przewidywalna bez tego (w Javie 7 może być całkiem przypadkowa).

 8
Author: Jesse Glick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-14 20:43:04

Spójrz na raport JUnit. JUnit jest już zorganizowany przez pakiet. Każdy pakiet ma (lub może mieć) klasy TestSuite, z których każda z kolei uruchamia wiele testów. Każdy TestCase może mieć wiele metod testowych w postaci public void test*(), z których każda stanie się instancją klasy TestCase, do której należy. Każda metoda testowa (instancja TestCase) ma nazwę i kryteria pass/fail.

Moje zarządzanie wymaga koncepcji poszczególnych TestStep elementów, każdy w tym zgłasza własne kryteria pass/fail. Niepowodzenie jakiegokolwiek etapu badania nie może uniemożliwiać wykonania kolejnych etapów badania.

W przeszłości Programiści testowi na moim stanowisku organizowali klasy TestCase w pakiety, które odpowiadają częściom testowanego produktu, tworzyli klasę TestCase dla każdego testu i uczynili każdą metodę testową oddzielnym "krokiem" w teście, wraz z własnymi kryteriami pass/fail w wyjściu JUnit. Każdy test jest samodzielnym "testem", ale poszczególne metody, lub "kroki" testowe w ramach TestCase, muszą występować w określonej kolejności.

Metody TestCase były etapami TestCase, a projektanci testów otrzymali oddzielne kryterium pass/fail na każdy etap testu. Teraz etapy testu są pomieszane, a testy (oczywiście) zawodzą.

Na przykład:

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()

Każda metoda badawcza zapewnia i zgłasza własne oddzielne kryteria pozytywnego / negatywnego wyniku. "Jedna wielka metoda testowa" dla Zamawiającego traci pass/fail kryteria szczegółowość każdego "kroku" w raporcie podsumowującym JUnit. ...i to denerwuje moich menedżerów. Obecnie domagają się innej alternatywy.

Czy ktoś może wyjaśnić, w jaki sposób JUnit z kodowaną metodą zamawiania metod testowych wspierałby oddzielne kryteria zaliczenia/niepowodzenia każdego kolejnego etapu testu, jak na przykładzie powyżej i wymaganym przez moje kierownictwo?

Niezależnie od dokumentacji, postrzegam to jako poważną regresję w ramach JUnit, która utrudnia życie wielu osobom test deweloperów.

 6
Author: Anonymous Developer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-24 19:00:29

To, czego chcesz, jest całkowicie rozsądne, gdy sprawy testowe są prowadzone jako pakiet.

Niestety nie ma czasu na podanie kompletnego rozwiązania w tej chwili, ale spójrz na klasę:

org.junit.runners.Suite

Który pozwala wywoływać przypadki testowe (z dowolnej klasy testowej) w określonej kolejności.

Mogą one służyć do tworzenia testów funkcjonalnych, integracyjnych lub systemowych.

To pozostawia testy jednostkowe bez określonej kolejności (zgodnie z zaleceniami), niezależnie od tego, czy je uruchamiasz w ten sposób, czy nie, a następnie ponownie wykorzystaj testy jako część szerszego obrazu.

Ponownie używamy / dziedziczymy ten sam kod do testów jednostek, integracji i systemów, czasami opartych na danych, czasami opartych na zatwierdzeniach, a czasami uruchamianych jako pakiet.

 3
Author: CharlieS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-27 00:58:21

Nie jestem pewien, czy się Zgadzam, jeśli chcę przetestować 'File Upload', a następnie przetestować 'Data Inserted by File Upload', dlaczego miałbym nie chcieć, aby były one niezależne od siebie? Całkiem rozsądne myślę, aby móc uruchomić je osobno, a nie mieć oba w przypadku testu Goliata.

 3
Author: Mattk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-19 12:11:44

Zobacz moje rozwiązanie tutaj: "Junit i java 7."

W tym artykule opiszę jak uruchamiać testy junit w kolejności - "tak jak w kodzie źródłowym". Testy zostaną uruchomione w kolejności, w jakiej metody testowe pojawią się w pliku klasowym.

Http://intellijava.blogspot.com/2012/05/junit-and-java-7.html

Ale jak powiedział Pascal Thivent, to nie jest dobra praktyka.

 2
Author: kornero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-05 10:12:22

Przeczytałem kilka odpowiedzi i zgadzam się, że nie jest to najlepsza praktyka, ale najprostszym sposobem na zamówienie testów - a sposób, w jaki JUnit uruchamia testy domyślnie jest Alfabetycznie rosnąca nazwa.

Więc po prostu nazwij swoje testy w porządku alfabetycznym, który chcesz. Należy również pamiętać, że nazwa testu musi się rozpocząć z testem słownym. Po prostu uważaj na liczby

Test12 uruchomi się przed testem2

Więc:

TestA_MyFirstTest testC_ThirdTest testB_ATestThatRunsSecond

 1
Author: pstorli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-10 20:01:20

Proszę sprawdzić ten: https://github.com/TransparentMarket/junit . uruchamia test w określonej kolejności (zdefiniowanej w skompilowanym pliku klasy). Posiada również Pakiet AllTests do uruchamiania testów zdefiniowanych przez podpakiet pierwszy. Korzystając z implementacji AllTests można rozszerzyć rozwiązanie również o filtrowanie właściwości (kiedyś używaliśmy @Fast adnotations, ale te nie zostały jeszcze opublikowane).

 0
Author: Martin Kersten,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-30 14:20:01

Oto rozszerzenie JUnit, które może wywołać pożądane zachowanie: https://github.com/aafuks/aaf-junit

Wiem, że jest to sprzeczne z filozofią JUnit, ale przy używaniu JUnit w środowiskach, które nie są ścisłymi testami jednostkowymi (jak to jest praktykowane w Javie), może to być bardzo pomocne.

 0
Author: shlomi33,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-25 15:28:02

Skończyłem tutaj myśląc, że moje testy nie były prowadzone w porządku, ale prawda jest taka, że bałagan był w moich pracach asynchronicznych. Podczas pracy z współbieżnością należy również przeprowadzać kontrole współbieżności między testami. W moim przypadku zadania i testy współdzielą SEMAFOR, więc kolejne testy zawieszają się, dopóki uruchomione zadanie nie zwolni blokady.

Wiem, że nie jest to w pełni związane z tym pytaniem, ale może pomoże w trafieniu poprawnego problemu

 0
Author: McCoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-01 15:44:06

Możesz użyć jednego z tych kodów:

@FixMethodOrder(MethodSorters.JVM)OR `@FixMethodOrder(MethodSorters.DEFAULT)` OR `@FixMethodOrder(MethodSorters.NAME_ASCENDING)` before your test class like this:


@FixMethodOrder(MethodSorters.NAME_ASCENDING)


public class BookTest { ...}
 0
Author: Arezoo Bagherzadi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-04 11:41:37

JUnit obecnie zezwala na uruchamianie metod testowych przy użyciu adnotacji klasy:

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FixMethodOrder(MethodSorters.JVM)
@FixMethodOrder(MethodSorters.DEFAULT)

Aby ustawić kolejność metod można je nazwać następująco:

A_testWorkUnit_WithCertainState_shoulddosomething b_testWorkUnit_WithCertainState_shoulddosomething c_testWorkUnit_WithCertainState_shoulddosomething

Możesz znaleźć przykłady tutaj.

 0
Author: Zon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-22 09:15:34