fabiobatsilva / arduinofake Goto Github PK
View Code? Open in Web Editor NEWArduino mocking made easy
Home Page: https://platformio.org/lib/show/1689/ArduinoFake
License: MIT License
Arduino mocking made easy
Home Page: https://platformio.org/lib/show/1689/ArduinoFake
License: MIT License
Hi there. I'm new to Arduino and trying to use your mocking library as part of a suite of gtest framework tests.
My CMakeLists.txt file looks like this:
cmake_minimum_required(VERSION 3.14) # version can be different
project(TestProject) #name of your project
# Set compilation flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto=1")
include(CTest)
include(FetchContent)
# Set a flag indicating whether building with CMake
set(BUILD_WITH_CMAKE TRUE)
# Conditionally include the appropriate headers based on BUILD_WITH_CMAKE
if(BUILD_WITH_CMAKE)
add_compile_definitions(BUILD_WITH_CMAKE)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/_deps/arduinofake-src/src)
endif()
enable_testing()
FetchContent_Declare(
googletest
# Specify the commit you depend on and update it regularly.
URL https://github.com/google/googletest/archive/5376968f6948923e2411081fd9372e71a59d8e77.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
# Fetch ArduinoFake library
FetchContent_Declare(
ArduinoFake
GIT_REPOSITORY https://github.com/FabioBatSilva/ArduinoFake.git
GIT_TAG cf9c596b73ffe7e7cf39faeb550bbef8598edb98
)
FetchContent_MakeAvailable(ArduinoFake)
# Now simply link against gtest or gtest_main as needed. Eg
add_executable(mytests mytests.cpp)
target_link_libraries(mytests gtest)
add_test(NAME example_test COMMAND mytests)
I had no issues running make before adding the ArduinoFake stuff, but am now getting the error:
[100%] Linking CXX executable main-d.exe
lto-wrapper.exe: warning: using serial compilation of 2 LTRANS jobs
lto-wrapper.exe: note: see the '-flto' option documentation for more information
lto1.exe: error: two or more sections for .gnu.lto__ZN10SerialTest19test_extends_streamEv.4317.e9bafa65
(null):0: confused by earlier errors, bailing out
lto-wrapper.exe: fatal error: C:\msys64\mingw64\bin\g++.exe returned 1 exit status
compilation terminated.
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: error: lto-wrapper failed
collect2.exe: error: ld returned 1 exit status
I'm not sure what I'm doing wrong or if I'm using the library wrong. Would anyone be willing to help me out?
One of the libraries I'm using expects 'EEPROM.h'
Is there any intention to support a version of this in ArduinoFake?
I am new to Arduino and trying to mock the application with this library. When I execute the test cases, I get the below message; when I try to check the JSON, it does not exist. Can you please suggest a way forward.
------------ pcSimulation:test_radiaion [ERRORED] Took 3.07 seconds ------------
=================================== SUMMARY ===================================
Environment Test Status Duration
pcSimulation test_radiaion ERRORED 00:00:03.067
================== 1 test cases: 0 succeeded in 00:00:03.067 ==================
-> Verbosity level can be increased via -v, -vv, or -vvv
option
Collected 1 tests
Building...
Saved JSON report to the C:\Users\10364462.platformio.cache\tmp\test-list-72429.json
#include <ArduinoFake.h>
int main() {
Serial.begin(9600);
Serial.print("hello");
}
$ .pio/build/native/program
Segmentation fault (core dumped)
I would have expected Serial.begin() to be a no-op, or maybe just set a flag that begin was called, and Serial.print() to simply write to stdout. Is this an unreasonable assumption?
https://github.com/FabioBatSilva/ArduinoFake/tree/master/src/fakeit – currently it is a hardcoded, very old version.
I actually came here to fix a few issues that the lib is throwing at me, when I build my tests with -Wpedantic
. But I see what's going on now -> and I don't think trying to fix the old hardcoded version would be a good idea ;-)
A better one would be:
fakeit
to its latest available version.lib_deps
?I want to play around with your testing framework but can't compile the example wiring-blink
.
I get this error for each occurence of std::strstr
:
.piolibdeps\ArduinoFake_ID1689\src/ArduinoFake.h:33:14: error: 'strstr' is not a member of 'std'
if (std::strstr(typeid(*var).name(), #mock)) { \
^
.piolibdeps\ArduinoFake_ID1689\src/ArduinoFake.h:79:13: note: in expansion of macro 'ArduinoFakeReturnInstaceOf'
ArduinoFakeReturnInstaceOf(p, Serial)
^~~~~~~~~~~~~~~~~~~~~~~~~~
I'm on windows with mingw-w64: gcc-7.1.0
platform information: https://pastebin.com/ZCCbF3E9
I did not find any information on this. Maybe you know the reason?
Hi, i've trying to create another serial port with the framework, but could't make it work, i need to mock Serial1.
Is there any tutorial on how to make this mocks for this framework?
Thanks
Where has the main.cpp File to be
I put it in the src folder.
Thanks for the great work, it is very handy!
I'm just a bit curious if there has been a licence chosen for this project? [According to Github]:(https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/licensing-a-repository)
You're under no obligation to choose a license. However, without a license, the default copyright laws apply, meaning that you retain all rights to your source code and no one may reproduce, distribute, or create derivative works from your work.
But I can see that you have guidelines for contributing which suggests that you're ok with people creating derivative works. Could you clarify?
I have a failing test - because I haven't mocked/faked all the Arduino bits fully.
When I run the tests I get a Failed
(correctly) reported for the test, but theres no error details. Should there be?
I have to debug each time to find which thing I've not mocked/faked properly.
I'm new to both PlatformIO and ArduinoFake
Any help much appreciated!
platformIO.ini snippet:
[env:native]
platform = native
build_type = debug
lib_deps =
ArduinoFake
debug_test = mytest
build_flags = -std=gnu++11
Good morning, i am wrapping my head around this.
i'm on PlatformIO in VScode, using Unity as test suite.
i am using Windows 10, installed minGW, test compiles and runs whitout including ArduinoFake".
As soon as i do it, ( without adding code to the test file) i get that error.
i assume it's not a minGW issue, because if i coment the "#include" and "using namespace" lines, the tests run correctly (for the hardcoded assertion).
[platformio]
default_envs = native
[env:native]
platform = native
test_framework = unity
test_ignore = test/test_embedded
test_filter = test/test_native
build_flags =
-std=gnu++11
debug_test = test/test_native
lib_deps = ArduinoFake
#include "../.pio/libdeps/native/ArduinoFake/src/ArduinoFake.h"
#include <unity.h>
using namespace fakeit;
void setUp(void) {
// set stuff up here
}
void tearDown(void) {
// clean stuff up here
}
void test_setup_function_default_host(void)
{
TEST_ASSERT_TRUE(1 == (2-1));
}
int main(int argc, char **argv) {
UNITY_BEGIN();
RUN_TEST(test_setup_function_default_host);
UNITY_END();
return 0;
}
pio test -e "native" -f "test_native" -vv
Processing test_native in native environment
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Building...
Verbose mode can be enabled via `-v, --verbose` option
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 2 compatible libraries
Scanning dependencies...
Dependency Graph
|-- ArduinoFake @ 0.4.0
|-- Unity @ 2.5.2
Building in test mode
Compiling .pio\build\native\unity_config_build\unity_config.o
Compiling .pio\build\native\test\test_native\test_constructors.o
Compiling .pio\build\native\libbcd\ArduinoFake\ArduinoFake.o
Compiling .pio\build\native\libbcd\ArduinoFake\ClientFake.o
Compiling .pio\build\native\libbcd\ArduinoFake\EEPROMFake.o
Compiling .pio\build\native\libbcd\ArduinoFake\FunctionFake.o
Compiling .pio\build\native\libbcd\ArduinoFake\PrintFake.o
Compiling .pio\build\native\libbcd\ArduinoFake\SPIFake.o
Compiling .pio\build\native\libbcd\ArduinoFake\SerialFake.o
Compiling .pio\build\native\libbcd\ArduinoFake\StreamFake.o
Compiling .pio\build\native\libbcd\ArduinoFake\WireFake.o
Compiling .pio\build\native\libbcd\ArduinoFake\arduino\IPAddress.o
Compiling .pio\build\native\libbcd\ArduinoFake\arduino\WString.o
Compiling .pio\build\native\libbcd\ArduinoFake\arduino\noniso.o
Compiling .pio\build\native\lib6e1\Unity\unity.o
Archiving .pio\build\native\lib6e1\libUnity.a
Indexing .pio\build\native\lib6e1\libUnity.a
Archiving .pio\build\native\libbcd\libArduinoFake.a
Indexing .pio\build\native\libbcd\libArduinoFake.a
Linking .pio\build\native\program.exe
Testing...
Program errored with 3221225785 code
Any hints? as i am not including any code, i think i am not missing any part of the function mocking.
i also searched some posts regarding that exact error code, and reinstalled minGW in consequence. but still no success.
Thanks!
I am using (I guess as most people) ArduinoFake for unittesting arduino (avr) code on my "native" platform (gcc on linux X64). I am using it in combination with platformio and its test runner.
There are a number of libraries I am using that should work with any arduino platform (like ArduinoJson and others). What I am not sure about is how to combine them with platformio, the native platform and ArduinoFake. In the library.json you specify "frameworks": "arduino"
and "platforms": "native"
. But there is no arduino framework defined in the native platform. And also the arduino framework requires a board, which there aren't for the native platform. So am I missing something here?
In my attempt to incorporate ArduinoFake into an example project using CppUTest:
https://github.com/graial/ArduinoFake-cpputest
I'm now failing to target the source file under test.
Within your wiring-blink example, you manage to mock out the Arduino system calls with ArduinoFake, and then call loop()
and setup()
from the source file.
This is currently failing for me, probably because of something wrong in CmakeLists.txt
a call to loop()
triggers fakeit::UnexpectedMethodCallException rather than the loop()
in blink.cpp.
Alternatively, if I try to just link the object, I get a redefinition error.
Do you have any idea how to get cmake to look for loop()
in the source file? rather than in ArduinoFake?
Or is there some way to flag the loop()
function so that it doesn't get passed to ArduinoFake?
Cheers
Does anyone know of a mock sensor library of classes that can be used for simulating realistic sensor data using maths and not just rand ?
Would be a nice addition
Is it possible to use the FakeIt impl. built by ArduinoFake to run mocks on the device? Otherwise it seems you need to install and build FakeIt separately to get on device mocks. Either that or a way to prevent ArduinoFake reimplementing <Arduino.h>
I'm still noobish with C++ – I mostly use PlatformIO, never wrote a single line of Makefile.
So, the question is: how do I build this project?
I've seen CONTRIBUTING.md, but it's inconclusive.
I've tried using make
(with no success):
➜ ArduinoFake git:(master) ✗ make
make: cmake: No such file or directory
make: *** [cmake] Error 1
➜ ArduinoFake git:(master) ✗ mkdir build
➜ ArduinoFake git:(master) ✗ make
make: cmake: No such file or directory
make: *** [cmake] Error 1
➜ ArduinoFake git:(master) ✗ make all
make: cmake: No such file or directory
make: *** [cmake] Error 1
➜ ArduinoFake git:(master) ✗ make build
make: cmake: No such file or directory
make: *** [cmake] Error 1
I've tried using pio run
(kinda works, but there is no main()
):
➜ ArduinoFake git:(master) ✗ pio run
Processing native (platform: native)
-------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 0 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Compiling .pio/build/native/src/ArduinoFake.o
Compiling .pio/build/native/src/ClientFake.o
Compiling .pio/build/native/src/FunctionFake.o
Compiling .pio/build/native/src/PrintFake.o
Compiling .pio/build/native/src/SPIFake.o
Compiling .pio/build/native/src/SerialFake.o
Compiling .pio/build/native/src/StreamFake.o
Compiling .pio/build/native/src/WireFake.o
Compiling .pio/build/native/src/arduino/IPAddress.o
Compiling .pio/build/native/src/arduino/WString.o
Compiling .pio/build/native/src/arduino/noniso.o
Linking .pio/build/native/program
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
*** [.pio/build/native/program] Error 1
===================================== [FAILED] Took 6.83 seconds =====================================
I've tried using pio test
(finally something working as expected):
➜ ArduinoFake git:(master) pio test
Verbosity level can be increased via `-v, -vv, or -vvv` option
Collected 1 tests
Processing * in native environment
-------------------------------------------------------------------------------------------------------
Building...
Library Manager: Installing throwtheswitch/Unity @ ^2.5.2
Unpacking [####################################] 100%
Library Manager: [email protected] has been installed!
Testing...
test/main.cpp:33: ArduinoStringTest::test_constructors [PASSED]
test/main.cpp:127: ArduinoContextTest::test_single_instance [PASSED]
test/main.cpp:128: ArduinoContextTest::test_reset [PASSED]
test/main.cpp:129: ArduinoContextTest::test_function_mock [PASSED]
test/main.cpp:130: ArduinoContextTest::test_print_mock [PASSED]
test/main.cpp:131: ArduinoContextTest::test_stream_mock [PASSED]
test/main.cpp:132: ArduinoContextTest::test_serial_mock [PASSED]
test/main.cpp:133: ArduinoContextTest::test_getter_overload_with_proxy [PASSED]
test/main.cpp:134: ArduinoContextTest::test_getter_overload_with_mapping [PASSED]
test/main.cpp:135: ArduinoContextTest::test_unknown_instance_exception [PASSED]
test/main.cpp:187: FunctionTest::test_timestamps [PASSED]
test/main.cpp:188: FunctionTest::test_pin_mode [PASSED]
test/main.cpp:189: FunctionTest::test_digital_pin [PASSED]
test/main.cpp:190: FunctionTest::test_analog_pin [PASSED]
test/main.cpp:191: FunctionTest::test_delay [PASSED]
test/main.cpp:192: FunctionTest::test_detach [PASSED]
test/main.cpp:193: FunctionTest::test_attach [PASSED]
test/main.cpp:194: FunctionTest::test_cli [PASSED]
test/main.cpp:195: FunctionTest::test_sei [PASSED]
test/main.cpp:196: FunctionTest::test_pulsein [PASSED]
test/main.cpp:197: FunctionTest::test_shift [PASSED]
test/main.cpp:198: FunctionTest::test_random [PASSED]
test/main.cpp:199: FunctionTest::test_tone [PASSED]
test/main.cpp:200: FunctionTest::test_map [PASSED]
test/main.cpp:100: PrintTest::test_print_variables [PASSED]
test/main.cpp:101: PrintTest::test_println_variables [PASSED]
test/main.cpp:168: StreamTest::test_extends_print [PASSED]
test/main.cpp:169: StreamTest::test_stream_basics [PASSED]
test/main.cpp:170: StreamTest::test_stream_find [PASSED]
test/main.cpp:171: StreamTest::test_stream_parse [PASSED]
test/main.cpp:172: StreamTest::test_stream_read [PASSED]
test/main.cpp:80: SerialTest::test_extends_stream [PASSED]
test/main.cpp:81: SerialTest::test_global_serial [PASSED]
test/main.cpp:82: SerialTest::test_basics [PASSED]
test/main.cpp:103: WireTest::test_extends_stream [PASSED]
test/main.cpp:104: WireTest::test_global_wire [PASSED]
test/main.cpp:105: WireTest::test_basics [PASSED]
test/main.cpp:35: SpiTest::test_basics [PASSED]
test/main.cpp:141: ClientTest::test_basics [PASSED]
test/main.cpp:142: ClientTest::test_connect [PASSED]
test/main.cpp:143: ClientTest::test_write [PASSED]
test/main.cpp:144: ClientTest::test_read [PASSED]
test/main.cpp:145: ClientTest::test_inject_instance [PASSED]
test/main.cpp:13: IncludeTest::test_empty [PASSED]
-------------------------------- native:* [PASSED] Took 61.63 seconds --------------------------------
=============================================== SUMMARY ===============================================
Environment Test Status Duration
------------- ------ -------- ------------
native * PASSED 00:01:01.629
============================= 44 test cases: 44 succeeded in 00:01:01.629 =============================
Anything else? Should I just run pio test
, or do I somehow make make
working?
I'm on MacOS with CLion, if that changes anything…
I am working a lot on ESP32 mcu's. This arduino core's have some libraries which are used a lot (WiFi, UDP, Ethernet, etc.).
how do you handle situations like this?
As per the documentation it should be possible to check if the connection is available.
Given:
when (!Serial);
The compiler spits out: undefined reference to 'Serial_::operator bool()'
. It seems it was commented out some time ago.
During the struggle with issue #6 I ran into the following. PROGMEM
is defined in pgmspace.h
but that file is only included in WString.cpp. Because of it, I ran into an issue with the OneWire library, which uses PROGMEM, and threw these errors:
*** [.pio/build/native/lib26a/therma_node/therma_node.o] Error 1
.pio/libdeps/native/OneWire_ID1/OneWire.cpp:496:30: error: expected initializer before ‘dscrc2x16_table’
496 | static const uint8_t PROGMEM dscrc2x16_table[] = {
| ^~~~~~~~~~~~~~~
.pio/libdeps/native/OneWire_ID1/OneWire.cpp: In static member function ‘static uint8_t OneWire::crc8(const uint8_t*, uint8_t)’:
.pio/libdeps/native/OneWire_ID1/OneWire.cpp:511:23: error: ‘dscrc2x16_table’ was not declared in this scope
511 | crc = pgm_read_byte(dscrc2x16_table + (crc & 0x0f)) ^
| ^~~~~~~~~~~~~~~
.pio/libdeps/native/OneWire_ID1/OneWire.cpp:511:9: error: ‘pgm_read_byte’ was not declared in this scope; did you mean ‘read_bytes’?
511 | crc = pgm_read_byte(dscrc2x16_table + (crc & 0x0f)) ^
| ^~~~~~~~~~~~~
| read_bytes
*** [.pio/build/native/lib3ac/OneWire_ID1/OneWire.o] Error 1
The solution for me was to #include pgmspace.h
in WString.h
instead. I did the same for noniso.h
.
I see yield is defined in arduino/Arduino.h
but not implemented anywhere. I am using ArduinoFake with DallasTemperature, which uses the yield
function, which causes the following compile error: undefined reference to
yield'`. How is yield supposed to be implemented? I don't care what it does (it won't even be called), but my efforts at implementing it myself with am empty function didn't work.
Hi I am trying to add SPI Arduino Core library and contribute in ArduinoFake for the community.
I have followed the contribution guidelines and added SPI the same way as the Print
since its quite similar to it. The issue was that I encountered an error that I was stuck on ArduinoFake.h
:
from test/main.cpp:1:
src/ArduinoFake.h: In member function ‘SPIClassFake* ArduinoFakeContext::SPIClass(SPIClass*)’:
src/ArduinoFake.h:59:52: error: cannot dynamic_cast ‘instance’ (of type ‘class SPIClass*’) to type ‘class SPIClassFakeProxy*’ (source type is not polymorphic)
if (dynamic_cast<name##FakeProxy*>(instance)) { \
^
src/ArduinoFake.h:103:9: note: in expansion of macro ‘_ArduinoFakeInstanceGetter2’
_ArduinoFakeInstanceGetter2(SPIClass, SPIClass)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
src/ArduinoFake.h:60:59: error: cannot dynamic_cast ‘instance’ (of type ‘class SPIClass*’) to type ‘class SPIClassFakeProxy*’ (source type is not polymorphic)
return dynamic_cast<name##FakeProxy*>(instance)->get##name##Fake(); \
^
src/ArduinoFake.h:103:9: note: in expansion of macro ‘_ArduinoFakeInstanceGetter2’
_ArduinoFakeInstanceGetter2(SPIClass, SPIClass)
It showed when I added _ArduinoFakeInstanceGetter2(SPIClass, SPIClass)
on ArduinoFakeContext
.
Maybe because SPI Class has static members? But I have removed the static
modifier on the members of SPIClass but it did not fixed the problem.
I have forked your repo to and made a branch to work on here is the link of my rcalcover#1
I'm starting a embedded project wich uses ESP32 microcontroller using the Arduino Framework and some modules like a Sigfox Module. I want to test a function which send messages via Sigfox:
void sigfoxSendMsg(String buf_tx)
{
//Adding line break
buf_tx += "\n";
//******************************
//Enable Sigfox Module
digitalWrite(SIGFOX_ENABLE, HIGH);
delay(1000);
#ifndef TEST
//Channel reset to ensure correct frequency
Serial1.print("AT$RC\n");
//******************************
//Sending data on Sigfox
Serial1.print(buf_tx);
#else
Serial.print("AT$RC\n");
Serial.print(buf_tx);
#endif
#ifdef SIGFOX_DEBUG
#ifndef TEST
Serial.print(buf_tx);
#endif
#endif
delay(3000);
//disable sigfox module
digitalWrite(SIGFOX_ENABLE, LOW);
}
But when I test it with my test function:
void test_sigfoxSendMsg_should_beAbleTo_SendMessagesCorrectly(){
String packedMessage = "AT$SF=d63c1042"; //Data
When(Method(ArduinoFake(), digitalWrite)).AlwaysReturn();
When(Method(ArduinoFake(), delay)).AlwaysReturn();
When(OverloadedMethod(ArduinoFake(Serial), print, size_t(char))).AlwaysReturn();
sigfoxSendMsg(packedMessage);
Verify(Method(ArduinoFake(), digitalWrite).Using(SIGFOX_ENABLE, HIGH));
Verify(Method(ArduinoFake(), digitalWrite).Using(SIGFOX_ENABLE, LOW));
}
The result of the test show me how the function Serial.print() wasn't mocked:
Building...
Testing...
Program errored with 3221225477 code
How can i fix these errors? I believe that I'am mocking Serial.print() wrongly. Additionaly, there is a way to use Serial1.print() instead of Serial.print() with ArduinoFake? It would help me to other functions that I want to adapt to test also.
I have no issues when I run pio run
or pio test
with fabiobatsilva/[email protected]
.
The issues appear after upgrading to fabiobatsilva/[email protected]
…
In file included from .pio/libdeps/native_arduino/ArduinoFake/src/ClientFake.cpp:1:
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: warning: class 'EEPROMClass' was previously declared as a struct; this is valid, but may result in linker errors under the Microsoft C++ ABI [-Wmismatched-tags]
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
.pio/libdeps/native_arduino/ArduinoFake/src/arduino/EEPROM.h:4:8: note: previous use is here
struct EEPROMClass {
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: note: did you mean struct here?
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
In file included from .pio/libdeps/native_arduino/ArduinoFake/src/EEPROMFake.cpp:2:
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: warning: class 'EEPROMClass' was previously declared as a struct; this is valid, but may result in linker errors under the Microsoft C++ ABI [-Wmismatched-tags]
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
.pio/libdeps/native_arduino/ArduinoFake/src/arduino/EEPROM.h:4:8: note: previous use is here
struct EEPROMClass {
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: note: did you mean struct here?
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
In file included from .pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.cpp:1:
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: warning: class 'EEPROMClass' was previously declared as a struct; this is valid, but may result in linker errors under the Microsoft C++ ABI [-Wmismatched-tags]
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
.pio/libdeps/native_arduino/ArduinoFake/src/arduino/EEPROM.h:4:8: note: previous use is here
struct EEPROMClass {
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: note: did you mean struct here?
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
1 warning generated.
In file included from .pio/libdeps/native_arduino/ArduinoFake/src/FunctionFake.cpp:2:
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: warning: class 'EEPROMClass' was previously declared as a struct; this is valid, but may result in linker errors under the Microsoft C++ ABI [-Wmismatched-tags]
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
.pio/libdeps/native_arduino/ArduinoFake/src/arduino/EEPROM.h:4:8: note: previous use is here
struct EEPROMClass {
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: note: did you mean struct here?
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
1 warning generated.
In file included from .pio/libdeps/native_arduino/ArduinoFake/src/PrintFake.cpp:1:
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: warning: class 'EEPROMClass' was previously declared as a struct; this is valid, but may result in linker errors under the Microsoft C++ ABI [-Wmismatched-tags]
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
.pio/libdeps/native_arduino/ArduinoFake/src/arduino/EEPROM.h:4:8: note: previous use is here
struct EEPROMClass {
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: note: did you mean struct here?
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
In file included from .pio/libdeps/native_arduino/ArduinoFake/src/SPIFake.cpp:1:
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: warning: class 'EEPROMClass' was previously declared as a struct; this is valid, but may result in linker errors under the Microsoft C++ ABI [-Wmismatched-tags]
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
.pio/libdeps/native_arduino/ArduinoFake/src/arduino/EEPROM.h:4:8: note: previous use is here
struct EEPROMClass {
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: note: did you mean struct here?
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
In file included from .pio/libdeps/native_arduino/ArduinoFake/src/SerialFake.cpp:1:
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: warning: class 'EEPROMClass' was previously declared as a struct; this is valid, but may result in linker errors under the Microsoft C++ ABI [-Wmismatched-tags]
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
.pio/libdeps/native_arduino/ArduinoFake/src/arduino/EEPROM.h:4:8: note: previous use is here
struct EEPROMClass {
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: note: did you mean struct here?
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
1 warning generated.
Compiling .pio/build/native_arduino/lib983/ArduinoFake/WireFake.o
1 warning generated.
Compiling .pio/build/native_arduino/lib983/ArduinoFake/arduino/IPAddress.o
In file included from .pio/libdeps/native_arduino/ArduinoFake/src/StreamFake.cpp:1:
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: warning: class 'EEPROMClass' was previously declared as a struct; this is valid, but may result in linker errors under the Microsoft C++ ABI [-Wmismatched-tags]
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
.pio/libdeps/native_arduino/ArduinoFake/src/arduino/EEPROM.h:4:8: note: previous use is here
struct EEPROMClass {
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: note: did you mean struct here?
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
In file included from .pio/libdeps/native_arduino/ArduinoFake/src/WireFake.cpp:1:
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: warning: class 'EEPROMClass' was previously declared as a struct; this is valid, but may result in linker errors under the Microsoft C++ ABI [-Wmismatched-tags]
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
.pio/libdeps/native_arduino/ArduinoFake/src/arduino/EEPROM.h:4:8: note: previous use is here
struct EEPROMClass {
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:116:9: note: did you mean struct here?
_ArduinoFakeInstanceGetter2(EEPROM, EEPROMClass)
^
.pio/libdeps/native_arduino/ArduinoFake/src/ArduinoFake.h:59:22: note: expanded from macro '_ArduinoFakeInstanceGetter2'
name##Fake* name(class clazz* instance) \
^
1 warning generated.
my
platform.ini looks like this
[env:native]
platform = native
build_flags = -std=gnu++11
lib_deps = ArduinoFake
build_type = debug
debug_init_break = tbreak setup
the compiler makes an debug code is 7 time bigger then the release code
but PlatformIO complains about something missing in platformio.ini
Greetings,
I tried to #include "ArduinoFake.h"
in a project tested with cpputest (both from docker & native install) and encountered this error.
compiling MyFirstTest.cpp
In file included from /usr/local/include/c++/12.2.0/bits/hashtable.h:35,
from /usr/local/include/c++/12.2.0/unordered_map:46,
from mocks/ArduinoFake/src/ArduinoFake.h:8,
from tests/MyFirstTest.cpp:3:
/usr/local/include/c++/12.2.0/bits/hashtable_policy.h: In member function 'void std::__detail::_Local_iterator_base<_Key, _Value, _ExtractKey, _Hash, _RangeHash, _Unused, false>::_M_init(const __hash_code_base&)':
/usr/local/include/c++/12.2.0/bits/hashtable_policy.h:1495:15: error: expected type-specifier before 'this'
1495 | { ::new(this->_M_h()) __hash_code_base(__base); }
| ^~~~
compilation terminated due to -Wfatal-errors.
Searching the internet, I've noticed threads like this which mention the need for a default constructor. This is pushing me into areas of C++ I am very unfamiliar with.
Is this something i can do during test set-up? If so, how?
I created minimal example here
Many thanks for any feedback or suggestions.
Hi,
I'm still reading the code to understand how it works. It's really hard stuff since I have never used templates and C++11 features before (because of missing compiler support).
As I understand your framework relies on the include of ArduinoFake.h instead of Arduino.h while unittesting.
#ifdef UNIT_TEST
#include "ArduinoFake.h"
#else
#include "Arduino.h"
#endif
I have a service that get a derivated instance of the Client
injected (WiFiClientSecureRedirect in my case). I want to test the interaction with the client and fake returns of the client.
There are some points I'm not sure about:
SerialFake
To 2. - My initial thought was you put a different e.g. Serial.h into your lib and include this one instead of the real Serial.h to put a class Serial into it and implementing the fake there. (But thats not correct obvously, since you have a File "SerialFake.h/cpp" and the class is called "SerialFake").
This is my scaffolding:
ServiceA.h
#pragma once
#ifdef UNIT_TEST
#include "ArduinoFake.h"
#else
#include "Arduino.h"
#endif
#include <Client.h>
class ServiceA
{
public:
ServiceA (Client &client);
String request(const char* url);
private:
Client* _client;
};
ServiceA.cpp
#include "ServiceA.h"
ServiceA::ServiceA(Client &client)
: _client(&client)
{}
ServiceA::request(const char *url) {
//TODO: meaningful implementation.
// Currently not implemented because testing/mock is the focus
// Can I inject a client mock and verify interaction with connect?
client->connect(url, 80);
return url;
}
test_servicea.cpp
#include "ServiceA.h"
#include <ArduinoFake.h>
#include <unity.h>
using namespace fakeit;
ServiceA* service;
void test_connect(void)
{
When(Method(ArduinoFake(), connect)).Return();
service->request("google.com");
Verify(Method(ArduinoFake(), connect)).Once();
}
void setUp(void)
{
Client clientMock = getClientMock//?
service = new ServiceA(clientMock);
ArduinoFakeReset();
}
int main(int argc, char **argv)
{
UNITY_BEGIN();
RUN_TEST(test_connect);
UNITY_END();
return 0;
}
I think Client.h is not accessible during unit tests because of missing framework/platform includes.
Can you please share your thoughts about this usecase? Is it possible this way? Maybe you can elaborate on the function of the framework.
External libraries that I am using, are calling a lot of built-in arduino functions (yield/cli/sei/pinMode/etc). I don't care about these calls, but they are resulting in fakeit::UnexpectedMethodCallException
anyway. Is there a way to automatically just AlwaysReturn
them or something? Right now I am just debugging it by constantly running the tests, checkig the backtrace of where the tests fail, and add an AlwaysReturn
in my int main
for them. This is kind of tedious.
Hello,
I am using the delay function which is causing the following crash when used within my tests.
Processing NativeTestWebserver in native environment
------------------------------------------
Building...
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain+, Compatibility ~ off
Found 6 compatible libraries
Scanning dependencies...
Dependency Graph
...
Testing...
libc++abi: terminating with uncaught exception of type fakeit::UnexpectedMethodCallException
I tried if it will even crash for a very simple test, which it does for me:
#define NATIVE_TEST
#include <ArduinoFake.h>
#include <unity.h>
void test_wifi_password(void) {
int test = 0;
TEST_ASSERT_EQUAL(test, 0);
}
int main(int argc, char** argv) {
UNITY_BEGIN();
delay(2000);
RUN_TEST(test_wifi_password);
UNITY_END();
return 0;
}
When I remove the delay(2000) it runs smoothly. Is this a general error, or can somebody explain the behavior?
I am running this on a Mac M1 and with the current master branch on GitHub.
I've faced with a strange behavior when String type is used
a test contains the following
When(OverloadedMethod(ArduinoFake(Serial), println, size_t(const String &s))).AlwaysReturn();
String msg("test");
Serial.println(msg);
Verify(OverloadedMethod(ArduinoFake(Serial), println, size_t(const String &s)).Using("test")).Once();
// [FAILED]
it fails with a message ...'ArduinoFake(Serial).println(1)...
"println(1)." <-- why '1' ?
BUT the following code works OK
When(OverloadedMethod(ArduinoFake(Serial), println, size_t(const char *))).AlwaysReturn();
Serial.println("test");
Verify(OverloadedMethod(ArduinoFake(Serial), println, size_t(const char *)).Using("test")).Once();
// [PASSED]
One more example which doesn't work
const char * msg = String("test").c_str();
Serial.println(msg);
Verify(OverloadedMethod(ArduinoFake(Serial), println, size_t(const char *)).Using("test")).Once();
// [FAILED]
// it prints 'ArduinoFake(Serial).println()' like println was called without any value at all
BUT this one works OK
const char * msg = "test";
Serial.println(msg);
Verify(OverloadedMethod(ArduinoFake(Serial), println, size_t(const char *)).Using("test")).Once();
// [PASSED]
[UPDATED]
as I see, one of possible workaround for this is to modify the 'proxy' methods, and always create a copy of a String without calling free() method. E.g.
size_t Print::println(const String &s)
{
return ArduinoFakeInstance(Print, this)->println(s);
}
replace to
size_t Print::println(const String &s)
{
char * str = (char*)malloc(s.length() * sizeof(char));
strcpy(str, s.c_str());
// do not call free(str).
return ArduinoFakeInstance(Print, this)->println(str);
}
I’m creating unit tests in PlatformIO using Unity with the ArduinoFake library I’m trying to test a piece of code that uses the Wire library
I have built a simple function in a separate file that just calls Wire.begin(), and has #include <Wire.h>, which builds fine for UNO
When I try to run the unit test (env:native), it complains that the build cannot find <Wire.h>
If I comment out #include <Wire.h> in the code under test, then it builds native & the test passes ok - but now the UNO build fails
It looks like I'm using this wrong - how should I be doing this?
my platformio.ini file has the following… (as well as other lines obviously..)
[env:native]
lib_deps = fabiobatsilva/ArduinoFake@^0.3.1
My code under test (protoWire.cpp)
#include <Arduino.h>
#include <Wire.h>
#include "protoWire.h"
void startWire(void) {
Wire.begin();
};
My testing code
#include <Arduino.h>
#include <unity.h>
using namespace fakeit;
#include "protoWire.h"
void setUp (void) {} /* Is run before every test, put unit init calls here. */
void tearDown (void) {} /* Is run after every test, put unit clean-up calls here. */
void test_startWire(void){
ArduinoFakeReset();
When(OverloadedMethod(ArduinoFake(Wire), begin, void(void))).AlwaysReturn();
startWire();
Verify(OverloadedMethod(ArduinoFake(Wire), begin, void())).Once();
}
int main(int argc, char **argv)
{
UNITY_BEGIN();
printf("***** starting WIRE tests *****\n\n");
RUN_TEST(startWire);
return UNITY_END();
}
hi all,
is ArduinoFake
compatible with AUnit?
what i would like to do is mock out analogX()
and digitalX()
calls.
please advise.
thanks in advance,
rey malahay
Hi, I have been struggling with this for some time. I am trying to write tests for a library that creates its own Stream child classes and I am encountering the following error:
what(): Unknown instance
MWE:
$ tree
.
├── include
│ └── README
├── lib
│ ├── README
│ └── StreamTest
│ └── StreamTest.h
├── platformio.ini
├── src
└── test
├── README
└── test_Stream
└── test_Stream.cpp
6 directories, 6 files
platformio.ini:
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:native]
platform = native
lib_deps =
fabiobatsilva/[email protected]
lib/StreamTest/StreamTest.h
:
#pragma once
#include <Arduino.h>
class StreamTest : public Stream {
public:
int available() { return 0; }
int read() { return 0; }
int peek() { return 0; }
void flush() { };
size_t write( uint8_t b ) { return 0; }
};
test/test_Stream/test_Stream.cpp
:
#include <unity.h>
#include <ArduinoFake.h>
using namespace fakeit;
#include "StreamTest.h"
void setUp()
{
ArduinoFakeReset();
}
void test_print()
{
StreamTest s;
s.println("test");
}
int runUnityTests()
{
UNITY_BEGIN();
RUN_TEST(test_print);
return UNITY_END();
}
int main()
{
return runUnityTests();
}
$ pio test -vvv
Collected 1 tests (test_Stream)
Processing test_Stream in native environment
----------------------------------------------------------------------------------------------------------------
Building...
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 3 compatible libraries
Scanning dependencies...
Dependency Graph
|-- ArduinoFake @ 0.4.0 (License: Unknown, Path: /home/ondra/temp/ArduinoFake-stream/.pio/libdeps/native/ArduinoFake)
|-- StreamTest (License: Unknown, Path: /home/ondra/temp/ArduinoFake-stream/lib/StreamTest)
| |-- ArduinoFake @ 0.4.0 (License: Unknown, Path: /home/ondra/temp/ArduinoFake-stream/.pio/libdeps/native/ArduinoFake)
|-- Unity @ 2.5.2 (License: MIT, Path: /home/ondra/temp/ArduinoFake-stream/.pio/libdeps/native/Unity)
Building in test mode
Testing...
terminate called after throwing an instance of 'std::runtime_error'
what(): Unknown instance
Program received signal SIGABRT (Aborted)
---------------------------------------- native:test_Stream [ERRORED] Took 0.81 seconds ------------------------
================================================== SUMMARY =====================================================
Environment Test Status Duration
------------- ----------- -------- ------------
native test_Stream ERRORED 00:00:00.808
=================================== 1 test cases: 0 succeeded in 00:00:00.808 ==================================
The error seems to be coming from here:
Lines 58 to 68 in cf9c596
throw std::runtime_error("Unknown instance: " # name); \
and the resulting error message is
what(): Unknown instance: Print
Unfortunately, I don't know how to proceed with debugging.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.