CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

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