Skip to content

Commit 429fe9d

Browse files
authored
Merge pull request #96 from hlovdal/setup_and_teardown
Add support for unittest_setup and unittest_teardown functions
2 parents 90457fe + bc0e16d commit 429fe9d

File tree

3 files changed

+100
-0
lines changed

3 files changed

+100
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include <ArduinoUnitTests.h>
2+
#include <Arduino.h>
3+
4+
class LcdInterface {
5+
public:
6+
virtual void print(const char *) = 0;
7+
};
8+
9+
class MockLcd : public LcdInterface {
10+
public:
11+
void print(const char *) {}
12+
};
13+
14+
LcdInterface *Lcd_p;
15+
16+
class Calculator {
17+
public:
18+
int add(int a, int b) {
19+
int result = a + b;
20+
char buf[40];
21+
sprintf(buf, "%d + %d = %d", a, b, result);
22+
Lcd_p->print(buf);
23+
return result;
24+
}
25+
};
26+
27+
unittest_setup()
28+
{
29+
Lcd_p = new MockLcd();
30+
}
31+
32+
unittest_teardown()
33+
{
34+
delete Lcd_p;
35+
}
36+
37+
// This is a typical test where using setup (and teardown) would be useful
38+
// to set up the "external" lcd dependency that the calculator uses indirectly
39+
// but it is not something that is related to the functionality that is tested.
40+
41+
// When you want to test that the calculator actually prints the calculations,
42+
// then that should be done in the arrange part of the actual test (by setting
43+
// up an mock lcd class that keeps a list of all messages printed).
44+
45+
unittest(add)
46+
{
47+
// Arrange
48+
Calculator c;
49+
50+
// Act
51+
int result = c.add(11, 22);
52+
53+
// Assert
54+
assertEqual(33, result);
55+
}
56+
57+
unittest_main()

cpp/unittest/ArduinoUnitTests.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
#include "ArduinoUnitTests.h"
22

3+
TestSetup *TestSetup::sInstance;
4+
TestTeardown *TestTeardown::sInstance;
5+
36
Test* Test::sRoot = 0;

cpp/unittest/ArduinoUnitTests.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,26 @@ struct TestData {
1515
int result;
1616
};
1717

18+
class TestSetup
19+
{
20+
public:
21+
TestSetup() {
22+
sInstance = this;
23+
}
24+
virtual void run() {}
25+
static TestSetup *sInstance;
26+
};
27+
28+
class TestTeardown
29+
{
30+
public:
31+
TestTeardown() {
32+
sInstance = this;
33+
}
34+
virtual void run() {}
35+
static TestTeardown *sInstance;
36+
};
37+
1838
class Test
1939
{
2040
public:
@@ -152,7 +172,9 @@ class Test
152172
static int run_and_report(int argc, char *argv[]) {
153173
// TODO: pick a reporter based on args
154174
ReporterTAP rep;
175+
if (TestSetup::sInstance) TestSetup::sInstance->run();
155176
Results results = run(&rep);
177+
if (TestTeardown::sInstance) TestTeardown::sInstance->run();
156178
return results.failed + results.skipped;
157179
}
158180

@@ -217,6 +239,24 @@ class Test
217239
} test_##name##_instance; \
218240
void test_##name ::task()
219241

242+
/**
243+
* The unittest_setup and unittest_teardown functions are intended to be used
244+
* to set up "external" dependencies that needs to present but are not directly
245+
* related to the functionality that you are testing, for instance a LCD.
246+
*/
247+
#define unittest_setup() \
248+
class unittest_setup_class : public TestSetup { \
249+
public: \
250+
virtual void run() override; \
251+
} unittest_setup_instance; \
252+
void unittest_setup_class::run()
253+
254+
#define unittest_teardown() \
255+
class unittest_teardown_class : public TestTeardown { \
256+
public: \
257+
virtual void run() override; \
258+
} unittest_teardown_instance; \
259+
void unittest_teardown_class::run()
220260

221261
#define unittest_main() \
222262
int main(int argc, char *argv[]) { \

0 commit comments

Comments
 (0)