Некоторые тесты необходимо повторить для ряда различных входных параметров. Одним из способов достижения этого является ручная регистрация тестового случая для каждого параметра. Вы также можете вызвать функцию тестирования со всеми параметрами вручную из вашего тестового случая, например:
voidsingle_test(inti){BOOST_TEST(/* test assertion */);}voidcombined_test(){intparams[]={1,2,3,4,5};std::for_each(params,params+5,&single_test);}
Приведенный выше подход имеет несколько недостатков:
Логика проведения тестов находится внутри самого теста:<single_test>в приведенном выше примере выполняется из тест-кейса<combined_test>, в то время как его выполнение будет лучше обрабатываться.Единичная система испытаний
В случае фатального отказа для одного из значений в<param>массиве выше (скажем, отказ в<BOOST_TEST_REQUIRE>), тест<combined_test>прерывается, и выполняется следующий тестовый случай в тестовом дереве.
В случае неудачи отчетность не является достаточно точной: тест, безусловно, должен быть повторен во время сеансов отладки человеком или в самом тесте должна быть реализована дополнительная логика для отчетности.
В некоторых обстоятельствах хотелось бы провести параметризированное испытание на произвольном большомнаборе значений. Перечисление параметров вручную не является решением, которое хорошо масштабируется, особенно когда эти параметры могут быть описаны в другой функции, которая генерирует эти значения. Однако это решение также имеет ограничения.
Генерирующие функции: Предположим, что у нас есть функция<func(floatf)>, где<f>- любое число в [0, 1]. Нас не интересует точная стоимость, но мы хотели бы проверить<func>. Что же, вместо того чтобы писать<f>, против которых<func>будет испытано, мы выбираем случайным образом<f>в [0, 1]? А как насчет того, что вместо того, чтобы иметь только одно значение для<f>, мы проверяем произвольно много чисел? Из этого небольшого примера легко понять, что тесты, требующие параметров, являются более мощными, когда вместо записи постоянных значений в тесте обеспечивается генерирующая функция.
Масштабируемость: Предположим, что у нас есть тест-кейс<func1>, на котором мы тестируем<N>значения, записанные как постоянные в тестовом файле. Что гарантирует тест? У нас есть гарантия, что<func1>работает над этими<N>ценностями. Однако в этой ситуации<N>обязательно конечно и обычно мало. Как мы можем увеличить или увеличить<N>? Одно из решений состоит в том, чтобы иметь возможность генерировать новые значения и определять тест на классевозможных входов для<func1>, на которых функция должна иметь определенное поведение. В какой-то степени<N>константа, записанная в тесте, является лишь отрывком из возможных входов<func1>, а работа над классом входов придает тесту большую гибкость и мощность.
Состав: Предположим, что у нас уже есть тестовые случаи для двух функций<func1>и<func2>, принимая в качестве аргумента типы<T1>и<T2>соответственно. Теперь мы хотели бы проверить новые функции<func3>, которые принимают в качестве аргумента тип<T3>, содержащий<T1>и<T2>, и вызов<func1>и<func2>с помощью известного алгоритма. В этом примере
<
// Returns the log of x// Precondition: x strictly positive.doublefast_log(doublex);// Returns 1/(x-1)// Precondition: x != 1doublefast_inv(doublex);structdummy{unsignedintfield1;unsignedintfield2;};doublefunc3(dummyvalue){return0.5*(exp(fast_log(value.field1))/value.field1+value.field2/fast_inv(value.field2));}
>
<func3>наследуется от предварительных условий<fast_log>и<fast_inv>: В<(0,+infinity)>и<[-C,+C]-{1}>для<field1>и<field2>соответственно<C>является постоянным произвольно большим.
Как определено выше,<func3>должен быть близок к 1 везде в своей области определения.
Мы хотели бы повторно использовать свойства<fast_log>и<fast_inv>в составной функции<func3>и утверждать, что<func3>хорошо определена над произвольной областью большого определения.
Having parametrized tests on func3
hardly tells us about the possible numerical properties or instabilities
close to the point {field1=0,field2=1}. Indeed, the parametrized test may
test for some points around (0,1), but will fail to provide an asymptotic behavior of the function close to
this point.
Предоставляемые услугиВ рамках Единой системы испытанийбыли рассмотрены вопросы, описанные выше:
наборы данныхоблегчают описание класса входов для тестовых случаев. Наборы данных также реализуют несколько операций, которые позволяют их комбинациям создавать новые, более сложные наборы данных.
два макроса,<BOOST_DATA_TEST_CASE>и<BOOST_DATA_TEST_CASE_F>, соответственно без и с опорой крепления, используются для декларирования и регистрации тестового случая по совокупности значений (образцов),
Каждый тестовый случай, связанный с уникальным значением, выполняется независимо от других. Эти тесты охраняются таким же образом, как и обычные тестовые случаи, что делает выполнение тестов над каждым образцом набора данных изолированным, надежным, повторяемым и облегчает отладку.
Несколько наборов данных, генерирующих функции, предоставляются.Единичная система испытаний
Остальная часть этого раздела охватывает понятия и функции, предоставляемые.Unit Test Frameworkо тестах на основе данных, в частности:
Статья Data-driven test cases раздела Boost.Test Test cases может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.