“Serious” developers of embedded systems (read: stmshchiki) from time to time like to spike naked “arduinschikov” whose development environment, among other things, does not even support hardware debuggers with breakpoints and viewing the values of variables under the mouse cursor or on a special table in real time . Well, the accusation is quite true, the window of the serial port monitor (Serial Monitor) plus Serial.println is not the best debugging tool. However, a competent Arduinschik will be able to easily parry the attack and put the overblown stunt in place if he (the arduinschik) uses unit tests.
So, unit tests (unit tests) make life easier when searching for problem areas in an application, prevent the repetition of problems already found (regressions), give a measurable confidence in the reliability of the written code. This is all the more important when developing embedded applications and all kinds of mobile robots, for which the process of debugging, catching and reproducing (especially, reproducing) errors is especially difficult compared to classic desktop, server or mobile applications.
However, the transition to the use of automatic tests in the project requires a special internal discipline, a special approach to writing code and organizing the project workspace.
In preparation for the introduction of modular tests in the project should be borne in mind:
I will no longer talk about the philosophy of unit testing, but just show you how to technically implement simple unit tests in your Arduino project.
Next, consider:
We need a unit testing framework:
For programming, Arduino uses the C ++ language mixed with C, therefore, theoretically, any unit testing framework for C ++ will go, but we want to run tests on the desktop and on the device. The fact is that for Arduino some calls to the standard libc library are implemented, but not all, so not every framework working with libc is compiled for Arduino. The reverse is also true: if the framework is made specifically for Arduino, then it may not work on the desktop system with libc.
I looked through several frameworks and stopped at 2x:
Still, my sympathies were outweighed in favor of sput, and the problem with std :: out was resolved with several fixes (replacing printf with sprintf + Serial.print).
The result was the project sput-ino - the port of the sput library to the Arduino platform while maintaining compatibility with desktop systems with libc
- an example of a single-file sketch with tests
/ sput-ino / examples / sput-ino-monolith /
- an example with separation of the main code and tests for modules
sput-ino / examples / sput-ino-modules /
- run tests on the desktop system
sput-ino / example-desktop /
- an example with the separation of the main code and tests for different projects - in a separate repository
https://github.com/sadr0b0t/sput-ino-demo
Just clone the git repository https://github.com/sadr0b0t/sput-ino.git into the $ HOME / Arduino / libraries directory:
cd $HOME/Arduino/libraries/
git clone https://github.com/sadr0b0t/sput-ino.git
IDE.
github https://github.com/sadr0b0t/sput-ino/ > ZIP (Clone or download > Download ZIP), sput-ino-master.zip : > > .ZIP ....
> > sput-ino (File > Examples > sput-ino)
. () «.ino». «.ino» «.cpp» ( Arduino.h - ), .
sput-ino/examples/sput-ino-monolith/sput-ino-monolith.ino
- :
/**
* @return a b
*/
int a_plus_b(int a, int b) {
return a + b;
}
/**
* @return a b
*/
int a_minus_b(int a, int b) {
return a - b;
}
/**
* ,
* @param pin
* @param num
* @return true, num
*/
bool led_on_even(int pin, int num) {
if(num % 2 == 0) {
digitalWrite(pin, HIGH);
} else {
digitalWrite(pin, LOW);
}
return num % 2 == 0;
}
sput ( : http://www.use-strict.de/sput-unit-testing/tutorial.html):
#include "sput.h"
/** Test a_plus_b call */
void test_a_plus_b() {
sput_fail_unless(a_plus_b(2, 2) == 4, "2 + 2 == 4");
sput_fail_unless(a_plus_b(-2, 2) == 0, "-2 + 2 == 0");
// this one would pass on 32-bit controllers and would fail on AVR with 16-bit int
sput_fail_unless(a_plus_b(34000, 34000) == 68000, "34000 + 34000 == 68000");
}
/** Test a_minus_b call */
void test_a_minus_b() {
sput_fail_unless(a_minus_b(115, 6) == 109, "115 - 6 == 109");
sput_fail_unless(a_minus_b(13, 17) == -4, "13 - 17 == -4");
}
/** Test test_led_on_even call */
bool test_led_on_even() {
pinMode(13, OUTPUT);
sput_fail_unless(led_on_even(13, 2), "num=2 => led#13 on");
// would pass on desktop, might fail or pass on difference devices
// (e.g.: Arduino Due - fail, ChipKIT Uno32 - pass)
sput_fail_unless(digitalRead(13) == HIGH, "num=2 => led#13 on");
sput_fail_unless(!led_on_even(13, 5), "num=5 => led#13 off");
sput_fail_unless(digitalRead(13) == LOW, "num=5 => led#13 off");
sput_fail_unless(led_on_even(13, 18), "num=18 => led#13 on");
sput_fail_unless(digitalRead(13) == HIGH, "num=18 => led#13 on");
}
(-).
:
/** All tests in one bundle */
int mylib_test_suite() {
sput_start_testing();
sput_enter_suite("a plus b");
sput_run_test(test_a_plus_b);
sput_enter_suite("a minus b");
sput_run_test(test_a_minus_b);
sput_enter_suite("led on even");
sput_run_test(test_led_on_even);
sput_finish_testing();
return sput_get_return_value();
}
:
/** Test suite for a_plus_b call */
int mylib_test_suite_a_plus_b() {
sput_start_testing();
sput_enter_suite("a plus b");
sput_run_test(test_a_plus_b);
sput_finish_testing();
return sput_get_return_value();
}
/** Test suite for a_minus_b call */
int mylib_test_suite_a_minus_b() {
sput_start_testing();
sput_enter_suite("a minus b");
sput_run_test(test_a_minus_b);
sput_finish_testing();
return sput_get_return_value();
}
/** Test suite for led_on_even call */
int mylib_test_suite_led_on_even() {
sput_start_testing();
sput_enter_suite("led on even");
sput_run_test(test_led_on_even);
sput_finish_testing();
return sput_get_return_value();
}
. -, , /, . (, , - ).
:
void run_tests() {
Serial.println("#################### Start testing...");
// comment out specific test suites if firmware does not
// fit to device memory
// Test suite for a_plus_b call
mylib_test_suite_a_plus_b();
// Test suite for a_minus_b call
mylib_test_suite_a_minus_b();
// Test suite for led_on_even call
mylib_test_suite_led_on_even();
// All tests in one bundle
//mylib_test_suite();
Serial.println("#################### Finished testing");
}
setup/loop, run_tests setup , Serial.begin, :
void setup() {
Serial.begin(9600);
while (!Serial);
// run tests
run_tests();
// other code - kinda application business logic
Serial.println("Just show that we call functions from tested lib, nothing useful here");
pinMode(13, OUTPUT);
Serial.print("14+23=");
Serial.println(a_plus_b(14, 23));
Serial.print("14-23=");
Serial.println(a_minus_b(14, 23));
Serial.print("34000+34000=");
Serial.println(a_plus_b(34000, 34000));
}
void loop() {
static int i = 0;
led_on_even(13, i++);
delay(2000);
}
. , run_tests, .
, , ( > / Tools > Serial monitor)
ChipKIT Uno32 ( 32- PIC32):
#################### Start testing...
== Entering suite #1, "a plus b" ==
[1:1] test_a_plus_b:#1 "2 + 2 == 4" pass
[1:2] test_a_plus_b:#2 "-2 + 2 == 0" pass
[1:3] test_a_plus_b:#3 "34000 + 34000 == 68000" pass
--> 3 check(s), 3 ok, 0 failed (0.00%)
==> 3 check(s) in 1 suite(s) finished after 0.00 second(s),
3 succeeded, 0 failed (0.00%)
[SUCCESS]
== Entering suite #1, "a minus b" ==
[1:1] test_a_minus_b:#1 "115 - 6 == 109" pass
[1:2] test_a_minus_b:#2 "13 - 17 == -4" pass
--> 2 check(s), 2 ok, 0 failed (0.00%)
==> 2 check(s) in 1 suite(s) finished after 0.00 second(s),
2 succeeded, 0 failed (0.00%)
[SUCCESS]
== Entering suite #1, "led on even" ==
[1:1] test_led_on_even:#1 "num=2 => led#13 on" pass
[1:2] test_led_on_even:#2 "num=2 => led#13 on" pass
[1:3] test_led_on_even:#3 "num=5 => led#13 off" pass
[1:4] test_led_on_even:#4 "num=5 => led#13 off" pass
[1:5] test_led_on_even:#5 "num=18 => led#13 on" pass
[1:6] test_led_on_even:#6 "num=18 => led#13 on" pass
--> 6 check(s), 6 ok, 0 failed (0.00%)
==> 6 check(s) in 1 suite(s) finished after 0.00 second(s),
6 succeeded, 0 failed (0.00%)
[SUCCESS]
#################### Finished testing
Just show that we call functions from tested lib, nothing useful here
14+23=37
14-23=-9
34000+34000=68000
Arduino Uno ( AVR 16 ):
#################### Start testing...
== Entering suite #1, "a#################### Start testing...
== Entering suite #1, "a plus b" ==
[1:1] test_a_plus_b:#1 "2 + 2 == 4" pass
[1:2] test_a_plus_b:#2 "-2 + 2 == 0" pass
[1:3] test_a_plus_b:#3 "34000 + 34000 == 68000" FAIL
! Type: fail-unless
! Condition: a_plus_b(34000, 34000) == 68000
! Line: 14
--> 3 check(s), 2 ok, 1 failed (?%)
==> 3 check(s) in 1 suite(s) finished after ? second(s),
2 succeeded, 1 failed (?%)
[FAILURE]
== Entering suite #1, "a minus b" ==
[1:1] test_a_minus_b:#1 "115 - 6 == 109" pass
[1:2] test_a_minus_b:#2 "13 - 17 == -4" pass
--> 2 check(s), 2 ok, 0 failed (?%)
==> 2 check(s) in 1 suite(s) finished after ? second(s),
2 succeeded, 0 failed (?%)
[SUCCESS]
== Entering suite #1, "led on even" ==
[1:1] test_led_on_even:#1 "num=2 => led#13 on" pass
[1:2] test_led_on_even:#2 "num=2 => led#13 on" pass
[1:3] test_led_on_even:#3 "num=5 => led#13 off" pass
[1:4] test_led_on_even:#4 "num=5 => led#13 off" pass
[1:5] test_led_on_even:#5 "num=18 => led#13 on" pass
[1:6] test_led_on_even:#6 "num=18 => led#13 on" pass
--> 6 check(s), 6 ok, 0 failed (?%)
==> 6 check(s) in 1 suite(s) finished after ? second(s),
6 succeeded, 0 failed (?%)
[SUCCESS]
#################### Finished testing
Just show that we call functions from tested lib, nothing useful here
14+23=37
14-23=-9
34000+34000=2464
:
— PIC32 , AVR . 34000 + 34000 == 68000 32- PIC32, AVR int = 2 (16 ), , = 2^16-1=65536-1=65535 ( unsigned). AVR 16- int , 32- PIC32 ( 64- x86_64) . , , .
— test_led_on_even ( , ) , , , digitalRead digitalWrite — .
-, digitalRead ( GPIO pinMode INPUT) , GPIO digitalWrite pinMode OUTPUT: digitalRead , .
-, , digitalRead digitalWrite, , . , , digitalWrite/digitalRead (, Arduino UNO AVR , pinMode(13, OUTPUT), ChipKIT Uno32 PIC32 ).
, digitalWrite GPIO , digitalRead . , digitalWriite . - , ( ).
— , .
. , , . , - .
: (.ino) (*.h), (.c) C++ (.cpp). #include, C/C++ . Arduino IDE .
:
sput-ino/examples/sput-ino-modules/
— :
sput-ino/examples/sput-ino-modules/mylib.h
#ifndef MYLIB_H
#define MYLIB_H
/**
* @return a b
*/
int a_plus_b(int a, int b);
/**
* @return a b
*/
int a_minus_b(int a, int b);
/**
* ,
* @param pin
* @param num
* @return true, num
*/
bool led_on_even(int pin, int num);
#endif // MYLIB_TEST_H
. API Arduino, Arduino.h.
sput-ino/examples/sput-ino-modules/mylib.cpp
#include "Arduino.h"
/**
* @return a b
*/
int a_plus_b(int a, int b) {
return a + b;
}
/**
* @return a b
*/
int a_minus_b(int a, int b) {
return a - b;
}
/**
* ,
* @param pin
* @param num
* @return true, num
*/
bool led_on_even(int pin, int num) {
if(num % 2 == 0) {
digitalWrite(pin, HIGH);
} else {
digitalWrite(pin, LOW);
}
return num % 2 == 0;
}
— (-), :
sput-ino/examples/sput-ino-modules/mylib-test.h
#ifndef MYLIB_TEST_H
#define MYLIB_TEST_H
/** Test suite for a_plus_b call */
int mylib_test_suite_a_plus_b();
/** Test suite for a_minus_b call */
int mylib_test_suite_a_minus_b();
/** Test suite for led_on_even call */
int mylib_test_suite_led_on_even();
/** All tests in one bundle */
int mylib_test_suite();
#endif // MYLIB_TEST_H
: , mylib.h Arduino.h .
sput-ino/examples/sput-ino-modules/mylib-test.cpp
// http://www.use-strict.de/sput-unit-testing/tutorial.html
#include "sput.h"
#include "Arduino.h"
#include "mylib.h"
/** Test a_plus_b call */
void test_a_plus_b() {
sput_fail_unless(a_plus_b(2, 2) == 4, "2 + 2 == 4");
sput_fail_unless(a_plus_b(-2, 2) == 0, "-2 + 2 == 0");
// this one would pass on 32-bit controllers and desktop (libc) and would fail on AVR with 16-bit int
sput_fail_unless(a_plus_b(34000, 34000) == 68000, "34000 + 34000 == 68000");
}
/** Test a_minus_b call */
void test_a_minus_b() {
sput_fail_unless(a_minus_b(115, 6) == 109, "115 - 6 == 109");
sput_fail_unless(a_minus_b(13, 17) == -4, "13 - 17 == -4");
}
/** Test test_led_on_even call */
bool test_led_on_even() {
pinMode(13, OUTPUT);
sput_fail_unless(led_on_even(13, 2), "num=2 => led#13 on");
// would pass on desktop, might fail or pass on difference devices
// (e.g.: Arduino Due - fail, ChipKIT Uno32 - pass)
sput_fail_unless(digitalRead(13) == HIGH, "num=2 => led#13 on");
sput_fail_unless(!led_on_even(13, 5), "num=5 => led#13 off");
sput_fail_unless(digitalRead(13) == LOW, "num=5 => led#13 off");
sput_fail_unless(led_on_even(13, 18), "num=18 => led#13 on");
sput_fail_unless(digitalRead(13) == HIGH, "num=18 => led#13 on");
}
/*******************************************/
// test suites
/** Test suite for a_plus_b call */
int mylib_test_suite_a_plus_b() {
sput_start_testing();
sput_enter_suite("a plus b");
sput_run_test(test_a_plus_b);
sput_finish_testing();
return sput_get_return_value();
}
/** Test suite for a_minus_b call */
int mylib_test_suite_a_minus_b() {
sput_start_testing();
sput_enter_suite("a minus b");
sput_run_test(test_a_minus_b);
sput_finish_testing();
return sput_get_return_value();
}
/** Test suite for led_on_even call */
int mylib_test_suite_led_on_even() {
sput_start_testing();
sput_enter_suite("led on even");
sput_run_test(test_led_on_even);
sput_finish_testing();
return sput_get_return_value();
}
/** All tests in one bundle */
int mylib_test_suite() {
sput_start_testing();
sput_enter_suite("a plus b");
sput_run_test(test_a_plus_b);
sput_enter_suite("a minus b");
sput_run_test(test_a_minus_b);
sput_enter_suite("led on even");
sput_run_test(test_led_on_even);
sput_finish_testing();
return sput_get_return_value();
}
: mylib.h mylib-test.h.
sput-ino/examples/sput-ino-modules/sput-ino-modules.ino
#include "mylib.h"
#include "mylib-test.h"
/** run tests on device */
void run_tests() {
Serial.println("#################### Start testing...");
// comment out specific test suites if firmware does not
// fit to device memory
// Test suite for a_plus_b call
mylib_test_suite_a_plus_b();
// Test suite for a_minus_b call
mylib_test_suite_a_minus_b();
// Test suite for led_on_even call
mylib_test_suite_led_on_even();
// All tests in one bundle
//mylib_test_suite();
Serial.println("#################### Finished testing");
}
void setup() {
Serial.begin(9600);
while (!Serial);
// run tests
run_tests();
// other code - kinda application business logic
Serial.println("Just show that we call functions from tested lib, nothing useful here");
pinMode(13, OUTPUT);
Serial.print("14+23=");
Serial.println(a_plus_b(14, 23));
Serial.print("14-23=");
Serial.println(a_minus_b(14, 23));
Serial.print("34000+34000=");
Serial.println(a_plus_b(34000, 34000));
}
void loop() {
static int i = 0;
led_on_even(13, i++);
delay(2000);
}
, , .
— :
sput-ino-modules/sput-ino-modules.ino
— :
sput-ino-modules/mylib.h
sput-ino-modules/mylib.cpp
— :
sput-ino-modules/mylib-test.h
sput-ino-modules/mylib-test.cpp
, . , , , / - / ,
, , , :
, :
, :
( , ) :
https://github.com/sadr0b0t/sput-ino-demo
- .
$HOME/Arduino/libraries
cd $HOME/Arduino/libraries/
ln -s /path/to/projects/dir/sput-ino-demo
, , .
:
$HOME/Arduino/libraries/sput-ino-demo/
— .
— /++:
sput-ino-demo/src/
sput-ino-demo/src/mylib.h
sput-ino-demo/src/mylib.cpp
:
#include "mylib.h"
, library.properties:
sput-ino-demo/library.properties
name=sput-ino-demo
version=0.0.1
author=sadr0b0t
maintainer=sadr0b0t
sentence=Demo project for sput-ino, Sput unit testing framework for C/C++ port to Arduino
paragraph=Demo project for sput-ino. Sput is an unit testing framework for C/C++ that focuses on simplicity of use and maximum portability. It is implemented as a single ANSI C compliant header file that provides all macros needed to start unit testing in nearly no time.
category=Other
url=https://github.com/sadr0b0t/sput-ino-demo
architectures=*
(, library.properties, .h, .c, .cpp src/, sput-ino-demo/. / , , .. src/, , .)
— , :
sput-ino-demo/sput-ino-demo/sput-ino-demo.ino
-2, - > > sput-ino-demo/sput-ino-demo, . , > .
-3, - mylib.h mylib.cpp Arduino IDE (.. sput-ino-demo/), . , , .
-4, «.ino».
, , .
:
sput-ino-demo/test/mylib-test-arduino/
sput-ino-demo/test/mylib-test-arduino/mylib-test-arduino.ino
sput-ino-demo/test/mylib-test-arduino/mylib-test.h
sput-ino-demo/test/mylib-test-arduino/mylib-test.cpp
:
sput-ino-demo/test/mylib-test-desktop/
.
, . , . ? -, : , , , ; , . -, , (, , , mock), (, , ). , , .
, :
, , -, , . , sput-ino : sput libc, sput-ino — sput API, . , , sput-ino, libc, .
, :
API
( a_plus_b a_minis_b) — , /++. - , . , . ( , - 16- int AVR, 32- PIC32 64- Intel/AMD ). .
API
( led_on_even) . , , digitalRead digitalWrite. , digitalRead digitalWrite libc , , ( GPIO?). ? - ? x86? AVR ?
, , - , , . , . , .
, API : ( ), . , . .
Arduino.h
sput-ino/example-desktop/Arduino.h
#ifndef WPROGRAM_H
#define WPROGRAM_H
#define OUTPUT 1
#define INPUT 0
#define HIGH 1
#define LOW 0
unsigned long micros();
void pinMode(int pin, int mode);
void digitalWrite(int pin, int val);
int digitalRead(int pin);
#endif // WPROGRAM_H
Arduino.cpp:
sput-ino/example-desktop/Arduino.cpp
// saved values for pins
static int _pin_modes[64];
static int _pin_values[64];
// from Arduino.h
/**
* micros stub
*/
unsigned long micros() {
return 0;
}
/**
* Set GPIO pin mode
*/
void pinMode(int pin, int mode) {
_pin_modes[pin] = mode;
}
/**
* Write GPIO pin value
*/
void digitalWrite(int pin, int val) {
_pin_values[pin] = val;
}
/**
* Read GPIO pin value
*/
int digitalRead(int pin) {
return _pin_values[pin];
}
API , , ( ). .
, , . main:
sput-ino/example-desktop/mylib-test-main.cpp
#include "mylib-test.h"
int main() {
return mylib_test_suite();
}
sput-ino/example-desktop/build.sh
#!/bin/sh
# simple build script, feel free to modify or convert it
# to your favourite build system config
#gcc -c c_file_stub.c
#g++ -std=c++11 -c cpp_file_stub.cpp
g++ -std=c++11 -c \
-I. -I../examples/sput-ino-modules -I$HOME/Arduino/libraries/sput-ino/src \
Arduino.cpp \
../examples/sput-ino-modules/mylib.cpp \
../examples/sput-ino-modules/mylib-test.cpp \
mylib-test-main.cpp
g++ *.o -o test_mylib
( )
./test_mylib
:
== Entering suite #1, "a plus b" ==
[1:1] test_a_plus_b:#1 "2 + 2 == 4" pass
[1:2] test_a_plus_b:#2 "-2 + 2 == 0" pass
[1:3] test_a_plus_b:#3 "34000 + 34000 == 68000" pass
--> 3 check(s), 3 ok, 0 failed (0.00%)
== Entering suite #2, "a minus b" ==
[2:1] test_a_minus_b:#1 "115 - 6 == 109" pass
[2:2] test_a_minus_b:#2 "13 - 17 == -4" pass
--> 2 check(s), 2 ok, 0 failed (0.00%)
== Entering suite #3, "led on even" ==
[3:1] test_led_on_even:#1 "num=2 => led#13 on" pass
[3:2] test_led_on_even:#2 "num=2 => led#13 on" pass
[3:3] test_led_on_even:#3 "num=5 => led#13 off" pass
[3:4] test_led_on_even:#4 "num=5 => led#13 off" pass
[3:5] test_led_on_even:#5 "num=18 => led#13 on" pass
[3:6] test_led_on_even:#6 "num=18 => led#13 on" pass
--> 6 check(s), 6 ok, 0 failed (0.00%)
==> 11 check(s) in 3 suite(s) finished after 0.00 second(s),
11 succeeded, 0 failed (0.00%)
[SUCCESS]
, , . , .
, , digitalWrite GPIO , digitalRead . , digitalWriite . , , digitalWrite , digitalRead. , digitalWrite/digitalRead, - ( digitalRead ), API , (, pinMode).
, API , .
, _Arduino.h ( ):
sput-ino/example-desktop/_Arduino.h
#ifndef _ARDUINO_H
#define _ARDUINO_H
// Additional calls to get extended info from Arduino mocks
/** Get pin mode */
int _get_pin_mode(int pin);
/** Get pin value */
int _get_pin_value(int pin);
#endif // _ARDUINO_H
Arduino.cpp:
sput-ino/example-desktop/Arduino.cpp
// From _Arduino.h
// Calls to get extended info from Arduino mocks
/** Get pin mode */
int _get_pin_mode(int pin) {
return _pin_modes[pin];
}
/** Get pin value */
int _get_pin_value(int pin) {
return _pin_values[pin];
}
, _get_pin_value digitalRead, _get_pin_mode API .
test_led_on_even — test_led_on_even_desktoponly, _get_pin_value digitalRead. , — sput-ino/example-desktop/
:
sput-ino/example-desktop/mylib-test-desktoponly.h
#ifndef MYLIB_TEST_DESKTOPONLY_H
#define MYLIB_TEST_DESKTOPONLY_H
/** Test suite for led_on_even call */
int mylib_test_suite_led_on_even_desktoponly();
/** Desktop-only tests in one bundle */
int mylib_test_suite_desktoponly();
#endif // MYLIB_TEST_DESKTOPONLY_H
:
sput-ino/example-desktop/mylib-test-desktoponly.cpp
// http://www.use-strict.de/sput-unit-testing/tutorial.html
#include "sput.h"
#include "_Arduino.h"
#include "Arduino.h"
#include "mylib.h"
/** Test test_led_on_even call */
bool test_led_on_even_desktoponly() {
// we do not use Arduino API calls here to get info about
// moked chip state, use calls from _Arduino.h instead
sput_fail_unless(led_on_even(13, 2), "num=2 => led#13 on");
sput_fail_unless(_get_pin_value(13) == HIGH, "num=2 => led#13 on");
sput_fail_unless(!led_on_even(13, 5), "num=5 => led#13 off");
sput_fail_unless(_get_pin_value(13) == LOW, "num=5 => led#13 off");
sput_fail_unless(led_on_even(13, 18), "num=18 => led#13 on");
sput_fail_unless(_get_pin_value(13) == HIGH, "num=18 => led#13 on");
}
/*******************************************/
// test suites
/** Test suite for led_on_even call */
int mylib_test_suite_led_on_even_desktoponly() {
sput_start_testing();
sput_enter_suite("led on even (only desktop)");
sput_run_test(test_led_on_even_desktoponly);
sput_finish_testing();
return sput_get_return_value();
}
/** All tests in one bundle */
int mylib_test_suite_desktoponly() {
sput_start_testing();
sput_enter_suite("led on even (only desktop)");
sput_run_test(test_led_on_even_desktoponly);
sput_finish_testing();
return sput_get_return_value();
}
— : - , .
sput-ino/example-desktop/mylib-test-main.cpp
#include "mylib-test.h"
#include "mylib-test-desktoponly.h"
int main() {
return mylib_test_suite() | mylib_test_suite_desktoponly();
}
( mylib-test-desktoponly.cpp)
#!/bin/sh
# simple build script, feel free to modify or convert it
# to your favourite build system config
#gcc -c c_file_stub.c
#g++ -std=c++11 -c cpp_file_stub.cpp
g++ -std=c++11 -c \
-I. -I../examples/sput-ino-modules -I$HOME/Arduino/libraries/sput-ino/src \
Arduino.cpp \
../examples/sput-ino-modules/mylib.cpp \
../examples/sput-ino-modules/mylib-test.cpp \
mylib-test-desktoponly.cpp \
mylib-test-main.cpp
g++ *.o -o test_mylib
./build.sh
./test_mylib
== Entering suite #1, "a plus b" ==
[1:1] test_a_plus_b:#1 "2 + 2 == 4" pass
[1:2] test_a_plus_b:#2 "-2 + 2 == 0" pass
[1:3] test_a_plus_b:#3 "34000 + 34000 == 68000" pass
--> 3 check(s), 3 ok, 0 failed (0.00%)
== Entering suite #2, "a minus b" ==
[2:1] test_a_minus_b:#1 "115 - 6 == 109" pass
[2:2] test_a_minus_b:#2 "13 - 17 == -4" pass
--> 2 check(s), 2 ok, 0 failed (0.00%)
== Entering suite #3, "led on even" ==
[3:1] test_led_on_even:#1 "num=2 => led#13 on" pass
[3:2] test_led_on_even:#2 "num=2 => led#13 on" pass
[3:3] test_led_on_even:#3 "num=5 => led#13 off" pass
[3:4] test_led_on_even:#4 "num=5 => led#13 off" pass
[3:5] test_led_on_even:#5 "num=18 => led#13 on" pass
[3:6] test_led_on_even:#6 "num=18 => led#13 on" pass
--> 6 check(s), 6 ok, 0 failed (0.00%)
==> 11 check(s) in 3 suite(s) finished after 0.00 second(s),
11 succeeded, 0 failed (0.00%)
[SUCCESS]
== Entering suite #1, "led on even (only desktop)" ==
[1:1] test_led_on_even_desktoponly:#1 "num=2 => led#13 on" pass
[1:2] test_led_on_even_desktoponly:#2 "num=2 => led#13 on" pass
[1:3] test_led_on_even_desktoponly:#3 "num=5 => led#13 off" pass
[1:4] test_led_on_even_desktoponly:#4 "num=5 => led#13 off" pass
[1:5] test_led_on_even_desktoponly:#5 "num=18 => led#13 on" pass
[1:6] test_led_on_even_desktoponly:#6 "num=18 => led#13 on" pass
--> 6 check(s), 6 ok, 0 failed (0.00%)
==> 6 check(s) in 1 suite(s) finished after 0.00 second(s),
6 succeeded, 0 failed (0.00%)
[SUCCESS]
, :
, ( ) . — 3 : 1 — ( ), 2 — STEP HIGH, 3 — : STEP LOW, .
:
#define ACTION_STOP 0
#define ACTION_CHECK_BOUNDS 1
#define ACTION_GO_HIGH 2
#define ACTION_STEP 3
int step_count = 0;
int action = ACTION_STOP;
void timer_handle_interrupts() {
// ,
//
if(!timeForStep()) return;
//
if(ACTION_CHECK_BOUNDS == action) {
// -
if(checkBounds()) {
// -
action = ACTION_STOP;
} else {
// ,
action = ACTION_GO_HIGH;
}
} else if(ACTION_GO_HIGH == action) {
// STEP,
digitalWrite(STEP_PIN, HIGH);
action = ACTION_STEP;
} else if(ACTION_STEP == action) {
//
digitalWrite(STEP_PIN, LOW);
step_count++;
if(step_count < max_steps) {
//
action = ACTION_CHECK_BOUNDS;
} else {
//
action = ACTION_STOP;
}
}
}
timer_handle_interrupts — , ( : arduino-timer-api).
, , , , - : , , - . , , . ? , , IDE. 100500 ? ? - .
, :
void test_timer_handle_interrupts() {
// 1
test_timer_handle_interrupts();
// 1
// 2
// 3
// 2
test_timer_handle_interrupts();
// 1
// 2
// 3
// 3
test_timer_handle_interrupts();
// 1
// 2
// 3
// 100500
for(long i = 0; i < 100500 - 3; i++) {
}
// 1
// 2
// 3
// 100500+1
test_timer_handle_interrupts();
// 1
// 2
// 3
// ...
//
}
test_timer_handle_interrupts. , : 1, 2, 3, 103, , , — .
Source: https://habr.com/ru/post/419445/
All Articles