Catch test case order

Могу ли я гарантировать порядок исполнения с несколькими TEST_CASEс Ловить? Я тестирую некоторый код, используя LLVM, и у них есть какое-то отвратительное глобальное состояние, которое мне нужно явно инициализировать.

Прямо сейчас у меня есть один тестовый пример, который выглядит так:

TEST_CASE("", "") {
// Initialize really shitty LLVM global variables.
llvm::InitializeAllTargets();
llvm::InitializeAllTargetMCs();
llvm::InitializeAllAsmPrinters();
llvm::InitializeNativeTarget();
llvm::InitializeAllAsmParsers();
// Some per-test setup I can make into its own function
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile...));
CHECK_NOTHROW(Interpret(...));
CHECK_THROWS(Compile(...));
CHECK_THROWS(Compile(...));
}

То, что я хочу, — это перестроить его на три части. TEST_CASE,

  • один для тестов, которые должны пройти компиляцию,
  • один для испытаний, которые должны провалиться, и
  • один для тестов, которые должны пройти интерпретацию (и в будущем, возможно, дальнейшие такие разделы).

Но я не могу просто переместить содержимое теста в другое TEST_CASE потому что если это TEST_CASE вызывается перед тем, который устанавливает неудобные глобальные переменные, тогда они не будут инициализированы, и тестирование будет провалено.

1

Решение

Я немного опоздал, потому что только что увидел — извините (в будущем вы можете публиковать вопросы, связанные с Catch, на Поймать форум или список проблем на GitHub, при необходимости.

Во всяком случае — я не знаю, что вы сделали в конце, но в этом случае кажется, что вы просто хотите сгруппировать каждый набор утверждений в SECTIONs.

TEST_CASE() {
// Initialize really shitty LLVM global variables.
llvm::InitializeAllTargets();
llvm::InitializeAllTargetMCs();
llvm::InitializeAllAsmPrinters();
llvm::InitializeNativeTarget();
llvm::InitializeAllAsmParsers();

SECTION( "should pass compilation" ) {
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile...));
}
SECTION( "should pass interpretation" ) {
CHECK_NOTHROW(Interpret(...));
}
SECTION( "Should fail compilation" ) {
CHECK_THROWS(Compile(...));
CHECK_THROWS(Compile(...));
}
}

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

… если код инициализации не должен быть выполнен только один раз — в этом случае вы можете либо поместить статический инициализатор, как предложил @paddy (класс, который вызывает инициализаторы в своем конструкторе, а затем просто создать глобальный экземпляр), или вы можете защитить блок кода инициализации с if на статическом bool.

3

Другие решения

Если решение Фила по какой-то причине не подходит, вот альтернатива:

struct TestFixture {
static bool _initialised;
TestFixture() {
if (!_initialised) {
llvm::InitializeAllTargets();
llvm::InitializeAllTargetMCs();
llvm::InitializeAllAsmPrinters();
llvm::InitializeNativeTarget();
llvm::InitializeAllAsmParsers();
_initialised = true;
}
}
};

bool TestFixture::_initialised = false;

TEST_CASE_METHOD(TestFixture, "should pass compilation" ) {
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
CHECK_NOTHROW(Compile(...));
}

TEST_CASE_METHOD(TestFixture, "should pass interpretation" ) {
CHECK_NOTHROW(Interpret(...));
}

TEST_CASE_METHOD(TestFixture, "Should fail compilation" ) {
CHECK_THROWS(Compile(...));
CHECK_THROWS(Compile(...));
}

В этом примере кода не имеет значения, какой TEST_CASE запускается первым, потому что первый запускающий вызовет функции инициализации llvm, а остальные пропустят это из-за bool.

Этот код использует поддержку Catch’s Test Fixture, которую мы широко используем в моей повседневной работе: https://github.com/philsquared/Catch/blob/master/docs/test-fixtures.md

1

По вопросам рекламы [email protected]