JUnit confusion: использовать 'extends TestCase' или '@Test'?
Я нашел правильное использование (или, по крайней мере, документации) JUnit очень запутанным.
Этот вопрос служит как будущей ссылкой, так и реальным вопросом.
Если я правильно понял, есть два основных подхода для создания и запуска теста JUnit:
Подход A (стиль JUnit 3): создать класс, расширяющий TestCase, и запустить методы тестирования со словом test
. При запуске класса в качестве теста JUnit (в Eclipse) автоматически запускаются все методы, начинающиеся со слова test
.
import junit.framework.TestCase;
public class DummyTestA extends TestCase {
public void testSum() {
int a = 5;
int b = 10;
int result = a + b;
assertEquals(15, result);
}
}
Подход B (JUnit 4-style): создайте класс "normal" и добавьте аннотацию @Test
к методу. Обратите внимание, что вам не нужно начинать метод со слова test
.
import org.junit.*;
import static org.junit.Assert.*;
public class DummyTestB {
@Test
public void Sum() {
int a = 5;
int b = 10;
int result = a + b;
assertEquals(15, result);
}
}
Смешивание двух, кажется, не очень хорошая идея, см., например, qaru.site/info/48641/...:
Теперь, мои вопросы (вопросы):
- Какой предпочтительный подход, или когда вы используете его вместо другого?
- Подход B позволяет тестировать исключения, расширяя аннотацию @Test, как в
@Test(expected = ArithmeticException.class)
. Но как вы проверяете исключения при использовании подхода A?
-
При использовании подхода A вы можете сгруппировать несколько тестовых классов в тестовом наборе, например:
TestSuite suite = new TestSuite("All tests");
suite.addTestSuite(DummyTestA.class);
suite.addTestSuite(DummyTestAbis.class);
Но это нельзя использовать с подходом B (так как каждый тестовый класс должен подклассифицировать TestCase). Каков подходящий способ групповых тестов для подхода B?
Изменить: я добавил версии JUnit для обоих подходов
Ответы
Ответ 1
Различие довольно просто:
- расширение
TestCase
- это то, как модульные тесты были написаны в JUnit 3 (конечно, он все еще поддерживается в JUnit 4)
- с помощью аннотации
@Test
- это способ, введенный JUnit 4
Как правило, вы должны выбрать путь аннотации, если не требуется совместимость с JUnit 3 (и/или версия Java раньше, чем Java 5). Новый способ имеет несколько преимуществ:
Чтобы проверить ожидаемые исключения в JUnit 3 TestCase
, вам нужно будет сделать текст явным.
public void testMyException() {
try {
objectUnderTest.myMethod(EVIL_ARGUMENT);
fail("myMethod did not throw an Exception!");
} catch (MyException e) {
// ok!
// check for properties of exception here, if desired
}
}
Ответ 2
Я предпочитаю JUnit 4 (подход аннотации), потому что считаю его более гибким.
Если вы хотите создать тестовый пакет в JUnit 4, вам нужно создать группу классов, которая будет группировать все тесты следующим образом:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({
Test1.class,
Test2.class,
Test3.class,
Test4.class
})public class TestSuite
{
/* empty class */
}
Ответ 3
На ваш вопрос есть неотвеченная часть, и это "Каков надлежащий способ группировать тесты для подхода B?"
Официальным ответом является то, что вы комментируете класс с @RunWith (Suite.class), а затем используйте аннотацию @Suite.SuiteClasses для перечисления классов. Вот как это делают разработчики JUnit (перечисление каждого класса в пакете вручную). Во многом этот подход является улучшением, поскольку тривиальным и интуитивно понятным для добавления перед набором и после поведения пакета (просто добавьте метод @BeforeClass и @AfterClass в класс, аннотированный с помощью @RunWith - намного лучше, чем старый TestFixture).
Однако он имеет шаг назад, в этом аннотации не позволяют динамически создавать список классов, и работа над этой проблемой становится немного уродливой. Вы должны подклассифицировать класс Suite и динамически создавать массив классов в подклассе и передавать его в конструктор Suite, но это неполное решение в том, что другие подклассы Suite (такие как Категории) не работают с ним и по существу не поддерживают динамическую коллекцию тестовых классов.
Ответ 4
Вы должны использовать JUnit 4. Это лучше.
Многие фреймворки начали обесценивать поддержку JUnit 3.8.
Это из справочной документации Spring 3.0:
[Предупреждение] Класс Legacy JUnit 3.8 иерархия устарела
В общем, вы всегда должны пытаться использовать последнюю стабильную версию фреймворка, когда вы начинаете что-то новое.
Ответ 5
-
"Предпочтительным" подходом было бы использование аннотаций, которые были введены с июня 4. Они облегчают многое (см. второй вопрос)
-
Для этого можно использовать простой блок try/catch:
public void testForException() {
try {
Integer.parseInt("just a string");
fail("Exception should have been thrown");
} catch (final Exception e) {
// expected
}
}