본문 바로가기

Dev/C++

Catch (A modern, C++-native, header-only, framework for unit-tests, TDD and BDD)

Github : https://github.com/philsquared/Catch

Tutorial : https://github.com/philsquared/Catch/blob/master/docs/tutorial.md


# 특징

- CppUnit, Google Test, Boost.Test 등등 다른 프레임웍크에 비해 의존성이 없는 헤더파일(catch.hpp) 하나면 사용 할 수 있음 

  * C++ Test Framework 비교 

- 별도 빌드 모듈로 운영 할 수도 있음

- 크로스 플랫폼 지원


# 사용 

- TEST_CASE 라는 기본 단위 테스트에 SECTION이라는 작은 부분으로 나누어서 테스트 할 수 있음

- 기본적으로 REQUIRE 와 CHECK 의 평가식을 이용하여 로직 검증. 

- REQUIRE 와 CHECK 차이점은, REQUIRE는 평가 실패 시 진행을 중지하고 다음 SECTION 이나 TEST_CASE 로 이동하는 반면, CHECK는 평가 결과와 관계없이 바로 다음 평가를 실행 

- REQUIRE_FALSE, CHECK_FALSE - 실패 평가 (NOT 조건)  

- REQUIRE_THROWS, CHECK_THROWS - 예외가 발생하면 성공 

- REQUIRE_NOTHROW, CHECK_NOTHROW - 예외가 발생하지 않으면 성공 

- INFO, WARN, FAILD - 각 실패 단계에 따른 메세지 출력

- CAPTURE - 주어진 식과 값 출력 (테스트 실패시 노출)

#define CATCH_CONFIG_MAIN - 메인함수 자동으로 생성 및 실행 


# 결론

- 진입장벽 낮으며 사용하기 편리하고 다른 테스트 프레임워크 만큼 많은 기능 제공하는듯

- 살짝 아쉬운점은 출력이 좀더 반듯? 하게 나왔으면 하는 생각. 


# 예제

 
#include <iostream>
#include <string>
#include <memory>
using namespace std;
 
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
 
TEST_CASE("std::string", "test")
{
string s = "abcedf";
 
REQUIRE(s.capacity() > 0);
 
SECTION("TEST 1") {
REQUIRE(s.length() > 0);
REQUIRE(s[0] == 'a');
string ss(move(s));
CAPTURE(ss);
 
CAPTURE(s.capacity());
REQUIRE(s.capacity() == 0); // FAILED
REQUIRE(ss.length() > 0);
}
 
s = "ab";
 
SECTION("TEST 2") {
REQUIRE_THROWS([]{ throw "error"; }());
REQUIRE_THROWS(s.at(5) = 'e');
REQUIRE_NOTHROW(s.at(0) = 's');
 
}
}
 
 
TEST_CASE("std::shared_ptr", "test")
{
auto sp = std::make_shared<string>("init");
CHECK(sp);
 
auto sp2 = sp;
CHECK(sp.use_count() == 2);
 
weak_ptr<string> wp = sp;
CHECK(sp.use_count() == 2);
 
SECTION("WeakPtr 1") {
auto spp = wp.lock();
CAPTURE(sp.use_count());
CAPTURE(spp.use_count());
CHECK(spp.use_count() == 3);
}
 
sp.reset();
sp2.reset();
 
SECTION("WeakPtr 2") {
auto spp = wp.lock();
CAPTURE(sp.use_count());
CAPTURE(spp.use_count());
CHECK(spp); // FAILED
}



# 결과