results_collector.ipp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. // (C) Copyright Gennadiy Rozental 2001.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // See http://www.boost.org/libs/test for the library home page.
  6. //
  7. /// @file
  8. /// Test results collecting facility.
  9. ///
  10. // ***************************************************************************
  11. #ifndef BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
  12. #define BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
  13. // Boost.Test
  14. #include <boost/test/unit_test_log.hpp>
  15. #include <boost/test/results_collector.hpp>
  16. #include <boost/test/framework.hpp>
  17. #include <boost/test/tree/test_unit.hpp>
  18. #include <boost/test/tree/visitor.hpp>
  19. #include <boost/test/tree/test_case_counter.hpp>
  20. #include <boost/test/tree/traverse.hpp>
  21. // Boost
  22. #include <boost/cstdlib.hpp>
  23. // STL
  24. #include <map>
  25. #include <boost/test/detail/suppress_warnings.hpp>
  26. //____________________________________________________________________________//
  27. namespace boost {
  28. namespace unit_test {
  29. // ************************************************************************** //
  30. // ************** test_results ************** //
  31. // ************************************************************************** //
  32. test_results::test_results()
  33. {
  34. clear();
  35. }
  36. //____________________________________________________________________________//
  37. bool
  38. test_results::passed() const
  39. {
  40. // if it is skipped, it is not passed. However, if any children is not failed/aborted
  41. // then their skipped status is not taken into account.
  42. return !p_skipped &&
  43. p_test_cases_failed == 0 &&
  44. p_assertions_failed <= p_expected_failures &&
  45. // p_test_cases_skipped == 0 &&
  46. !p_aborted;
  47. }
  48. //____________________________________________________________________________//
  49. bool
  50. test_results::aborted() const
  51. {
  52. return p_aborted;
  53. }
  54. //____________________________________________________________________________//
  55. bool
  56. test_results::skipped() const
  57. {
  58. return p_skipped;
  59. }
  60. //____________________________________________________________________________//
  61. int
  62. test_results::result_code() const
  63. {
  64. return passed() ? exit_success
  65. : ( (p_assertions_failed > p_expected_failures || p_skipped )
  66. ? exit_test_failure
  67. : exit_exception_failure );
  68. }
  69. //____________________________________________________________________________//
  70. void
  71. test_results::operator+=( test_results const& tr )
  72. {
  73. p_assertions_passed.value += tr.p_assertions_passed;
  74. p_assertions_failed.value += tr.p_assertions_failed;
  75. p_warnings_failed.value += tr.p_warnings_failed;
  76. p_test_cases_passed.value += tr.p_test_cases_passed;
  77. p_test_cases_warned.value += tr.p_test_cases_warned;
  78. p_test_cases_failed.value += tr.p_test_cases_failed;
  79. p_test_cases_skipped.value += tr.p_test_cases_skipped;
  80. p_test_cases_aborted.value += tr.p_test_cases_aborted;
  81. p_duration_microseconds.value += tr.p_duration_microseconds;
  82. }
  83. //____________________________________________________________________________//
  84. void
  85. test_results::clear()
  86. {
  87. p_assertions_passed.value = 0;
  88. p_assertions_failed.value = 0;
  89. p_warnings_failed.value = 0;
  90. p_expected_failures.value = 0;
  91. p_test_cases_passed.value = 0;
  92. p_test_cases_warned.value = 0;
  93. p_test_cases_failed.value = 0;
  94. p_test_cases_skipped.value = 0;
  95. p_test_cases_aborted.value = 0;
  96. p_duration_microseconds.value= 0;
  97. p_aborted.value = false;
  98. p_skipped.value = false;
  99. }
  100. //____________________________________________________________________________//
  101. // ************************************************************************** //
  102. // ************** results_collector ************** //
  103. // ************************************************************************** //
  104. namespace {
  105. struct results_collector_impl {
  106. std::map<test_unit_id,test_results> m_results_store;
  107. };
  108. results_collector_impl& s_rc_impl() { static results_collector_impl the_inst; return the_inst; }
  109. } // local namespace
  110. //____________________________________________________________________________//
  111. void
  112. results_collector_t::test_start( counter_t )
  113. {
  114. s_rc_impl().m_results_store.clear();
  115. }
  116. //____________________________________________________________________________//
  117. void
  118. results_collector_t::test_unit_start( test_unit const& tu )
  119. {
  120. // init test_results entry
  121. test_results& tr = s_rc_impl().m_results_store[tu.p_id];
  122. tr.clear();
  123. tr.p_expected_failures.value = tu.p_expected_failures;
  124. }
  125. //____________________________________________________________________________//
  126. class results_collect_helper : public test_tree_visitor {
  127. public:
  128. explicit results_collect_helper( test_results& tr, test_unit const& ts ) : m_tr( tr ), m_ts( ts ) {}
  129. void visit( test_case const& tc )
  130. {
  131. test_results const& tr = results_collector.results( tc.p_id );
  132. m_tr += tr;
  133. if( tr.passed() ) {
  134. if( tr.p_warnings_failed )
  135. m_tr.p_test_cases_warned.value++;
  136. else
  137. m_tr.p_test_cases_passed.value++;
  138. }
  139. else if( tr.p_skipped )
  140. m_tr.p_test_cases_skipped.value++;
  141. else {
  142. if( tr.p_aborted )
  143. m_tr.p_test_cases_aborted.value++;
  144. m_tr.p_test_cases_failed.value++;
  145. }
  146. }
  147. bool test_suite_start( test_suite const& ts )
  148. {
  149. if( m_ts.p_id == ts.p_id )
  150. return true;
  151. m_tr += results_collector.results( ts.p_id );
  152. return false;
  153. }
  154. private:
  155. // Data members
  156. test_results& m_tr;
  157. test_unit const& m_ts;
  158. };
  159. //____________________________________________________________________________//
  160. void
  161. results_collector_t::test_unit_finish( test_unit const& tu, unsigned long elapsed_in_microseconds )
  162. {
  163. if( tu.p_type == TUT_SUITE ) {
  164. results_collect_helper ch( s_rc_impl().m_results_store[tu.p_id], tu );
  165. traverse_test_tree( tu, ch );
  166. }
  167. else {
  168. test_results & tr = s_rc_impl().m_results_store[tu.p_id];
  169. tr.p_duration_microseconds.value = elapsed_in_microseconds;
  170. bool num_failures_match = tr.p_aborted || tr.p_assertions_failed >= tr.p_expected_failures;
  171. if( !num_failures_match )
  172. BOOST_TEST_FRAMEWORK_MESSAGE( "Test case " << tu.full_name() << " has fewer failures than expected" );
  173. bool check_any_assertions = tr.p_aborted || (tr.p_assertions_failed != 0) || (tr.p_assertions_passed != 0);
  174. if( !check_any_assertions )
  175. BOOST_TEST_FRAMEWORK_MESSAGE( "Test case " << tu.full_name() << " did not check any assertions" );
  176. }
  177. }
  178. //____________________________________________________________________________//
  179. void
  180. results_collector_t::test_unit_skipped( test_unit const& tu, const_string /*reason*/ )
  181. {
  182. test_results& tr = s_rc_impl().m_results_store[tu.p_id];
  183. tr.clear();
  184. tr.p_skipped.value = true;
  185. if( tu.p_type == TUT_SUITE ) {
  186. test_case_counter tcc;
  187. traverse_test_tree( tu, tcc );
  188. tr.p_test_cases_skipped.value = tcc.p_count;
  189. }
  190. }
  191. //____________________________________________________________________________//
  192. void
  193. results_collector_t::assertion_result( unit_test::assertion_result ar )
  194. {
  195. test_results& tr = s_rc_impl().m_results_store[framework::current_test_case_id()];
  196. switch( ar ) {
  197. case AR_PASSED: tr.p_assertions_passed.value++; break;
  198. case AR_FAILED: tr.p_assertions_failed.value++; break;
  199. case AR_TRIGGERED: tr.p_warnings_failed.value++; break;
  200. }
  201. if( tr.p_assertions_failed == 1 )
  202. first_failed_assertion();
  203. }
  204. //____________________________________________________________________________//
  205. void
  206. results_collector_t::exception_caught( execution_exception const& )
  207. {
  208. test_results& tr = s_rc_impl().m_results_store[framework::current_test_case_id()];
  209. tr.p_assertions_failed.value++;
  210. }
  211. //____________________________________________________________________________//
  212. void
  213. results_collector_t::test_unit_aborted( test_unit const& tu )
  214. {
  215. s_rc_impl().m_results_store[tu.p_id].p_aborted.value = true;
  216. }
  217. //____________________________________________________________________________//
  218. test_results const&
  219. results_collector_t::results( test_unit_id id ) const
  220. {
  221. return s_rc_impl().m_results_store[id];
  222. }
  223. //____________________________________________________________________________//
  224. } // namespace unit_test
  225. } // namespace boost
  226. #include <boost/test/detail/enable_warnings.hpp>
  227. #endif // BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER