AP_Test.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. */
  13. //
  14. /// @file AP_Test.h
  15. /// @brief A simple unit test framework.
  16. ///
  17. /// AP_Test provides the usual test start, condition validation and reporting
  18. /// functions in a compact form.
  19. ///
  20. /// Each test must be contained within a block; either a standalone function or
  21. /// a block within a function. The TEST macro is used to start a test; it creates
  22. /// the local object which will track the results of the test and saves the name
  23. /// for later reporting. Only one test may be performed within each block.
  24. ///
  25. /// Within the test, use the REQUIRE macro to describe a condition that must be
  26. /// met for the test to pass. If the condition within the macro is not met,
  27. /// the condition will be output as a diagnostic and the test will be considered
  28. /// to have failed.
  29. ///
  30. /// The test ends at the end of the block, and the result of the test will be
  31. /// output as a diagnostic.
  32. ///
  33. /// Optionally at the end of the test suite, the Test::report method may be used
  34. /// to summarize the results of all of the tests that were performed.
  35. ///
  36. /// Unit test state and methods.
  37. ///
  38. class Test
  39. {
  40. public:
  41. /// Constructor - creates a new test.
  42. ///
  43. /// Normally called by the TEST macro.
  44. ///
  45. /// @param name The name of the test being started.
  46. ///
  47. Test(const char *name);
  48. /// Destructor - ends the test.
  49. ///
  50. ~Test();
  51. /// Perform a success check.
  52. ///
  53. /// @param expr If false, the test has failed.
  54. /// @param source The expression source; emitted in the diagnostic
  55. /// indicating test failure.
  56. ///
  57. void require(bool expr, const char *source);
  58. /// Report the overall number of tests/pass/fails.
  59. ///
  60. static void report();
  61. private:
  62. const char *_name; ///< name of the current test
  63. bool _fail; ///< set if any ::require calls indicate the test failed
  64. static int16_t _passed; ///< global pass count
  65. static int16_t _failed; ///< global fail count
  66. };
  67. /// Constructor
  68. ///
  69. Test::Test(const char *name) :
  70. _name(name),
  71. _fail(false)
  72. {
  73. }
  74. /// Destructor
  75. ///
  76. Test::~Test()
  77. {
  78. Serial.printf("%s: %s\n", _fail ? "FAILED" : "passed", _name);
  79. if (_fail) {
  80. _failed++;
  81. } else {
  82. _passed++;
  83. }
  84. }
  85. /// Success check
  86. ///
  87. void
  88. Test::require(bool expr, const char *source)
  89. {
  90. if (!expr) {
  91. _fail = true;
  92. Serial.printf("%s: fail: %s\n", _name, source);
  93. }
  94. }
  95. /// Summary report
  96. ///
  97. void
  98. Test::report()
  99. {
  100. Serial.printf("\n%d passed %d failed\n", _passed, _failed);
  101. }
  102. int16_t Test::_passed = 0;
  103. int16_t Test::_failed = 0;
  104. /// Start a new test.
  105. ///
  106. /// This should be invoked at the beginning of a block, before any REQUIRE
  107. /// statements. A new test called name is started, and subsequent REQUIRE
  108. /// statements will be applied to the test. The test will continue until
  109. /// the end of the block (or until the _test object that is created otherwise
  110. /// goes out of scope).
  111. ///
  112. #define TEST(name) Test _test(# name)
  113. /// Attach an expression to the test's success criteria.
  114. ///
  115. /// The expression expr must evaluate true for the test to pass. If
  116. /// it does not, the text of the expression is output as a diagnostic
  117. /// and the test is marked as a failure.
  118. ///
  119. #define REQUIRE(expr) _test.require(expr, # expr)