Начал ли JUnit4 поддержку заказа тестов? Это намеренно?

Новичок в JUnit (на самом деле JUnit 4) и наткнулся на удобный способ выполнения теста.

@RunWith(Suite.class)
@Suite.SuiteClasses(
        {                               
                CreateNewProfile.class,
                EditProfile.class,

        })
public class ProfileTestSuite {

}

Это пример кода, с которым я столкнулся, просматривая тестовую базу кода у моего нового работодателя. Во время выполнения я финансирую это - сначала выполняются тесты CreateNewProfile, а затем EditProfile, что имеет смысл, но затем вводит зависимость между тестами.

Я следил за независимым механизмом тестирования пару месяцев (хотя раньше использовал TestNG, а не JUnit) и ожидал, что EditProfile также сможет выполняться изолированно. То есть профиль редактирования должен позаботиться о создании профиля, а затем его редактировании и последующем утверждении операций.

У меня вопрос: в Junit 4 введена функция тестового заказа. Предназначена ли эта функция или одна пасхалка, как я всегда чувствовал, JUnit = независимые тесты.


person Tarun    schedule 21.10.2011    source источник


Ответы (6)


Никакой JUnit не поддерживает упорядочивание тестов, кроме как так, как вы говорите, через Suite. Это определяет только порядок, в котором выполняются тестовые классы. Это было там в течение долгого времени, включая классы JUnit 3 Suite.

Для более полного объяснения нам нужно поговорить о трех вещах:

  1. порядок классов тестов в наборе тестов
  2. порядок тестовых классов, когда они найдены путем отражения Eclipse или Maven
  3. порядок тестовых методов (с аннотацией @Test) в тестовом классе.

Порядок классов тестов в наборе тестов

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

Порядок тестовых классов, когда они найдены отражением

При поиске классов в пути к классам порядок их нахождения не гарантируется, поэтому на него нельзя полагаться. На самом деле поиском занимается не JUnit, а плагин Eclipse Junit или maven surefire или failsafe.

Порядок тестовых методов в тестовом классе

JUnit не гарантирует порядок выполнения тестов внутри класса. В большинстве случаев на большинстве JVM до версии 7 порядок, в котором они находятся с использованием отражения, соответствует порядку объявления, т. е. порядку, в котором они находятся в файле. Это порядок, в котором они выполняются. Однако с JVM 7 это больше не гарантируется, поэтому последовательного порядка не будет. Существует проблема github #293 Сортировать методы тестирования для обеспечения предсказуемости с предлагаемыми решениями, и в списке рассылки junit есть ветка: Алфавитизация порядка выполнения методов тестирования?. Таким образом, вы не можете зависеть от порядка выполнения тестов с использованием JUnit, но в настоящее время это обсуждается.

person Matthew Farwell    schedule 21.10.2011
comment
Отсюда я исхожу из того, что тест должен выполняться независимо и не в зависимости от порядка их расположения в @Suite. И это преподнесет мне сюрприз, когда я буду выполнять тесты параллельно. Правильно? - person Tarun; 21.10.2011
comment
Тестовые методы (и, следовательно, классы) всегда должны выполняться независимо друг от друга, хотя бы для того, чтобы можно было выполнить один тест в среде IDE. Это зависит от того, как ваш параллельный бегун выполняет тесты, параллельно ли он выполняет классы или методы внутри классов, но да, это может вызвать проблемы. Лучше попытаться избежать всех зависимостей между тестами. - person Matthew Farwell; 21.10.2011
comment
Мэтью: независимыми должны быть только модульные тесты. Для функционального тестирования возможность заказывать методы очень полезна, поэтому эта функция появилась в TestNG с версии 1. - person Cedric Beust; 21.10.2011

Нет, заказ не поддерживается. И да, намерение:

KentBeck прокомментировал (30 декабря 2010 г.): Независимые тесты более ценны, поэтому JUnit не поддерживает упорядочивание тестов.

Если вам нужна эта функция, вы можете использовать TestNG с его @Test(sequential = true).

person jeha    schedule 21.10.2011
comment
Что ж, каждый раз, когда я его выполняю, я вижу, что сначала вызываются методы CreateNewProfile.class, а затем EditProfile.class. Сейчас не заказывает? - person Tarun; 21.10.2011
comment
@Tarun: я думаю, это результат того, как это реализовано (неявный порядок). Дело в том, что последовательность выполнения не гарантируется (нет явного порядка), так что это может измениться, и вы не можете на это полагаться. - person jeha; 21.10.2011
comment
Использование \@Suite для заказа тестовых классов меня беспокоит, поскольку я не могу выполнять их независимо, когда запускаю их из \@suite. - person Tarun; 21.10.2011
comment
На самом деле, с TestNG это @Test(dependsOnMethods=...) или, что рекомендуется, @Test(dependsOnGroups=...). - person Cedric Beust; 21.10.2011
comment
Упорядочение может быть достигнуто в JUnit с помощью аннотации класса @FixMethodOrder(MethodSorters.NAME_ASCENDING) (начиная с JUnit 4.11), но этого следует избегать по уже упомянутым причинам. - person nrainer; 06.11.2014

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

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

Вы спрашиваете о порядке тестовых занятий. Это не должно быть сюрпризом: вы явно перечисляете тестовые классы, используя @Suite.SuiteClasses, и JUnit, вероятно, не нужно их перемешивать и запускать в другом порядке. Вы беспокоитесь о введении зависимости между тестами просто потому, что вы явно заказали их?

person Tomasz Nurkiewicz    schedule 21.10.2011
comment
Да, меня беспокоит порядок, который вводится при выполнении тестовых классов, указанных в \@Suite. Я чувствую, что это неправильное использование \@Suite, и я не могу просто выполнить EditProfile.class из @Suite, если бы захотел. - person Tarun; 21.10.2011

Вы можете расширить бегун Suite:

public class MySuite extends Suite {

    public SuiteRunner(Class<?> klass, RunnerBuilder builder) throws InitializationError {
        super(klass, builder);
    }

    @Override
    protected List<Runner> getChildren() {
        List<Runner> children = super.getChildren();
        ... here modify the children list - you can remove or reorder test...
        return children;
    }
}

Затем аннотируйте свой набор:

@RunWith(MySuite.class)
@Suite.SuiteClasses({                               
        CreateNewProfile.class,
        EditProfile.class})
public class ProfileTestSuite { }

Тесты, отмеченные @Ignore, будут представлены IgnoredClassRunner, а обычные тесты будут представлены BlockJUnit4ClassRunner (или любым бегуном, которым вы их аннотируете, что, вероятно, будет расширением BlockJUnit4ClassRunner).

Из бегуна можно получить тестовый класс. Затем вы можете использовать собственные аннотации.

person Masáč    schedule 06.11.2014

JUnit 4.11 теперь поддерживает указание порядка выполнения с помощью аннотации @FixMethodOrder.

person Aleksandr Dubinsky    schedule 28.01.2015

Просто обойдите его, упорядочив имена классов, используя _# перед именем класса. Ex _1testcaselogin _2testcaseverify

person Kelly Ryan    schedule 17.01.2013