Простое решение для одного заголовка для единичного тестирования для C/C ++.
Просто #include "utest.h" в вашем коде!
Текущие поддерживаемые платформы - это Linux, MacOS и Windows.
Текущие поддерживаемые компиляторы являются GCC, Clang, MSVC's Cl.exe и Clang-Cl.exe.
Он также работает с TCC, но с предостережением: в последнем выпуске компилятора TCC (версия 0.9.27) не хватает функции для работы. Обязательно используйте TCC, который исправлен с расширением атрибута конструктора. Недавние Ubuntu и Debian Linux Distros Ship Ship с этим патчем уже включен. Если вы сами скомпилируете TCC, используйте версию багажника, и она будет работать, как и ожидалось.
utest.h поддерживает некоторые параметры командной строки:
--help выводу справочного сообщения--filter=<filter> будет отфильтровать тестовые примеры для запуска (полезно для повторного управления одним конкретным примером испытаний на правонарушение).--list-tests будут перечислять имена испытаний, по одному на строку. Выходные имена могут быть переданы в --filter .--output=<output> выведет файл XML XML XML-файла XUNIT (что Jenkins, Travis-Ci и Appveyor могут анализировать для результатов теста).--enable-mixed-units позволит мощности за перспективы содержать смешанные единицы (S/MS/US/NS).--random-order[=<seed>] будет рандомизировать порядок, в котором проводятся тесты. Если необязательный аргумент не предоставлен, то используется случайное начальное семя. Utest - это библиотека единого заголовка, чтобы обеспечить все удовольствие от модульного тестирования в C и C ++. Библиотека была разработана для предоставления вывода, аналогичного Google Googletest Framework:
[==========] Running 1 test cases.
[ RUN ] foo.bar
[ OK ] foo.bar (631ns)
[==========] 1 test cases ran.
[ PASSED ] 1 tests.
В одном файле C или C ++ вы должны вызвать Macro utest_main:
UTEST_MAIN ()Это вызовет utest.h, создаст экземпляры всех испытательных штук и запустит модульную структуру тестирования.
В качестве альтернативы, если вы хотите написать свой собственный Main и вызовать utest.h, вы можете вместо этого, в одном файле C или C ++:
UTEST_STATE ();А потом, когда вы готовы позвонить в Framework Do:
int main ( int argc , const char * const argv []) {
// do your own thing
return utest_main ( argc , argv );
}Чтобы определить тестовый пример для запуска, вы можете сделать следующее;
#include "utest.h"
UTEST ( foo , bar ) {
ASSERT_TRUE ( 1 );
}Matest Macro принимает два параметра - первым из которых является набор, к которому принадлежит тестовый пример, вторым является имя теста. Это позволяет сгруппировать тесты для удобства.
Тестовая тестовая приспособление - это тот, в котором существует структура, которая может быть разделена по нескольким тестам.
struct MyTestFixture {
char c ;
int i ;
float f ;
};
UTEST_F_SETUP ( MyTestFixture ) {
utest_fixture -> c = 'a' ;
utest_fixture -> i = 42 ;
utest_fixture -> f = 3.14f ;
// we can even assert and expect in setup!
ASSERT_EQ ( 42 , utest_fixture -> i );
EXPECT_TRUE (true);
}
UTEST_F_TEARDOWN ( MyTestFixture ) {
// and also assert and expect in teardown!
ASSERT_EQ ( 13 , utest_fixture -> i );
}
UTEST_F ( MyTestFixture , a ) {
utest_fixture -> i = 13 ;
// teardown will succeed because i is 13...
}
UTEST_F ( MyTestFixture , b ) {
utest_fixture -> i = 83 ;
// teardown will fail because i is not 13!
}Некоторые вещи, которые следует отметить, которые были продемонстрированы выше:
UTEST_F_SETUP и UTEST_F_TEARDOWN - даже если они ничего не делают в теле.Иногда вы хотите многократно использовать один и тот же приспособление и Testcase, но, возможно, тонко изменять одну переменную внутри. Вот где появляются индексированные тестовые шкафы.
struct MyTestIndexedFixture {
bool x ;
bool y ;
};
UTEST_I_SETUP ( MyTestIndexedFixture ) {
if ( utest_index < 30 ) {
utest_fixture -> x = utest_index & 1 ;
utest_fixture -> y = ( utest_index + 1 ) & 1 ;
}
}
UTEST_I_TEARDOWN ( MyTestIndexedFixture ) {
EXPECT_LE ( 0 , utest_index );
}
UTEST_I ( MyTestIndexedFixture , a , 2 ) {
ASSERT_TRUE ( utest_fixture -> x | utest_fixture -> y );
}
UTEST_I ( MyTestIndexedFixture , b , 42 ) {
// this will fail when the index is >= 30
ASSERT_TRUE ( utest_fixture -> x | utest_fixture -> y );
}Примечание:
Сопоставление того, что есть Googletest, мы предоставляем два варианта каждого из условий проверки ошибок - утверждает и ожидает. Если утверждение не удается, тестовый пример прекратит выполнение, и utest.h продолжит запуск следующего тестового примера. Если ожидание не удается, оставшаяся часть тестового примера все еще будет выполнена, что позволяет проводить дополнительные проверки.
В настоящее время мы предоставляем следующие макросы, которые будут использоваться в условиях:
Утверждает, что x оценивает истину (например, ненулевой).
UTEST ( foo , bar ) {
int i = 1 ;
ASSERT_TRUE ( i ); // pass!
ASSERT_TRUE ( 42 ); // pass!
ASSERT_TRUE ( 0 ); // fail!
}Утверждает, что x оценивает ложь (например, ноль).
UTEST ( foo , bar ) {
int i = 0 ;
ASSERT_FALSE ( i ); // pass!
ASSERT_FALSE ( 1 ); // fail!
}Утверждает, что x и y равны.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 42 ;
ASSERT_EQ ( a , b ); // pass!
ASSERT_EQ ( a , 42 ); // pass!
ASSERT_EQ ( 42 , b ); // pass!
ASSERT_EQ ( 42 , 42 ); // pass!
ASSERT_EQ ( a , b + 1 ); // fail!
}Утверждает, что X и Y не равны.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
ASSERT_NE ( a , b ); // pass!
ASSERT_NE ( a , 27 ); // pass!
ASSERT_NE ( 69 , b ); // pass!
ASSERT_NE ( 42 , 13 ); // pass!
ASSERT_NE ( a , 42 ); // fail!
}Утверждает, что X меньше Y.
UTEST ( foo , bar ) {
int a = 13 ;
int b = 42 ;
ASSERT_LT ( a , b ); // pass!
ASSERT_LT ( a , 27 ); // pass!
ASSERT_LT ( 27 , b ); // pass!
ASSERT_LT ( 13 , 42 ); // pass!
ASSERT_LT ( b , a ); // fail!
}Утверждает, что X меньше или равна Y.
UTEST ( foo , bar ) {
int a = 13 ;
int b = 42 ;
ASSERT_LE ( a , b ); // pass!
ASSERT_LE ( a , 27 ); // pass!
ASSERT_LE ( a , 13 ); // pass!
ASSERT_LE ( 27 , b ); // pass!
ASSERT_LE ( 42 , b ); // pass!
ASSERT_LE ( 13 , 13 ); // pass!
ASSERT_LE ( 13 , 42 ); // pass!
ASSERT_LE ( b , a ); // fail!
}Утверждает, что X больше Y.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
ASSERT_GT ( a , b ); // pass!
ASSERT_GT ( a , 27 ); // pass!
ASSERT_GT ( 27 , b ); // pass!
ASSERT_GT ( 42 , 13 ); // pass!
ASSERT_GT ( b , a ); // fail!
}Утверждает, что x больше или равен Y.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
ASSERT_GE ( a , b ); // pass!
ASSERT_GE ( a , 27 ); // pass!
ASSERT_GE ( a , 13 ); // pass!
ASSERT_GE ( 27 , b ); // pass!
ASSERT_GE ( 42 , b ); // pass!
ASSERT_GE ( 13 , 13 ); // pass!
ASSERT_GE ( 42 , 13 ); // pass!
ASSERT_GE ( b , a ); // fail!
}Утверждает, что строки x и y равны.
UTEST ( foo , bar ) {
char * a = "foo" ;
char * b = "bar" ;
ASSERT_STREQ ( a , a ); // pass!
ASSERT_STREQ ( b , b ); // pass!
ASSERT_STREQ ( a , b ); // fail!
}Утверждает, что строки x и y не равны.
UTEST ( foo , bar ) {
char * a = "foo" ;
char * b = "bar" ;
ASSERT_STRNE ( a , b ); // pass!
ASSERT_STRNE ( a , a ); // fail!
}Утверждает, что строки x и y равны длине строки x.
UTEST ( foo , bar ) {
char * a = "foobar" ;
char * b = "foo" ;
ASSERT_STRNEQ ( a , a ); // pass!
ASSERT_STRNEQ ( b , b ); // pass!
ASSERT_STRNEQ ( a , b ); // pass!
}Утверждает, что строки x и y не равны длине строки x.
UTEST ( foo , bar ) {
char * a = "foobar" ;
char * b = "bar" ;
ASSERT_STRNNE ( a , b ); // pass!
ASSERT_STRNNE ( a , a ); // fail!
}Утверждает, что значения с плавающей точкой x и y находятся на расстоянии Эпсилона друг от друга.
UTEST ( foo , bar ) {
float a = 42.0f ;
float b = 42.01f ;
ASSERT_NEAR ( a , b , 0.01f ); // pass!
ASSERT_NEAR ( a , b , 0.001f ); // fail!
}Утверждает, что exception_type будет выброшен при выполнении кода X.
void foo ( int bar) {
if (bar == 1 )
throw std::range_error;
}
UTEST (foo, bar) {
ASSERT_EXCEPTION ( foo ( 1 ), std::range_error); // pass!
ASSERT_EXCEPTION ( foo ( 2 ), std::range_error); // fail!
ASSERT_EXCEPTION ( foo ( 1 ), std:: exception ); // fail!
}Ожидает, что X оценивает True (т. Е. Ненлере).
UTEST ( foo , bar ) {
int i = 1 ;
EXPECT_TRUE ( i ); // pass!
EXPECT_TRUE ( 42 ); // pass!
EXPECT_TRUE ( 0 ); // fail!
}Ожидает, что X оценивает false (то есть ноль).
UTEST ( foo , bar ) {
int i = 0 ;
EXPECT_FALSE ( i ); // pass!
EXPECT_FALSE ( 1 ); // fail!
}Ожидает, что X и Y равны.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 42 ;
EXPECT_EQ ( a , b ); // pass!
EXPECT_EQ ( a , 42 ); // pass!
EXPECT_EQ ( 42 , b ); // pass!
EXPECT_EQ ( 42 , 42 ); // pass!
EXPECT_EQ ( a , b + 1 ); // fail!
}Ожидает, что X и Y не равны.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
EXPECT_NE ( a , b ); // pass!
EXPECT_NE ( a , 27 ); // pass!
EXPECT_NE ( 69 , b ); // pass!
EXPECT_NE ( 42 , 13 ); // pass!
EXPECT_NE ( a , 42 ); // fail!
}Ожидает, что X меньше Y.
UTEST ( foo , bar ) {
int a = 13 ;
int b = 42 ;
EXPECT_LT ( a , b ); // pass!
EXPECT_LT ( a , 27 ); // pass!
EXPECT_LT ( 27 , b ); // pass!
EXPECT_LT ( 13 , 42 ); // pass!
EXPECT_LT ( b , a ); // fail!
}Ожидает, что X меньше или равна Y.
UTEST ( foo , bar ) {
int a = 13 ;
int b = 42 ;
EXPECT_LE ( a , b ); // pass!
EXPECT_LE ( a , 27 ); // pass!
EXPECT_LE ( a , 13 ); // pass!
EXPECT_LE ( 27 , b ); // pass!
EXPECT_LE ( 42 , b ); // pass!
EXPECT_LE ( 13 , 13 ); // pass!
EXPECT_LE ( 13 , 42 ); // pass!
EXPECT_LE ( b , a ); // fail!
}Ожидает, что X больше Y.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
EXPECT_GT ( a , b ); // pass!
EXPECT_GT ( a , 27 ); // pass!
EXPECT_GT ( 27 , b ); // pass!
EXPECT_GT ( 42 , 13 ); // pass!
EXPECT_GT ( b , a ); // fail!
}Ожидает, что X больше или равна Y.
UTEST ( foo , bar ) {
int a = 42 ;
int b = 13 ;
EXPECT_GE ( a , b ); // pass!
EXPECT_GE ( a , 27 ); // pass!
EXPECT_GE ( a , 13 ); // pass!
EXPECT_GE ( 27 , b ); // pass!
EXPECT_GE ( 42 , b ); // pass!
EXPECT_GE ( 13 , 13 ); // pass!
EXPECT_GE ( 42 , 13 ); // pass!
EXPECT_GE ( b , a ); // fail!
}Ожидает, что строки x и y равны.
UTEST ( foo , bar ) {
char * a = "foo" ;
char * b = "bar" ;
EXPECT_STREQ ( a , a ); // pass!
EXPECT_STREQ ( b , b ); // pass!
EXPECT_STREQ ( a , b ); // fail!
}Ожидает, что строки x и y не равны.
UTEST ( foo , bar ) {
char * a = "foo" ;
char * b = "bar" ;
EXPECT_STRNE ( a , b ); // pass!
EXPECT_STRNE ( a , a ); // fail!
}Ожидает, что строки x и y равны длине строки x.
UTEST ( foo , bar ) {
char * a = "foobar" ;
char * b = "foo" ;
EXPECT_STRNEQ ( a , a ); // pass!
EXPECT_STRNEQ ( b , b ); // pass!
EXPECT_STRNEQ ( a , b ); // pass!
}Ожидает, что строки x и y не равны длине строки x.
UTEST ( foo , bar ) {
char * a = "foobar" ;
char * b = "bar" ;
EXPECT_STRNNE ( a , b ); // pass!
EXPECT_STRNNE ( a , a ); // fail!
}Ожидает, что значения с плавающей точкой x и y находятся на расстоянии Эпсилона друг от друга.
UTEST ( foo , bar ) {
float a = 42.0f ;
float b = 42.01f ;
EXPECT_NEAR ( a , b , 0.01f ); // pass!
EXPECT_NEAR ( a , b , 0.001f ); // fail!
}Ожидает, что Exception_type будет выброшен при выполнении кода X.
void foo ( int bar) {
if (bar == 1 )
throw std::range_error;
}
UTEST (foo, bar) {
EXPECT_EXCEPTION ( foo ( 1 ), std::range_error); // pass!
EXPECT_EXCEPTION ( foo ( 2 ), std::range_error); // fail!
EXPECT_EXCEPTION ( foo ( 1 ), std:: exception ); // fail!
}Ожидает, что exception_type будет брошен с сообщением exception_message, когда будет выполнен код x.
void foo ( int bar) {
if (bar == 1 )
throw std::range_error ( " bad bar " );
}
UTEST (foo, bar) {
EXPECT_EXCEPTION_WITH_MESSAGE ( foo ( 1 ), std::range_error, " bad bar " ); // pass!
EXPECT_EXCEPTION_WITH_MESSAGE ( foo ( 2 ), std::range_error, " bad bar2 " ); // fail!
EXPECT_EXCEPTION_WITH_MESSAGE ( foo ( 1 ), std:: exception , " bad bar " ); // fail!
} Этот макрос позволяет отметить тестовый пример как пропущенный - например. что тестовый пример не должен быть выполнен. Тест перестанет работать по мере выполнения макроса, сообщать о msg в качестве причины пропущенного и отмечать тест как «пропущенный» . Они будут сообщены в конце исполнения перед сбоями, а пропущенные тестовые случаи не приведут к выходу процесса с помощью ненулевого кода.
UTEST ( foo , bar ) {
UTEST_SKIP ( "Need to implement this test!" );
}Кроме того, чтобы дать возможность наличия пользовательских сообщений в тестах на неисправность, все макросы могут использоваться с суффиксом, называемым «_MSG», который получает дополнительный параметр, который является строкой с пользовательским сообщением для печати в случае сбоя.
Например:
UTEST ( foo , bar ) {
int i = 1 ;
EXPECT_TRUE_MSG ( i , "custom message" ); // pass!
EXPECT_TRUE_MSG ( 42 , "custom message" ); // pass!
EXPECT_TRUE_MSG ( 0 , "custom message" ); // fail! (with the following output)
} test.cpp:42: Failure
Expected : true
Actual : false
Message : custom message
[ FAILED ] foo.bar (8086ns)
Библиотека поддерживает утверждение на любом встроенном интератном, плавающем точке или типе указателя.
Это бесплатное и незаключенное программное обеспечение, выпущенное в общественном достоянии.
Любой может бесплатно копировать, модифицировать, публиковать, использовать, компилировать, продавать или распространять это программное обеспечение, либо в форме исходного кода, либо в качестве составленного двоичного, для любых целей, коммерческих или некоммерческих и любых средств.
В юрисдикциях, которые признают законы об авторском праве, автор или авторы этого программного обеспечения посвящают любой интересный интерес к программному обеспечению в общественное достояние. Мы делаем эту посвящение в интересах общественности в целом и на ущерб нашим наследникам и преемникам. Мы намереваемся стать явным актом отказа от вечности всех нынешних и будущих прав на это программное обеспечение в соответствии с законодательством об авторском праве.
Программное обеспечение предоставляется «как есть», без гарантии любого рода, явного или подразумеваемого, включая, помимо прочего, гарантии товарной пригодности, пригодности для определенной цели и несоответствия. Ни в коем случае авторы не должны нести ответственность за любые претензии, ущерб или другую ответственность, будь то в действии контракта, деликте или иным образом, возникающим из или в связи с программным обеспечением или использованием или другими сделками в программном обеспечении.
Для получения дополнительной информации, пожалуйста, обратитесь к http://unlicense.org/