18 template <
typename TestClass>
19 class test_class_attribute;
27 unit_test(std::unique_ptr<tunit::event_listener> event_listener,
char* argv[],
int argc) noexcept : arguments(argv + 1, argv + argc), name_(get_filename(argv[0])), event_listener_(std::move(event_listener)) {}
36 if (parse_arguments(this->arguments))
40 std::vector<std::string> tests;
44 return this->list_tests(tests);
48 std::random_device rd;
50 std::shuffle(test_classes().begin(), test_classes().end(), g);
58 unit_test_initialize();
61 this->start_time_point_ = std::chrono::high_resolution_clock::now();
65 this->end_time_point_ = std::chrono::high_resolution_clock::now();
72 }
catch(
const std::exception&) {
87 int repeat_iteration()
const noexcept {
return this->repeat_iteration_;}
93 size_t test_cases_count()
const noexcept {
101 size_t test_count()
const noexcept {
108 size_t aborted_test_count()
const noexcept {
116 std::vector<std::string> aborted_test_names()
const noexcept {
117 std::vector<std::string> names;
124 std::chrono::milliseconds elapsed_time()
const noexcept {
125 using namespace std::chrono_literals;
126 if (this->start_time_point_.time_since_epoch() == 0ms && this->end_time_point_.time_since_epoch() == 0ms)
return 0ms;
127 if (this->end_time_point_.time_since_epoch() == 0ms)
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - this->start_time_point_);
128 return std::chrono::duration_cast<std::chrono::milliseconds>(this->end_time_point_ - this->start_time_point_);
131 size_t ignored_test_count()
const noexcept {
134 count +=
test_class.test()->ignored_test_count();
138 std::vector<std::string> ignored_test_names()
const noexcept {
139 std::vector<std::string> names;
146 size_t failed_test_count()
const noexcept {
154 std::vector<std::string> failed_test_names()
const noexcept {
155 std::vector<std::string> names;
162 size_t succeed_test_count()
const noexcept {
170 std::vector<std::string> succeed_test_names()
const noexcept {
171 std::vector<std::string> names;
179 virtual int list_tests(
const std::vector<std::string>& tests) {
183 virtual bool parse_arguments(
const std::vector<std::string>& args) {
184 for (
auto arg : args) {
202 template <
typename TestClass>
210 void unit_test_cleanup() {
213 void unit_test_initialize() {
216 static std::vector<tunit::registered_test_class>& test_classes() {
217 static std::vector<tunit::registered_test_class> test_classes;
221 std::string get_filename(
const std::string& path) {
222 std::string filename = path;
223 const size_t last_slash_idx = filename.find_last_of(
"\\/");
224 if (std::string::npos != last_slash_idx)
225 filename.erase(0, last_slash_idx + 1);
227 const size_t period_idx = filename.rfind(
'.');
228 if (std::string::npos != period_idx)
229 filename.erase(period_idx);
233 std::string to_string(
const std::chrono::milliseconds& ms) {
234 std::stringstream ss;
238 ss << ms.count() / 1000 <<
"." << std::setfill(
'0') << std::setw(3) << ms.count() % 1000;
242 std::string to_string(
const std::chrono::time_point<std::chrono::system_clock>& time) {
243 std::time_t time_t = std::chrono::system_clock::to_time_t(time);
244 std::tm tm = *std::localtime(&time_t);
245 std::stringstream ss;
246 ss << tm.tm_year + 1900 <<
"-" << std::setfill(
'0') << std::setw(2) << tm.tm_mon <<
"-" << std::setfill(
'0') << std::setw(2) << tm.tm_mday;
247 ss <<
"T" << std::setfill(
'0') << std::setw(2) << tm.tm_hour <<
":" << std::setfill(
'0') << std::setw(2) << tm.tm_min <<
":" << std::setfill(
'0') << std::setw(2) << tm.tm_sec;
252 std::stringstream ss;
253 if (test.not_started() || test.ignored()) ss <<
"notrun";
258 std::string message_to_string(
const tunit::test& test) {
259 std::stringstream ss;
262 ss <<
"Expected: " << test.expect() <<
"�x0A;";
263 ss <<
"But was : " << test.actual();
267 std::string cdata_message_to_string(
const tunit::test& test) {
268 std::stringstream ss;
271 ss <<
"Expected: " << test.expect() << std::endl;
272 ss <<
"But was : " << test.actual();
279 file <<
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
280 file <<
"<testsuites tests=\"" << this->test_count() <<
"\" failures=\"" << this->failed_test_count() <<
"\" disabled=\"" << this->ignored_test_count() <<
"\" errors=\"" << 0 <<
"\" timestamp=\"" << to_string(
tunit::settings::default_settings().start_time()) <<
"\" time=\"" << to_string(this->elapsed_time()) <<
"\" name=\"" << this->name_ <<
"\">" << std::endl;
281 for (
auto& test_class : test_classes()) {
282 file <<
" <testsuite name=\"" << test_class.test()->name() <<
"\" tests=\"" << test_class.test()->test_count() <<
"\" failures=\"" << test_class.test()->failed_test_count() <<
"\" disabled=\"" << test_class.test()->ignored_test_count() <<
"\" error=\"" << test_class.test()->failed_test_count() <<
"\" time=\"" << to_string(test_class.test()->elapsed_time()) <<
"\">" << std::endl;
283 for (
auto& test : test_class.test()->tests()) {
284 file <<
" <testcase name=\"" << test.name() <<
"\" status=\"" << status_to_string(test) <<
"\" time=\"" << to_string(test.elapsed_time()) <<
"\" classname=\"" << test_class.test()->name() <<
"\"";
286 file <<
" />" << std::endl;
288 file <<
">" << std::endl;
289 file <<
" <failure message=\"" << message_to_string(test) <<
"\" type= \"" <<
"\">" <<
"<![CDATA[" << cdata_message_to_string(test) <<
"]]></failure>" << std::endl;
290 file <<
" </testcase>" << std::endl;
293 file <<
" </testsuite>" << std::endl;
295 file <<
"</testsuites>" << std::endl;
300 std::vector<std::string> arguments;
301 std::string name_ =
"AllTests";
302 std::unique_ptr<tunit::event_listener> event_listener_;
303 std::chrono::high_resolution_clock::time_point end_time_point_;
304 int repeat_iteration_ = 0;
305 std::chrono::high_resolution_clock::time_point start_time_point_;
Contains tunit::registered_test_class class.
bool is_match_test_name(const std::string &test_class_name, const std::string &test_name) const noexcept
Return true if a specified test class name and specified test name match with the current filter test...
Definition: settings.h:60
Definition: test_class.h:21
int repeaat_test() const noexcept
Gets repeat tests count.
Definition: settings.h:117
Definition: test_class_attribute.h:11
unsigned int line_number() const noexcept
Gets the line number.
Definition: line_info.h:50
static tunit::settings & default_settings() noexcept
Get default settings intance.
Definition: settings.h:23
int exit_status() const noexcept
Gets exit status.
Definition: settings.h:40
std::chrono::time_point< std::chrono::system_clock > end_time() const noexcept
Gets unit test end time.
Definition: settings.h:134
The template class.
Definition: unit_test.h:23
bool output_color() const noexcept
Gets output color.
Definition: settings.h:72
static tunit::line_info empty()
Return an empty line info.
Definition: line_info.h:31
void repeat_tests(int repeat_tests) noexcept
Sets repeat tests count.
Definition: settings.h:122
bool also_run_ignored_tests() const noexcept
Gets also run ignored test.
Definition: settings.h:30
int run()
Runs all tests in this UnitTest object and prints the result.
Definition: unit_test.h:35
tunit_event_args is the base class for classes containing event data.
Definition: tunit_event_args.h:12
Represent the event listener class.
Definition: event_listener.h:15
bool output_xml() const noexcept
Gets output xml.
Definition: settings.h:80
Definition: base_assert.h:15
The tunit namespace contains a unit test library.
Definition: abort_error.h:8
Contains tunit::settings class.
Contains tunit::event_listener class.
Definition: registered_test_class.h:10
bool show_duration() const noexcept
Gets if show duration for each test.
Definition: settings.h:126
bool shuffle_test() const noexcept
Gets shuffle tests.
Definition: settings.h:97
std::string output_xml_path() const noexcept
Gets output xml path.
Definition: settings.h:88
const std::string & filter_tests() const noexcept
Gets filter tests.
Definition: settings.h:51
int random_seed() const noexcept
Gets random seed value.
Definition: settings.h:107
const std::string & file_path() const noexcept
Gets the file path.
Definition: line_info.h:46
bool list_tests() const noexcept
Gets list tests.
Definition: settings.h:64