Какая польза от аннотации @TestInstance в JUnit 5?

Можете ли вы дать простое объяснение аннотации @TestInstance и как она может быть полезна в JUnit 5?

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

Ответы

Ответ 1

Я думаю, что документы предоставляют полезное резюме:

Если вы предпочитаете, чтобы JUnit Jupiter выполнял все тестовые методы в одном и том же тестовом экземпляре, просто аннотируйте ваш тестовый класс с помощью @TestInstance (Lifecycle.PER_CLASS). При использовании этого режима новый экземпляр теста будет создаваться один раз для каждого класса теста. Таким образом, если ваши методы тестирования полагаются на состояние, хранящееся в переменных экземпляра, вам может потребоваться сбросить это состояние в методах @BeforeEach или @AfterEach.

Режим "на класс" имеет некоторые дополнительные преимущества по сравнению с режимом "на метод" по умолчанию. В частности, в режиме "на класс" становится возможным объявить @BeforeAll и @AfterAll для нестатических методов, а также для методов интерфейса по умолчанию. Следовательно, режим "на класс" также позволяет использовать методы @BeforeAll и @AfterAll в классах @Nested test.

Но вы, вероятно, уже читали это, и вы правы, полагая, что создание статического поля будет иметь тот же эффект, что и объявление поля в качестве переменной экземпляра и использование @TestInstance(Lifecycle.PER_CLASS).

Таким образом, возможно, ответ на вопрос "как это может быть полезно в JUnit 5" заключается в том, что используется @TestInstance...

  • Откровенно о ваших намерениях. Можно предположить, что использование статического ключевого слова было случайным, в то время как использование @TestInstance менее вероятно, будет случайным или результатом хотя бы бессмысленного копирования-n-вставки.
  • Делегирует ответственность за управление областью действия и жизненным циклом, а также за очистку от структуры, вместо того, чтобы не забывать управлять этим самостоятельно.

Ответ 2

Эта аннотация была введена для уменьшения количества объектов, созданных при выполнении модульных тестов.

Добавление @TestInstance(TestInstance.Lifecycle.PER_CLASS) к вашему тестовому классу позволит избежать создания нового экземпляра вашего класса для каждого теста в классе. Это особенно полезно, если у вас много тестов в одном классе тестов, и создание этого класса дорого.

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

Создание полей, статических для достижения того же эффекта, не является хорошей идеей. Это действительно уменьшит количество созданных объектов, но их нельзя будет очистить, когда будут выполнены все тесты в тестовом классе. Это может вызвать проблемы, когда у вас есть гигантский набор тестов.

Ответ 3

@TestInstance используется для настройки жизненного цикла тестовых экземпляров для аннотированного класса теста или интерфейса теста:

  • PER_CLASS: новый экземпляр теста будет создан один раз для каждого класса теста.
  • PER_METHOD: новый экземпляр теста будет создан для каждого метода теста, метода фабрики тестов или метода шаблона теста. Этот режим аналогичен поведению в версиях JUnit с 1 по 4.

Если @TestInstance явно не объявлен в тестовом классе или в тестовом интерфейсе, реализованном тестовым классом, режим жизненного цикла по умолчанию неявно будет PER_METHOD.


Установка режима жизненного цикла экземпляра теста на PER_CLASS включает следующие функции:

  • Состояние экземпляра общего теста между методами теста в данном классе теста, а также между нестатическими @BeforeAll и @AfterAll в классе теста.
  • Объявление методов @BeforeAll и @AfterAll в классах @Nested test.
  • Объявление @BeforeAll и @AfterAll в методах интерфейса по умолчанию.
  • Упрощенное объявление методов @BeforeAll и @AfterAll в тестовых классах, реализованных на языке программирования Kotlin.

Более подробную информацию смотрите в документации по жизненному циклу тестового экземпляра.