Подтвердить что ты не робот

JUnit: включение утверждений в тестируемом классе

Я несколько раз несколько раз выполнял инструкции Java assert, которые не сбой в наборе тестов JUnit, потому что утверждения не были включены в JUnit JVM-экземпляре. Чтобы быть ясными, это утверждения "черного ящика" внутри реализаций (проверка инвариантов и т.д.), А не утверждения, определенные самими тестами JUnit. Конечно, я бы хотел поймать любые подобные ошибки утверждения в тестовом наборе.

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

  @Test(expected=AssertionError.class)
  public void testAssertionsEnabled() {
    assert(false);
  }

Есть ли более автоматический способ сделать это? Конфигурация системы для JUnit? Динамический вызов, который я мог бы ввести в метод setUp()?

4b9b3361

Ответ 1

В Eclipse вы можете перейти на WindowsPreferencesJavaJUnit, который имеет возможность добавлять -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");
    }
}

Ответ 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) приводит к тому, что статус утверждения устанавливается до загрузки любого из тестовых классов.