JUnit: включение утверждений в тестируемом классе
Я несколько раз несколько раз выполнял инструкции Java assert
, которые не сбой в наборе тестов JUnit, потому что утверждения не были включены в JUnit JVM-экземпляре. Чтобы быть ясными, это утверждения "черного ящика" внутри реализаций (проверка инвариантов и т.д.), А не утверждения, определенные самими тестами JUnit. Конечно, я бы хотел поймать любые подобные ошибки утверждения в тестовом наборе.
Очевидным решением является очень осторожное использование -enableassertions
всякий раз, когда я запускаю JUnit, но я бы предпочел более надежное решение. Один из вариантов заключается в добавлении следующего теста в каждый тестовый класс:
@Test(expected=AssertionError.class)
public void testAssertionsEnabled() {
assert(false);
}
Есть ли более автоматический способ сделать это? Конфигурация системы для JUnit? Динамический вызов, который я мог бы ввести в метод setUp()
?
Ответы
Ответ 1
В Eclipse вы можете перейти на Windows
→ Preferences
→ Java
→ JUnit
, который имеет возможность добавлять -ea
каждый раз при создании новой конфигурации запуска. Он добавляет параметр -ea
в конфигурацию отладки.
Полный текст рядом с флажком
Добавьте "-ea" в аргументы VM при создании нового запуска JUnit Конфигурация
Ответ 2
Я предлагаю три возможных (простых?) исправления, которые работают для меня после быстрого теста (но вам может потребоваться проверить побочные эффекты использования статического инициализационного блока)
1.) Добавьте блок статического инициализатора в те тестовые ячейки, которые полагаются на утверждения, которые включены
import ....
public class TestXX....
...
static {
ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
}
...
@Test(expected=AssertionError.class)
...
...
2.) Создайте базовый класс, который расширяется всеми вашими тестовыми классами, для которых требуются утверждения
public class AssertionBaseTest {
static {
//static block gets inherited too
ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
}
}
3.) Создайте тестовый набор, который запускает все ваши тесты
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
//list of comma-separated classes
/*Foo.class,
Bar.class*/
})
public class AssertionTestSuite {
static {
//should run before the test classes are loaded
ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
}
public static void main(String args[]) {
org.junit.runner.JUnitCore.main("AssertionTestSuite");
}
}
Ответ 3
В качестве альтернативы вы можете скомпилировать свой код таким образом, чтобы утверждения не могли быть отключены. В Java 6 вы можете использовать "fa.jar - проверка принудительной проверки, даже если она не включена" , небольшой русик.
Ответ 4
Как мой друг говорит... зачем тратить время, чтобы написать утверждение, если вы просто отключите его?
Учитывая эту логику, все утверждения assert должны стать:
if(!(....))
{
// or some other appropriate RuntimeException subclass
throw new IllegalArgumentException(".........");
}
Чтобы ответить на ваш вопрос, вы, вероятно, захотите: -)
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
FooTest.class,
BarTest.class
})
public class TestSuite
{
@BeforeClass
public static void oneTimeSetUp()
{
ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true);
}
}
Затем запустите тестовый пакет, а не каждый тест. Это должно (работает в моем тестировании, но я не читал внутренности кода среды JUnit) приводит к тому, что статус утверждения устанавливается до загрузки любого из тестовых классов.