Library testing - pio test

Hi folks,

I try to test my time library. The link is, as usual, GitHub - stoire/einstein: A PlatformIO package for time-handling and string generation . The test folder and tests are ready, but they crash when I type “pio test”. Could you help me fixing it? Thank you.

Best regards,
BP

  • Delete the .pio folder in einstein/.pio at master · stoire/einstein · GitHub, it contains build artifects. The auto-generated .gitignore can also prevent this. You must also locally remove this folder before trying pio test again.
  • The actual compilation errors during pio test stem from the fact that PlatformIO will by default not build the source files in src/, because it is expecting a standard project in which the to-be-tested logic in placed in the lib/ folder. However, since you’ve made the library itself a project with the platformio.ini file, and all the source code of it is in src/, the option has test_build_project_src to be activated.

If you do that, and have a Arduino Uno plugged, in, you get

(py38) C:\Users\Max\temp\einstein>pio test
Verbose mode can be enabled via `-v, --verbose` option
Collected 2 items

Processing test_converter in uno environment
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Building...
Uploading...

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file ".pio\build\uno\firmware.hex"
avrdude: writing flash (10832 bytes):

Writing | ################################################## | 100% 1.74s

avrdude: 10832 bytes of flash written
avrdude: verifying flash memory against .pio\build\uno\firmware.hex:
avrdude: load data flash data from input file .pio\build\uno\firmware.hex:
avrdude: input file .pio\build\uno\firmware.hex contains 10832 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 1.39s

avrdude: verifying ...
avrdude: 10832 bytes of flash verified

avrdude: safemode: Fuses OK (E:00, H:00, L:00)

avrdude done.  Thank you.

Testing...
If you don't see any output for the first 10 secs, please reset board (press reset button)

test\test_converter\test_converters.cpp:230:test_ms2s_lt_quocient       [PASSED]
test\test_converter\test_converters.cpp:231:test_ms2s_lt_remainder      [PASSED]
test\test_converter\test_converters.cpp:232:test_ms2s_eq_quocient       [PASSED]
test\test_converter\test_converters.cpp:233:test_ms2s_eq_remainder      [PASSED]
test\test_converter\test_converters.cpp:234:test_ms2s_gt_quocient       [PASSED]
test\test_converter\test_converters.cpp:235:test_ms2s_gt_remainder      [PASSED]
test\test_converter\test_converters.cpp:237:test_s2min_lt_quocient      [PASSED]
test\test_converter\test_converters.cpp:238:test_s2min_lt_remainder     [PASSED]
test\test_converter\test_converters.cpp:239:test_s2min_eq_quocient      [PASSED]
test\test_converter\test_converters.cpp:240:test_s2min_eq_remainder     [PASSED]
test\test_converter\test_converters.cpp:241:test_s2min_gt_quocient      [PASSED]
test\test_converter\test_converters.cpp:242:test_s2min_gt_remainder     [PASSED]
test\test_converter\test_converters.cpp:244:test_min2h_lt_quocient      [PASSED]
test\test_converter\test_converters.cpp:245:test_min2h_lt_remainder     [PASSED]
test\test_converter\test_converters.cpp:246:test_min2h_eq_quocient      [PASSED]
test\test_converter\test_converters.cpp:247:test_min2h_eq_remainder     [PASSED]
test\test_converter\test_converters.cpp:248:test_min2h_gt_quocient      [PASSED]
test\test_converter\test_converters.cpp:249:test_min2h_gt_remainder     [PASSED]
test\test_converter\test_converters.cpp:251:test_ms2time_999_ms [PASSED]
test\test_converter\test_converters.cpp:252:test_ms2time_1_s    [PASSED]
test\test_converter\test_converters.cpp:253:test_ms2time_1_s_1_ms       [PASSED]
test\test_converter\test_converters.cpp:254:test_ms2time_59_s   [PASSED]
test\test_converter\test_converters.cpp:255:test_ms2time_1_min  [PASSED]
test\test_converter\test_converters.cpp:256:test_ms2time_1_h    [PASSED]
test\test_converter\test_converters.cpp:258:test_stringify_time [PASSED]
-----------------------
25 Tests 0 Failures 0 Ignored
=============== [PASSED] Took 10.05 seconds ===============

Processing test_helpers in uno environment
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Building...
Uploading...

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file ".pio\build\uno\firmware.hex"
avrdude: writing flash (5804 bytes):

Writing | ################################################## | 100% 0.94s

avrdude: 5804 bytes of flash written
avrdude: verifying flash memory against .pio\build\uno\firmware.hex:
avrdude: load data flash data from input file .pio\build\uno\firmware.hex:
avrdude: input file .pio\build\uno\firmware.hex contains 5804 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.75s

avrdude: verifying ...
avrdude: 5804 bytes of flash verified

avrdude: safemode: Fuses OK (E:00, H:00, L:00)

avrdude done.  Thank you.

Testing...
If you don't see any output for the first 10 secs, please reset board (press reset button)

test\test_helpers\test_helpers.cpp:46:test_left_zeros_gt        [PASSED]
test\test_helpers\test_helpers.cpp:47:test_left_zeros_eq        [PASSED]
test\test_helpers\test_helpers.cpp:48:test_left_zeros_lt        [PASSED]
test\test_helpers\test_helpers.cpp:49:test_n_chars      [PASSED]
-----------------------
4 Tests 0 Failures 0 Ignored
=============== [PASSED] Took 8.41 seconds ===============

Test            Environment    Status    Duration
--------------  -------------  --------  ------------
test_converter  uno            PASSED    00:00:10.055
test_helpers    uno            PASSED    00:00:08.408
=============== 2 succeeded in 00:00:18.463 ===============

As an improvement thought, you can also run the tests on the local machine with the locally available compiler (platform = native), that way it can be integrated into CI workflows / automated testing in Github etc.

Oh nice. Thank you! Can you better explain the last paragraph about the native option? I understand one may integrate the library into a greater project and the CI/CD can run its tests. But the “native” platform part I don’t get.

Other question: is it possible to use virtual instead of embedded environments for testing, building and debugging? It is essential for an embedded environment.

Moreover, it seems I do the job of QA or a test engineer. Do you have any remote applications positions? :stuck_out_tongue:

PlatformIO has good documentation on it: Redirecting.... Especially see the examples that are linked in there. (platformio-examples/unit-testing at develop · platformio/platformio-examples · GitHub)

Basically, the native platform attempts to use the toolchain of the host computer to compile the ‘firmware’ or run tests. There are even mocking libraries for Arduino so that libraries depending on Arduino.h and the functionality therein (see arduino-mock example).

For your library this is also possible. The only place where you really depend on Arduino.h is in the code in src/helpers using String, in other places you do #include <Arduino.h> just to get the standard fixed-width integer types, which are also available in just #include <stdint.h>.

If I add

[env:native]
platform = native
build_flags = -std=gnu++11
lib_deps =
    ArduinoFake
test_build_project_src = yes

to the bottom of the platformio.ini, and further rewrite these parts

so that the standard main() function is compiled for desktop, by using the code

#ifdef ARDUINO
void setup() {}

void loop() {
#else 
int main() {
#endif

to replace the setup() and loop() with just main() (same for here), I can use

> pio test -e native
Verbose mode can be enabled via `-v, --verbose` option
Collected 2 items

Processing test_converter in native environment
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Building...
Testing...
test\test_converter\test_converters.cpp:234:test_ms2s_lt_quocient       [PASSED]
test\test_converter\test_converters.cpp:235:test_ms2s_lt_remainder      [PASSED]
test\test_converter\test_converters.cpp:236:test_ms2s_eq_quocient       [PASSED]
test\test_converter\test_converters.cpp:237:test_ms2s_eq_remainder      [PASSED]
test\test_converter\test_converters.cpp:238:test_ms2s_gt_quocient       [PASSED]
test\test_converter\test_converters.cpp:239:test_ms2s_gt_remainder      [PASSED]
test\test_converter\test_converters.cpp:241:test_s2min_lt_quocient      [PASSED]
test\test_converter\test_converters.cpp:242:test_s2min_lt_remainder     [PASSED]
test\test_converter\test_converters.cpp:243:test_s2min_eq_quocient      [PASSED]
test\test_converter\test_converters.cpp:244:test_s2min_eq_remainder     [PASSED]
test\test_converter\test_converters.cpp:245:test_s2min_gt_quocient      [PASSED]
test\test_converter\test_converters.cpp:246:test_s2min_gt_remainder     [PASSED]
test\test_converter\test_converters.cpp:248:test_min2h_lt_quocient      [PASSED]
test\test_converter\test_converters.cpp:249:test_min2h_lt_remainder     [PASSED]
test\test_converter\test_converters.cpp:250:test_min2h_eq_quocient      [PASSED]
test\test_converter\test_converters.cpp:251:test_min2h_eq_remainder     [PASSED]
test\test_converter\test_converters.cpp:252:test_min2h_gt_quocient      [PASSED]
test\test_converter\test_converters.cpp:253:test_min2h_gt_remainder     [PASSED]
test\test_converter\test_converters.cpp:255:test_ms2time_999_ms [PASSED]
test\test_converter\test_converters.cpp:256:test_ms2time_1_s    [PASSED]
test\test_converter\test_converters.cpp:257:test_ms2time_1_s_1_ms       [PASSED]
test\test_converter\test_converters.cpp:258:test_ms2time_59_s   [PASSED]
test\test_converter\test_converters.cpp:259:test_ms2time_1_min  [PASSED]
test\test_converter\test_converters.cpp:260:test_ms2time_1_h    [PASSED]
test\test_converter\test_converters.cpp:262:test_stringify_time [PASSED]

-----------------------
25 Tests 0 Failures 0 Ignored
OK
=============== [PASSED] Took 3.17 seconds ===============

Processing test_helpers in native environment
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Building...
Testing...
test\test_helpers\test_helpers.cpp:50:test_left_zeros_gt        [PASSED]
test\test_helpers\test_helpers.cpp:51:test_left_zeros_eq        [PASSED]
test\test_helpers\test_helpers.cpp:52:test_left_zeros_lt        [PASSED]
test\test_helpers\test_helpers.cpp:53:test_n_chars      [PASSED]

-----------------------
4 Tests 0 Failures 0 Ignored
OK
=============== [PASSED] Took 4.43 seconds ===============

Test            Environment    Status    Duration
--------------  -------------  --------  ------------
test_converter  native         PASSED    00:00:03.172
test_helpers    native         PASSED    00:00:04.435
=============== 2 succeeded in 00:00:07.607 ===============

so all tests are compilable and have executed correctly by using the native compiler, no Arduino Uno needed.

Of course I just use pio test, it will run on both environments, testing the embedded and native case.

Test            Environment    Status    Duration
--------------  -------------  --------  ------------
test_converter  uno            PASSED    00:00:10.633
test_converter  native         PASSED    00:00:03.109
test_helpers    uno            PASSED    00:00:08.295
test_helpers    native         PASSED    00:00:03.132
=============== 4 succeeded in 00:00:25.169 ===============

Note that that ofc needs a host compiler. I use Windows 10 with the MinGW toolchain installed to give me a GCC and friends.

Great trick! I feel overwhelmed and thankful for these flags. I am working on a SD-based library as well which this knowledge is helpful.

Regarding the SD library I started, I use it in a sensor reading library GitHub - stoire/arduino-logging-example: A minimal example with Arduino SD logging. It was woking yesterday, but not today. Could you take a look? The platformio.ini and error are below.

[env:uno]
platform = atmelavr
board = uno
framework = arduino
lib_deps = 
	painlessmesh/arduinoUnity@^0.0.2
	https://github.com/brunolnetto/einstein.git
	https://github.com/brunolnetto/fortuneteller.git
	arduino-libraries/SD @ ^1.2.4
	SPI

error: Error: Please specify `upload_port` for environment or use global `--upload-port` option.

Do you have an Uno connected to your computer? It’s looking for one to run the tests in the uno environment (if you’ve run pio test, otherwise you may have attempted a normal upload?)

I try to upload the “Blink” project, but it still does no upload. It attempts to install other framework-arduino-avr like “prusa_rambo” and “majorcore”. Even though, still not working.

Can you show a screenshot of PIO Home → Devices? If a Uno is connected it should show something like

If not, something is wrong with your Uno.

Also make double sure you’ve selected the correct project via the project ennvironment switcher.

If it still doesn’t work, please post the output of the “Upload” task.

The tab “Devices” shows “No device detected”. It is a progress on our investigation. I tested on two other boards, an uno and a mega, without any output on “Devices”.

You must also press “Refresh” manually in the upper right corner, it doesn’t auto-update.

Evenso, no device appeared.

And the Windows device manager also shows no COM port with an Uno on it?

grafik

I use linux. The command lsusb outputs the logging below. No Arduino detected, although its leds are blinking:

Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:8008 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 004: ID 5986:014c Acer, Inc MSI Integrated Webcam
Bus 003 Device 003: ID 13d3:3394 IMC Networks Bluetooth
Bus 003 Device 006: ID 1532:0016 Razer USA, Ltd DeathAdder 3.5G
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

What happens when you have the Arduino unplugged, and open a terminal and do

sudo dmesg -w

then press enter once to get a seperator and then plug in the Arduino.

What output, if any, does appear?

A wild log appears:

[14539.841448] usb 3-6: new full-speed USB device number 8 using xhci_hcd
[14539.990997] usb 3-6: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice= 2.54
[14539.991000] usb 3-6: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[14539.991001] usb 3-6: Product: USB2.0-Serial
[14539.992463] ch341 3-6:1.0: ch341-uart converter detected
[14539.992963] usb 3-6: ch341-uart converter now attached to ttyUSB0

I uploaded VSCode due some IDE notification. Now it detects the port, but times out with the following log:

avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00

Well at least the CH341 device seem to be detected now and drivers are loaded. Why weren’t they before? Bad USB cable or USB port? The CH340 type chips are the very cheap chinese chips and they also had some bug in the linux drivers for them once (USB: serial: ch341: fix wrong baud rate setting calculation - Patchwork) .

This usually occurs if the either the bootloader speed is wrongly configured or if the target chip is dead. Is this the Uno or Mega that’s attempting to get programmed here?

Now that you mention, I changed the board parameter on platformio.ini to ATmega2560 as well as plugged board, but it remained uno somewhere. When I change both board and parameters back to uno, it uploads sucessfully. Well, once more thank you sir. I hope you remain with us for a long while.

Stay ready for next questions. My next challenge is to input real time on my clock library wich Real Time Clock RTC DS1302 module.

Then you selected the wrong project environment that has the Uno and not the Mega? You checked the project environment switcher documentation yes?