Native and embedded tests with hardware stuff and pure logic intertwined

I want to test my src code on the embedded device and natively.
The problem is that there is a lot hardware related stuff that makes it hard to separate the two tests.
I have for example a function in a class that is only building the path for writing to an SD card. If I only want to test this one now natively, what would be the best method to do this?

Currently my platformio.ino looks like this:

; Latest stable version
[env:native]
platform = native
test_ignore = 
	*Embedded*
	*embedded*
build_flags = -std=gnu++11 
lib_deps = 
	bblanchon/ArduinoJson@^6.18.5
	ArduinoFake
lib_ldf_mode=chain+
test_build_project_src = true
#only include Statistics for now for native platform, because the rest is not compilable with the libraries needed atm
src_filter = +<*> -<.git/> -<.svn/> -<Led/> 

[env:nano33iot]
board = nano_33_iot
#targets = upload, monitor
framework = arduino
board_build.mcu = SAMD21
platform = atmelsam
test_ignore = 
	*native*
	*Native*
test_build_project_src = true
lib_deps = 
	sparkfun/SparkFun VCNL4040 Proximity Sensor Library @ ^1.0.2
	sparkfun/SparkFun I2C Mux Arduino Library @ ^1.0.1
	bblanchon/StreamUtils@^1.6.1
	rweather/Crypto @ ^0.2.0
	rweather/CryptoLW @ ^0.2.0
	jandrassy/StreamLib@^1.1.0
	arduino-libraries/ArduinoMDNS@^0.0.0
	adafruit/Adafruit MCP23017 Arduino Library@^1.3.0
	sparkfun/SparkFun ATECCX08a Arduino Library@^1.3.0
	bblanchon/ArduinoJson@^6.18.3
	greiman/SdFat@^2.1.0
	arduino-libraries/WiFiNINA@^1.8.13

I basically excluded everything for native with the src_filter and test_build_project_src = true to built from the src folder when testing, but this is not a real solution to this problem.

For example I get the following error atm:

In file included from src/Logs/logs.cpp:1:
In file included from src/Logs/logs.h:8:
src/TableConfig/sd_card_handler.h:4:10: fatal error: 'SdFat.h' file not found
#include "SdFat.h"

The problem is, that I don’t know how to predefine something only for native tests like:

#if defined(NATIVE_TEST)
  #include <SdFat_mocked.h>
#endif

because then I could do something like:

#if defined(NATIVE_TEST)
  #include <SdFat_mocked.h>
#else
  #include <SdFat.h>
#endif

But this also feels very cumbersome. How do you this the right way?

You could use#if !defined(ARDUINO) to detect that you’re on a desktop in general (like in official examples), or, use #if defined(UNIT_TEST) (set here) to detect that you’re running inside unit test mode (but that doesn’t give you the info whether it’s a native or embedded unit test).

Well one strategy would be to always use the same same (SdFat.h) but in the embedded test have that provided by different header that is either provided by a library that is lib_ignored in the embedded case, or have a -I <some folder> build_flags directive to include the folder to where the mocked version of SdFat.h is – that would reduce clutter a bit.

1 Like