Можно ли определить порядок выполнения тестовых примеров Junit для нескольких классов? [Дубликат]

Конечно, есть много таких подходов, как синхронный запрос, обещание, но из моего опыта я думаю, что вы должны использовать подход обратного вызова. Естественно, что асинхронное поведение Javascript. Итак, ваш фрагмент кода можно переписать немного иначе:

function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            myCallback(response);
        }
    });

    return result;
}

function myCallback(response) {
    // Does something.
}
345
задан ROMANIA_engineer 28 October 2014 в 11:59
поделиться

16 ответов

Я думаю, что это очень важная функция для JUnit, если автор JUnit не хочет, чтобы функция заказа, почему?

Я не уверен, что с JUnit существует чистый способ, насколько я знаю. JUnit предполагает, что все тесты могут выполняться в произвольном порядке. Из часто задаваемых вопросов:

Как использовать тестовое устройство?

(...) Порядок вызова тестовых методов не является гарантировано, поэтому testOneItemCollection () может быть выполнено до testEmptyCollection (). (...)

Почему это так? Я считаю, что выполнение тестов зависит от порядка - это практика, которую авторы не хотят продвигать. Тесты должны быть независимыми, они не должны сочетаться и нарушать это, что усложнит работу, нарушит способность запускать тесты индивидуально (очевидно) и т. Д.

. Говоря, если вы действительно хотите чтобы пойти в этом направлении, рассмотрите возможность использования TestNG, поскольку он поддерживает запуск методов тестирования в любом произвольном порядке изначально (и такие вещи, как указание того, что методы зависят от групп методов). Седрик Боуст объясняет, как это сделать в порядке выполнения тестов в testng .

206
ответ дан Community 25 August 2018 в 21:55
поделиться

Изменение (пока еще неизданное) https://github.com/junit-team/junit/pull/386 вводит @SortMethodsWith. https://github.com/junit-team/junit/pull/293 , по крайней мере, сделал предсказуемый прогноз без этого (в Java 7 он может быть довольно случайным).

8
ответ дан Anthony Dahanne 25 August 2018 в 21:55
поделиться

вы можете использовать один из этих фрагментов кода:

@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
ответ дан Arezoo Bagherzadi 25 August 2018 в 21:55
поделиться

То, что вы хотите, вполне разумно, когда тестовые примеры запускаются как набор.

К сожалению, нет времени, чтобы дать полное решение прямо сейчас, но посмотрите на класс:

org.junit.runners.Suite

Это позволяет вам вызывать тестовые примеры (из любого тестового класса) в определенном порядке.

Они могут использоваться для создания функциональных, интеграционных или системных тестов.

(как рекомендовано), независимо от того, запускаете ли вы их или нет, а затем повторно используйте тесты как часть более крупного изображения.

Мы повторно используем / наследуют один и тот же код для модульных, интеграционных и системных тестов, иногда управляются данными, иногда управляются, а иногда запускаются как набор.

3
ответ дан CharlieS 25 August 2018 в 21:55
поделиться

Если вы избавитесь от существующего экземпляра Junit и загрузите JUnit 4.11 или больше в пути сборки, следующий код выполнит методы тестирования в порядке их имен, отсортированных по возрастанию порядок:

@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");
    }
}
54
ответ дан Eric Leschinski 25 August 2018 в 21:55
поделиться

Миграция в TestNG кажется лучшим способом, но я не вижу здесь ясного решения для jUnit. Вот наиболее читаемое решение / форматирование, которое я нашел для 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(){}
}

Это гарантирует, что методы stage2 вызывается после stage1 и до stage3.

30
ответ дан joro 25 August 2018 в 21:55
поделиться

См. мое решение здесь: «Junit and java 7.»

В этой статье описывается, как запускать junit-тесты по порядку - «так же, как в вашем исходном коде». Тесты будут выполняться, чтобы ваши тестовые методы отображались в файле класса.

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

Но, как сказал Паскаль Тивент, это не очень хорошая практика.

2
ответ дан kornero 25 August 2018 в 21:55
поделиться

Пожалуйста, ознакомьтесь с этим: https://github.com/TransparentMarket/junit . Он запускает тест в том порядке, в котором они указаны (определяется в файле скомпилированного класса). Кроме того, в нем есть пакет AllTests для запуска тестов, определенных в первом пакете. Используя реализацию AllTests, вы можете расширить решение и фильтровать свойства (мы использовали аннотации @Fast, но они еще не были опубликованы).

0
ответ дан Martin Kersten 25 August 2018 в 21:55
поделиться

Не уверен, что я согласен, если я хочу проверить «Загрузка файлов», а затем проверить «Данные, вставленные путем загрузки файлов», почему я не хочу, чтобы они были независимыми друг от друга? Совершенно разумно, я думаю, чтобы иметь возможность запускать их отдельно, а не как в случае с Goliath.

3
ответ дан Mattk 25 August 2018 в 21:55
поделиться

В итоге я подумал, что мои тесты не выполняются по порядку, но правда в том, что беспорядок был в моих асинхронных заданиях. При работе с параллелизмом вам также необходимо выполнять проверки параллельности между вашими тестами. В моем случае задания и тесты используют семафор, поэтому следующие тесты зависают до тех пор, пока запущенное задание не освободит блокировку.

Я знаю, что это не полностью связано с этим вопросом, но, возможно, может помочь настроить правильную проблему

0
ответ дан McCoy 25 August 2018 в 21:55
поделиться

Я прочитал несколько ответов и согласен с тем, что это не самая лучшая практика, но самый простой способ заказать ваши тесты - и то, как JUnit запускает тесты по умолчанию, - это по алфавиту по возрастанию.

Так что просто укажите свои тесты в алфавитном порядке, который вы хотите. Также обратите внимание, что имя теста должно начинаться с теста слова. Просто следите за числами

test12 будет работать до test2

, поэтому:

testA_MyFirstTest testC_ThirdTest testB_ATestThatRunsSecond

1
ответ дан pstorli 25 August 2018 в 21:55
поделиться

Его главная проблема, с которой я столкнулась, когда я работал над 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 ()». Спасибо!

13
ответ дан ricosrealm 25 August 2018 в 21:55
поделиться

Вот расширение JUnit, которое может вызвать желаемое поведение: https://github.com/aafuks/aaf-junit

Я знаю, что это противоречит авторы философии JUnit, но при использовании JUnit в средах, которые не являются строгим модульным тестированием (как это практикуется на Java), это может быть очень полезно.

0
ответ дан shlomi33 25 August 2018 в 21:55
поделиться

Посмотрите отчет 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, который усложняет жизнь многим разработчикам тестов.

6
ответ дан Stefan Hanke 25 August 2018 в 21:55
поделиться

Если порядок важен, вы должны сделать заказ самостоятельно.

@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() - простая функция, которая выполняет итерацию все возможные перестановки в массив массивов.

48
ответ дан Xiè Jìléi 25 August 2018 в 21:55
поделиться

В настоящее время JUnit позволяет методам тестирования выполнять упорядочение с помощью аннотаций классов:

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

Чтобы задать порядок методов, вы можете их назвать:

a_testWorkUnit_WithCertainState_ShouldDoSomething b_testWorkUnit_WithCertainState_ShouldDoSomething c_testWorkUnit_WithCertainState_ShouldDoSomething

Здесь вы можете найти примеры .

0
ответ дан Zon 25 August 2018 в 21:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: