-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathTestRunner.h
More file actions
330 lines (281 loc) · 7.51 KB
/
TestRunner.h
File metadata and controls
330 lines (281 loc) · 7.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
#ifndef TEST_RUNNER_H
#define TEST_RUNNER_H
/*
* Simpatico - Simulation Package for Polymeric and Molecular Liquids
*
* Copyright 2010 - 2017, The Regents of the University of Minnesota
* Distributed under the terms of the GNU General Public License.
*/
#include <string>
#include <iostream>
#ifdef TEST_MPI
#include <mpi.h>
#endif
/**
* Abstract base class for classes that run tests.
*
* TestRunner is an abstract base class with two types of subclass:
* The UnitTestRunner class template defines a TestRunner that runs
* the tests for an associated UnitTest. A CompositeTestRunner runs
* the tests for a sequence of other TestRunner objects, each of
* which can be a UnitTestRunner or another CompositeTestRunner.
*
* An implementation of the pure virtual run() method of must run
* all of the associated test methods, and records the number
* nSuccess() of tests that succeed and the number nFailure() that
* fail. A test fails if it throws a TestException. Test methods
* use the TEST_ASSERT(expr) macro to assert the truth of a logical
* exprression expr, which throws a TestException if expr is false.
* The implementation of run() for a UnitTestRunner runs each unit
* test method of the associated UnitTest in a try-catch block and
* catches any thrown TestExceptions. The implementation of run
* for a TestComposite calls the run() method for each of its
* children.
*
* Each TestRunner may optionally have a parent TestRunner. The
* parent if any, is always a TestComposite. A TestComposite can
* have any number of children.
*
* The recordFailure() and recordSuccess() methods of a TestRunner,
* which can be called by the run method, increment the nSuccess or
* nFailure counters. If the TestRunner has a parent, each function
* also calls the corresponding function of the parent, thus
* incrementing the corresponding counter of the parent. The
* nSuccess and nFailure counters for a TestComposite thereby keep
* track of the total number of successful and failed unit test
* methods run by all descendants.
*
* Each TestRunner has a filePrefix string. The filePrefix is
* initialized to an empty string, and may be modified by the
* virtual addFilePrefix() function. The default implementation
* of this function prepends a string argument to the existing
* filePrefix.
*
* The UnitTestRunner class template supplies the filePrefix to
* instances of the associated UnitTest class when a UnitTest
* is created. (See the notes for UnitTestRunner for details of
* how). The filePrefix string of the UnitTest is then prepended
* to the names of any files opened by the functions openInputFile(),
* openOutputFile(), and openFile of the UnitTest subclass.
*
*
* The implementation of addFilePrefix() by the TestComposite
* subclass calls the addFilePrefix method of each of its
* children, and thus allows a common prefix to be added to the
* file paths used by all of its children.
*
* \ingroup Test_Module
*/
class TestRunner
{
public:
/**
* Constructor.
*/
TestRunner();
/**
* Destructor.
*/
virtual ~TestRunner();
/**
* Run all tests.
*
* \return number of failures.
*/
virtual int run() = 0;
/**
* Increment counter for failed tests, and that of parent (if any).
*/
void recordFailure();
/**
* Increment counter for successful tests, and that of parent (if any).
*/
void recordSuccess();
/**
* Set another TestRunner as the parent.
*
* \param parent parent CompositeTestRunner object
*/
void setParent(TestRunner& parent);
/**
* Return the parent object, if any.
*/
TestRunner& parent();
/**
* Does this object have a parent?
*/
bool hasParent() const;
/**
* Return number of successful tests run.
*/
int nSuccess() const;
/**
* Return number of failed tests run.
*/
int nFailure() const;
/**
* If this object has no parent, report success and failure counters.
*/
void report() const;
/**
* Is this the IO processor of an MPI communicator?
*/
bool isIoProcessor() const;
#ifdef TEST_MPI
/**
* Return the MPI rank in the communicator.
*/
int mpiRank() const;
/**
* Return the size (number of processors) of the communicator.
*/
int mpiSize() const;
#endif
/**
* Prepend argument prefix to existing filePrefix.
*/
virtual void addFilePrefix(const std::string& prefix);
/**
* Return file prefix by const reference.
*/
const std::string& filePrefix() const;
protected:
/// Prefix added to file names
std::string filePrefix_;
private:
/// Pointer to a parent TestRunner (if any).
TestRunner* parentPtr_;
/// Total number of successful tests run.
int nSuccess_;
/// Total number of failed tests run.
int nFailure_;
/// Can this processor input and output data?
/// This is always true when TEST_MPI is not defined.
bool isIoProcessor_;
#ifdef TEST_MPI
/// Rank of this processor within an MPI job.
int mpiRank_;
/// Size of associated MPI communicator.
int mpiSize_;
#endif
};
// Inline methods
/*
* Set another TestRunner as the parent.
*/
inline void TestRunner::setParent(TestRunner& parent)
{ parentPtr_ = &parent; }
/*
* Return the parent object, if any.
*/
inline TestRunner& TestRunner::parent()
{ return *parentPtr_; }
/*
* Does this object have a parent?
*/
inline bool TestRunner::hasParent() const
{ return (parentPtr_ != 0); }
/*
* Return number of successful tests run.
*/
inline int TestRunner::nSuccess() const
{ return nSuccess_; }
/*
* Return number of failed tests run.
*/
inline int TestRunner::nFailure() const
{ return nFailure_; }
/*
* Return file prefix by const reference.
*/
inline
const std::string& TestRunner::filePrefix() const
{ return filePrefix_; }
/*
* Is this an Io processor? (always true without MPI)
*/
inline bool TestRunner::isIoProcessor() const
{ return isIoProcessor_; }
#ifdef TEST_MPI
inline int TestRunner::mpiRank() const
{ return mpiRank_; }
inline int TestRunner::mpiSize() const
{ return mpiSize_; }
#endif
// Non-inline methods
/*
* Constructor.
*/
TestRunner::TestRunner()
: parentPtr_(0),
nSuccess_(0),
nFailure_(0),
isIoProcessor_(0)
#ifdef TEST_MPI
,mpiRank_(0),
mpiSize_(0)
#endif
{
#ifndef TEST_MPI
isIoProcessor_ = true;
#else
mpiRank_ = MPI::COMM_WORLD.Get_rank();
mpiSize_ = MPI::COMM_WORLD.Get_size();
if (mpiRank_ == 0) {
isIoProcessor_ = true;
} else {
isIoProcessor_ = false;
}
#endif
}
/*
* Destructor.
*/
TestRunner::~TestRunner()
{}
/*
* Increment counter for failed tests, and that of parent (if any).
*/
void TestRunner::recordFailure()
{
if (isIoProcessor()) {
++nFailure_;
if (hasParent()) {
parent().recordFailure();
}
}
}
/*
* Increment counter for successful tests, and that of parent (if any).
*/
void TestRunner::recordSuccess()
{
if (isIoProcessor()) {
++nSuccess_;
if (hasParent()) {
parent().recordSuccess();
}
}
}
/*
* If this object has no parent, report success and failure counters.
*/
void TestRunner::report() const
{
if (!hasParent() && isIoProcessor()) {
std::cout << std::endl;
std::cout << nSuccess_ << " successful tests " << std::endl;
std::cout << nFailure_ << " failed tests " << std::endl;
std::cout << std::endl;
}
}
/*
* Prepend argument prefix to existing filePrefix (virtual).
*/
void TestRunner::addFilePrefix(const std::string& prefix)
{
std::string newPrefix = prefix;
newPrefix += filePrefix_;
filePrefix_ = newPrefix;
}
#endif