C/C ++에 대한 단위 테스트를위한 간단한 하나의 헤더 솔루션.
코드에서 #include "utest.h" !
현재 지원되는 플랫폼은 Linux, MacOS 및 Windows입니다.
현재 지원되는 컴파일러는 GCC, Clang, MSVC의 CL.Exe 및 Clang-Cl.exe입니다.
또한 TCC와 함께 작동하지만 경고와 함께 작동합니다. TCC 컴파일러의 최신 릴리스 (버전 0.9.27)에는 UTEST가 작동하는 기능이 없습니다. 생성자 속성 확장자와 함께 패치 된 TCC를 사용해야합니다. 최근 Ubuntu와 Debian Linux 배포판이 이미 포함 된 패치가 포함 된 TCC를 선박으로 선적했습니다. TCC를 직접 컴파일하면 트렁크 버전을 사용하면 예상대로 작동합니다.
utest.h는 일부 명령 줄 옵션을 지원합니다.
--help 도움말 메시지를 출력하려면 헬프--filter=<filter> 테스트 케이스를 실행하도록 필터링합니다 (특정 불쾌한 테스트 사례를 다시 실행하는 데 유용합니다).--list-tests 한 줄 당 하나의 테스트 이름을 나열합니다. 출력 이름을 --filter 로 전달할 수 있습니다.--output=<output> 테스트 결과와 함께 Xunit XML 파일을 출력합니다 (Jenkins, Travis-CI 및 Appveyor는 테스트 결과를 위해 구문 분석 할 수 있음).--enable-mixed-units 테스트 별 출력이 혼합 장치 (S/MS/US/NS)를 포함 할 수있게합니다.--random-order[=<seed>] 테스트가 실행되는 순서를 무작위로 표시합니다. 선택 사항 인수가 제공되지 않으면 임의의 시작 시드가 사용됩니다. UTEST는 단일 헤더 라이브러리로 C 및 C ++의 단위 테스트의 모든 재미를 가능하게합니다. 라이브러리는 Google의 Googletest 프레임 워크와 유사한 출력을 제공하도록 설계되었습니다.
[==========] 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로 호출하고 모든 테스트 케이스를 인스턴스화하고 단위 테스트 프레임 워크를 실행합니다.
또는 자신의 메인을 작성하고 Utest.h로 전화하려면 대신 하나의 C 또는 C ++ 파일로 호출 할 수 있습니다.
UTEST_STATE ();그런 다음 Utest.h 프레임 워크에 전화 할 준비가되면 :
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 );
}UTEST 매크로는 두 개의 매개 변수를 취합니다. 첫 번째는 테스트 사례가 속한 세트이고 두 번째는 테스트의 이름입니다. 이를 통해 편의를 위해 테스트를 그룹화 할 수 있습니다.
비품 테스트 케이스는 여러 테스트 케이스에서 공유 할 수있는 구조물이있는 것입니다.
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 매크로가 있어야합니다.때로는 동일한 고정물 과 테스트 케이스를 반복적으로 사용하고 싶지만 미묘하게 하나의 변수를 변경합니다. 이것은 인덱스 테스트 케이스가 들어오는 곳입니다.
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가 가지고있는 것을 일치 시키면 각 오류 점검 조건의 두 가지 변형을 제공합니다 - Asserts and Expect. 어제가 실패하면 테스트 케이스는 실행이 중단되고 Utest.h는 다음 테스트 케이스를 계속 실행합니다. 기대치가 실패하면 테스트 사례의 나머지가 여전히 실행되어 추가 점검을 수행 할 수 있습니다.
우리는 현재 UTESTS 내에서 사용할 다음 매크로를 제공합니다.
X가 True (예 : 0이 아닌)로 평가한다고 주장합니다.
UTEST ( foo , bar ) {
int i = 1 ;
ASSERT_TRUE ( i ); // pass!
ASSERT_TRUE ( 42 ); // pass!
ASSERT_TRUE ( 0 ); // fail!
}X가 False로 평가한다고 주장합니다 (예 : 0).
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!
}코드 X가 실행될 때 Exception_type가 던져 질 것이라고 주장합니다.
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 (예 : 0이 아닌)로 평가할 것으로 예상합니다.
UTEST ( foo , bar ) {
int i = 1 ;
EXPECT_TRUE ( i ); // pass!
EXPECT_TRUE ( 42 ); // pass!
EXPECT_TRUE ( 0 ); // fail!
}X가 False (즉, 0)로 평가할 것으로 예상합니다.
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!
}코드 X가 실행될 때 Exception_type가 발생할 것으로 예상합니다.
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!
}코드 X가 실행될 때 Exception_type가 메시지 Exception_Message와 함께 던져 질 것으로 예상합니다.
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 를 건너 뛰는 원인으로보고 한 후 테스트를 '건너 뛰기' 로 표시합니다. 이들은 실패 전에 실행 종료시보고되며 건너 뛰는 테스트 케이스로 인해 프로세스가 0이 아닌 코드로 종료되지 않습니다 .
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/를 참조하십시오.