Skip to content

Commit b186145

Browse files
author
Sebastiano Merlino
committed
Added autotest functionality and statistics
1 parent db3928a commit b186145

File tree

1 file changed

+165
-68
lines changed

1 file changed

+165
-68
lines changed

test/littletest.hpp

Lines changed: 165 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -31,33 +31,59 @@
3131
#include <sstream>
3232
#include <algorithm>
3333
#include <sys/time.h>
34+
#include <vector>
3435

3536
#define WARN 0
3637
#define CHECK 1
3738
#define ASSERT 2
3839

3940
#define LT_BEGIN_TEST_ENV() int main() {
41+
4042
#define LT_END_TEST_ENV() return 0; }
43+
44+
#define AUTORUN_TESTS() \
45+
std::vector<test_base*>::iterator autorun_it; \
46+
for(autorun_it = auto_test_vector.begin(); autorun_it != auto_test_vector.end(); ++autorun_it) \
47+
auto_test_runner((*autorun_it)); \
48+
auto_test_runner();
49+
4150
#define LT_TEST(name) name ## _obj
51+
4252
#define LT_CREATE_RUNNER(suite_name, runner_name) \
43-
std::cout << "** Initializing Runner \"" << #runner_name << "\" for suite \"" << #suite_name << "\" **" << std::endl; \
44-
test_runner<suite_name> runner_name
53+
std::cout << "** Initializing Runner \"" << #runner_name << "\" **" << std::endl; \
54+
test_runner runner_name
55+
4556
#define LT_RUNNER(runner_name) runner_name
46-
#define LT_SUITE(name) struct name : public suite<name>
57+
58+
#define LT_BEGIN_SUITE(name) \
59+
struct name : public suite<name> \
60+
{
61+
62+
#define LT_END_SUITE(name) \
63+
};
64+
4765
#define LT_CHECKPOINT() tr->set_checkpoint(__FILE__, __LINE__)
66+
4867
#define LT_BEGIN_TEST(suite_name, test_name) \
49-
struct test_name : public suite_name, test<suite_name, test_name> \
68+
struct test_name : public suite_name, test<test_name> \
5069
{ \
51-
public: \
52-
static const char* name; \
53-
void operator()(test_runner<suite_name>* tr) \
70+
test_name() \
71+
{ \
72+
name = #test_name; \
73+
auto_test_vector.push_back(this); \
74+
} \
75+
void operator()(test_runner* tr) \
5476
{
5577

5678
#define LT_END_TEST(test_name) \
5779
} \
5880
}; \
59-
const char* test_name::name = #test_name; \
60-
test_name test_name ## _obj;
81+
test_name test_name ## _obj; \
82+
83+
#define LT_BEGIN_AUTO_TEST(suite_name, test_name) LT_BEGIN_TEST(suite_name, test_name)
84+
85+
#define LT_END_AUTO_TEST(test_name) \
86+
LT_END_TEST(test_name) \
6187

6288
#define LT_SWITCH_MODE(mode) \
6389
switch(mode) \
@@ -304,60 +330,12 @@ class suite
304330
suite(const suite<suite_impl>& s) { }
305331
};
306332

307-
template <class suite_impl>
308-
struct test_runner;
309-
310-
template <class suite_impl, class test_impl>
311-
class test
333+
double calculate_duration(timeval* before, timeval* after)
312334
{
313-
private:
314-
bool run_test(test_runner<suite_impl>* tr)
315-
{
316-
timeval before, after;
317-
static_cast<test_impl* >(this)->suite_set_up();
318-
bool result = false;
319-
try
320-
{
321-
gettimeofday(&before, NULL);
322-
(*static_cast<test_impl*>(this))(tr);
323-
result = true;
324-
}
325-
catch(assert_unattended& au)
326-
{
327-
}
328-
catch(std::exception& e)
329-
{
330-
std::cout << "Exception during " << test_impl::name << " run" << std::endl;
331-
std::cout << e.what() << std::endl;
332-
if(tr->last_checkpoint_line != -1)
333-
std::cout << "Last checkpoint in " << tr->last_checkpoint_file << ":" << tr->last_checkpoint_line << std::endl;
334-
}
335-
catch(...)
336-
{
337-
std::cout << "Exception during " << test_impl::name << " run" << std::endl;
338-
if(tr->last_checkpoint_line != -1)
339-
std::cout << "Last checkpoint in " << tr->last_checkpoint_file << ":" << tr->last_checkpoint_line << std::endl;
340-
}
341-
gettimeofday(&after, NULL);
342-
343-
double duration = ((after.tv_sec * 1000 + (after.tv_usec / 1000.0)) -
344-
(before.tv_sec * 1000 + (before.tv_usec / 1000.0)));
345-
346-
tr->add_good_time(duration);
347-
348-
std::cout << "Time spent during \"" << test_impl::name << "\": " << duration << std::endl;
349-
350-
static_cast<test_impl* >(this)->suite_tier_down();
351-
return result;
352-
}
353-
protected:
354-
test() { }
355-
test(const test<suite_impl, test_impl>& t) { }
335+
return ((after->tv_sec * 1000 + (after->tv_usec / 1000.0)) -
336+
(before->tv_sec * 1000 + (before->tv_usec / 1000.0)));
337+
}
356338

357-
friend class test_runner<suite_impl>;
358-
};
359-
360-
template <class suite_impl>
361339
struct test_runner
362340
{
363341
public:
@@ -367,25 +345,28 @@ struct test_runner
367345
failures_counter(0),
368346
last_checkpoint_file(""),
369347
last_checkpoint_line(-1),
370-
good_time_total(0.0)
348+
good_time_total(0.0),
349+
total_set_up_time(0.0),
350+
total_tier_down_time(0.0),
351+
total_time(0.0)
371352
{
372353
}
373354

374355
template <class test_impl>
375-
test_runner& run(test<suite_impl, test_impl>& t)
356+
test_runner& run(test_impl* t)
376357
{
377358
std::cout << "Running test (" <<
378359
test_counter << "): " <<
379-
static_cast<test_impl*>(&t)->name << std::endl;
360+
t->name << std::endl;
380361

381-
t.run_test(this);
362+
t->run_test(this);
382363

383364
test_counter++;
384365
return *this;
385366
}
386367

387368
template <class test_impl>
388-
test_runner& operator()(test<suite_impl, test_impl>& t)
369+
test_runner& operator()(test_impl* t)
389370
{
390371
return run(t);
391372
}
@@ -395,9 +376,12 @@ struct test_runner
395376
std::cout << "** Runner terminated! **" << std::endl;
396377
std::cout << test_counter << " tests executed" << std::endl;
397378
std::cout << (failures_counter + success_counter) << " checks" << std::endl;
398-
std::cout << "-> " << success_counter << " failures" << std::endl;
379+
std::cout << "-> " << success_counter << " successes" << std::endl;
399380
std::cout << "-> " << failures_counter << " failures" << std::endl;
400-
std::cout << "Total time spent in tests: " << good_time_total << std::endl;
381+
std::cout << "Total run time: " << total_time << std::endl;
382+
std::cout << "Total time spent in tests: " << good_time_total << " ms" << std::endl;
383+
std::cout << "Average set up time: " << (total_set_up_time / test_counter) << " ms" << std::endl;
384+
std::cout << "Average tier down time: " << (total_tier_down_time / test_counter) << " ms" << std::endl;
401385
}
402386

403387
void add_failure()
@@ -421,6 +405,21 @@ struct test_runner
421405
good_time_total += t;
422406
}
423407

408+
void add_set_up_time(double t)
409+
{
410+
total_set_up_time += t;
411+
}
412+
413+
void add_tier_down_time(double t)
414+
{
415+
total_tier_down_time += t;
416+
}
417+
418+
void add_total_time(double t)
419+
{
420+
total_time += t;
421+
}
422+
424423
std::string last_checkpoint_file;
425424
int last_checkpoint_line;
426425

@@ -429,6 +428,104 @@ struct test_runner
429428
int success_counter;
430429
int failures_counter;
431430
double good_time_total;
431+
double total_set_up_time;
432+
double total_tier_down_time;
433+
double total_time;
434+
};
435+
436+
class test_base
437+
{
438+
public:
439+
const char* name;
440+
virtual bool run_test(test_runner* tr) { }
441+
virtual void operator()() { }
442+
};
443+
444+
test_runner auto_test_runner;
445+
std::vector<test_base*> auto_test_vector;
446+
447+
template <class test_impl>
448+
class test : public test_base
449+
{
450+
virtual bool run_test(test_runner* tr)
451+
{
452+
double set_up_duration = 0.0, tier_down_duration = 0.0, test_duration = 0.0;
453+
timeval before, after;
454+
try
455+
{
456+
gettimeofday(&before, NULL);
457+
static_cast<test_impl* >(this)->suite_set_up();
458+
gettimeofday(&after, NULL);
459+
set_up_duration = calculate_duration(&before, &after);
460+
tr->add_set_up_time(set_up_duration);
461+
}
462+
catch(std::exception& e)
463+
{
464+
std::cout << "Exception during " << static_cast<test_impl* >(this)->name << " set up" << std::endl;
465+
std::cout << e.what() << std::endl;
466+
}
467+
catch(...)
468+
{
469+
std::cout << "Exception during " << static_cast<test_impl* >(this)->name << " set up" << std::endl;
470+
}
471+
bool result = false;
472+
try
473+
{
474+
gettimeofday(&before, NULL);
475+
(*static_cast<test_impl*>(this))(tr);
476+
result = true;
477+
}
478+
catch(assert_unattended& au)
479+
{
480+
;
481+
}
482+
catch(std::exception& e)
483+
{
484+
std::cout << "Exception during " << static_cast<test_impl* >(this)->name << " run" << std::endl;
485+
std::cout << e.what() << std::endl;
486+
if(tr->last_checkpoint_line != -1)
487+
std::cout << "Last checkpoint in " << tr->last_checkpoint_file << ":" << tr->last_checkpoint_line << std::endl;
488+
}
489+
catch(...)
490+
{
491+
std::cout << "Exception during " << static_cast<test_impl* >(this)->name << " run" << std::endl;
492+
if(tr->last_checkpoint_line != -1)
493+
std::cout << "Last checkpoint in " << tr->last_checkpoint_file << ":" << tr->last_checkpoint_line << std::endl;
494+
}
495+
gettimeofday(&after, NULL);
496+
497+
test_duration = calculate_duration(&before, &after);
498+
499+
tr->add_good_time(test_duration);
500+
501+
std::cout << "- Time spent during \"" << static_cast<test_impl* >(this)->name << "\": " << test_duration << std::endl;
502+
503+
try
504+
{
505+
gettimeofday(&before, NULL);
506+
static_cast<test_impl* >(this)->suite_tier_down();
507+
gettimeofday(&after, NULL);
508+
tier_down_duration = calculate_duration(&before, &after);
509+
tr->add_tier_down_time(tier_down_duration);
510+
}
511+
catch(std::exception& e)
512+
{
513+
std::cout << "Exception during " << static_cast<test_impl* >(this)->name << " tier down" << std::endl;
514+
std::cout << e.what() << std::endl;
515+
}
516+
catch(...)
517+
{
518+
std::cout << "Exception during " << static_cast<test_impl* >(this)->name << " tier down" << std::endl;
519+
}
520+
double total = set_up_duration + test_duration + tier_down_duration;
521+
tr->add_total_time(total);
522+
return result;
523+
}
524+
protected:
525+
test() { }
526+
test(const test<test_impl>& t) { }
527+
528+
friend class test_runner;
432529
};
433530

434531
#endif //_LITTLETEST_HPP_

0 commit comments

Comments
 (0)