1 | // |
2 | // TestCase.h |
3 | // |
4 | |
5 | |
6 | #ifndef Poco_CppUnit_TestCase_INCLUDED |
7 | #define Poco_CppUnit_TestCase_INCLUDED |
8 | |
9 | |
10 | #include "Poco/CppUnit/CppUnit.h" |
11 | #include "Poco/CppUnit/Guards.h" |
12 | #include "Poco/CppUnit/Test.h" |
13 | #include "Poco/CppUnit/CppUnitException.h" |
14 | #include <string> |
15 | #include <typeinfo> |
16 | |
17 | |
18 | namespace CppUnit { |
19 | |
20 | |
21 | class TestResult; |
22 | |
23 | |
24 | /* |
25 | * A test case defines the fixture to run multiple tests. To define a test case |
26 | * 1) implement a subclass of TestCase |
27 | * 2) define instance variables that store the state of the fixture |
28 | * 3) initialize the fixture state by overriding setUp |
29 | * 4) clean-up after a test by overriding tearDown. |
30 | * |
31 | * Each test runs in its own fixture so there |
32 | * can be no side effects among test runs. |
33 | * Here is an example: |
34 | * |
35 | * class MathTest : public TestCase { |
36 | * protected: int m_value1; |
37 | * protected: int m_value2; |
38 | * |
39 | * public: MathTest (std::string name) |
40 | * : TestCase (name) { |
41 | * } |
42 | * |
43 | * protected: void setUp () { |
44 | * m_value1 = 2; |
45 | * m_value2 = 3; |
46 | * } |
47 | * } |
48 | * |
49 | * |
50 | * For each test implement a method which interacts |
51 | * with the fixture. Verify the expected results with assertions specified |
52 | * by calling assert on the expression you want to test: |
53 | * |
54 | * protected: void testAdd () { |
55 | * int result = value1 + value2; |
56 | * assert (result == 5); |
57 | * } |
58 | * |
59 | * Once the methods are defined you can run them. To do this, use |
60 | * a TestCaller. |
61 | * |
62 | * Test *test = new TestCaller<MathTest>("testAdd", MathTest::testAdd); |
63 | * test->run (); |
64 | * |
65 | * |
66 | * The tests to be run can be collected into a TestSuite. CppUnit provides |
67 | * different test runners which can run a test suite and collect the results. |
68 | * The test runners expect a static method suite as the entry |
69 | * point to get a test to run. |
70 | * |
71 | * public: static MathTest::suite () { |
72 | * TestSuite *suiteOfTests = new TestSuite; |
73 | * suiteOfTests->addTest(new TestCaller<MathTest>("testAdd", testAdd)); |
74 | * suiteOfTests->addTest(new TestCaller<MathTest>("testDivideByZero", testDivideByZero)); |
75 | * return suiteOfTests; |
76 | * } |
77 | * |
78 | * Note that the caller of suite assumes lifetime control |
79 | * for the returned suite. |
80 | * |
81 | * see TestResult, TestSuite and TestCaller |
82 | * |
83 | */ |
84 | class CppUnit_API TestCase: public Test |
85 | { |
86 | REFERENCEOBJECT (TestCase) |
87 | |
88 | public: |
89 | TestCase(const std::string& Name); |
90 | ~TestCase(); |
91 | |
92 | virtual void run(TestResult* result); |
93 | virtual TestResult* run(); |
94 | virtual int countTestCases(); |
95 | const std::string& name() const; |
96 | virtual std::string toString(); |
97 | |
98 | virtual void setUp(); |
99 | virtual void tearDown(); |
100 | |
101 | protected: |
102 | virtual void runTest(); |
103 | TestResult* defaultResult(); |
104 | |
105 | void assertImplementation(bool condition, |
106 | const std::string& conditionExpression = "" , |
107 | long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER, |
108 | const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME); |
109 | |
110 | void loop1assertImplementation(bool condition, |
111 | const std::string& conditionExpression = "" , |
112 | long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER, |
113 | long dataLineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER, |
114 | const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME); |
115 | |
116 | void loop2assertImplementation(bool condition, |
117 | const std::string& conditionExpression = "" , |
118 | long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER, |
119 | long data1LineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER, |
120 | long data2LineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER, |
121 | const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME); |
122 | |
123 | void assertEquals(long expected, |
124 | long actual, |
125 | long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER, |
126 | const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME); |
127 | |
128 | void assertEquals(double expected, |
129 | double actual, |
130 | double delta, |
131 | long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER, |
132 | const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME); |
133 | |
134 | void assertEquals(const std::string& expected, |
135 | const std::string& actual, |
136 | long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER, |
137 | const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME); |
138 | |
139 | void assertEquals(const void* expected, |
140 | const void* actual, |
141 | long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER, |
142 | const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME); |
143 | |
144 | std::string notEqualsMessage(long expected, long actual); |
145 | std::string notEqualsMessage(double expected, double actual); |
146 | std::string notEqualsMessage(const void* expected, const void* actual); |
147 | std::string notEqualsMessage(const std::string& expected, const std::string& actual); |
148 | |
149 | void assertNotNull(const void* pointer, |
150 | const std::string& pointerExpression = "" , |
151 | long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER, |
152 | const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME); |
153 | |
154 | void assertNull(const void* pointer, |
155 | const std::string& pointerExpression = "" , |
156 | long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER, |
157 | const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME); |
158 | |
159 | void fail(const std::string& message = "" , |
160 | long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER, |
161 | const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME); |
162 | |
163 | void warn(const std::string& message = "" , |
164 | long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER, |
165 | const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME); |
166 | |
167 | |
168 | protected: |
169 | const std::string _name; |
170 | }; |
171 | |
172 | |
173 | // Constructs a test case |
174 | inline TestCase::TestCase(const std::string& name): _name (name) |
175 | { |
176 | } |
177 | |
178 | |
179 | // Destructs a test case |
180 | inline TestCase::~TestCase() |
181 | { |
182 | } |
183 | |
184 | |
185 | // Returns a count of all the tests executed |
186 | inline int TestCase::countTestCases() |
187 | { |
188 | return 1; |
189 | } |
190 | |
191 | |
192 | // Returns the name of the test case |
193 | inline const std::string& TestCase::name() const |
194 | { |
195 | return _name; |
196 | } |
197 | |
198 | |
199 | // A hook for fixture set up |
200 | inline void TestCase::setUp() |
201 | { |
202 | } |
203 | |
204 | |
205 | |
206 | // A hook for fixture tear down |
207 | inline void TestCase::tearDown() |
208 | { |
209 | } |
210 | |
211 | |
212 | // Returns the name of the test case instance |
213 | inline std::string TestCase::toString() |
214 | { |
215 | const std::type_info& thisClass = typeid(*this); |
216 | return std::string(thisClass.name()) + "." + name(); |
217 | } |
218 | |
219 | |
220 | // A set of macros which allow us to get the line number |
221 | // and file name at the point of an error. |
222 | // Just goes to show that preprocessors do have some |
223 | // redeeming qualities. |
224 | |
225 | // for backward compatibility only |
226 | // (may conflict with C assert, use at your own risk) |
227 | #undef assert |
228 | #define assert(condition) \ |
229 | (this->assertImplementation((condition), (#condition), __LINE__, __FILE__)) |
230 | |
231 | #define assertTrue(condition) \ |
232 | (this->assertImplementation((condition), (#condition), __LINE__, __FILE__)) |
233 | |
234 | #define assertFalse(condition) \ |
235 | (this->assertImplementation((!(condition)), (#condition), __LINE__, __FILE__)) |
236 | |
237 | #define loop_1_assert(data1line, condition) \ |
238 | (this->loop1assertImplementation((condition), (#condition), __LINE__, data1line, __FILE__)) |
239 | |
240 | #define loop_2_assert(data1line, data2line, condition) \ |
241 | (this->loop2assertImplementation((condition), (#condition), __LINE__, data1line, data2line, __FILE__)) |
242 | |
243 | #define assertEqualDelta(expected, actual, delta) \ |
244 | (this->assertEquals((expected), (actual), (delta), __LINE__, __FILE__)) |
245 | |
246 | #define assertEqual(expected, actual) \ |
247 | (this->assertEquals((expected), (actual), __LINE__, __FILE__)) |
248 | |
249 | #define assertNullPtr(ptr) \ |
250 | (this->assertNull((ptr), #ptr, __LINE__, __FILE__)) |
251 | |
252 | #define assertNotNullPtr(ptr) \ |
253 | (this->assertNotNull((ptr), #ptr, __LINE__, __FILE__)) |
254 | |
255 | #define failmsg(msg) \ |
256 | (this->fail(msg, __LINE__, __FILE__)) |
257 | |
258 | #define warnmsg(msg) \ |
259 | (this->fail(msg, __LINE__, __FILE__)) |
260 | |
261 | |
262 | } // namespace CppUnit |
263 | |
264 | |
265 | #endif // Poco_CppUnit_TestCase_INCLUDED |
266 | |