c++esp32esp-idfunity-test-framework

ESP-IDF: Unit tests with unity and C++


I have a project with a few components that I want to test. I've read the documentation and started to create unit tests using unity for one of my component (the component is switches.hpp/cpp). I've created a test folder in the component's folder and added a CMakeLists.txt and the test file as .cpp (since my project is in C++.

switch/test/CMakeLists.txt

idf_component_register(SRC "test_switches.cpp"
                    INCLUDE_DIRS "."
                    REQUIRES unity switches)[/code]

switch/test/test_switches.cpp

#include "unity.h"
#include "driver/gpio.h"
#include "switches.hpp"

Switches* switches = nullptr;

void setUp(void) {
    switches = Switches::get_instance();

    switches->set_switch_m1_state(SWITCH_M1_A);
    switches->set_switch_m2_state(SWITCH_M2_D);
    switches->set_switch_m3_state(SWITCH_M3_D);
    switches->set_switch_m4_state(SWITCH_M4_GO);
    switches->set_switch_m5_state(SWITCH_M5_F);
}

void tearDown(void) {
    // TODO
}

void test_switch_m1(void) {
    switches->set_switch_m1_state(SWITCH_M1_B);
    TEST_ASSERT_EQUAL(SWITCH_M1_B, switches->get_switch_m1_state());
    //TEST_ASSERT_EQUAL(1, gpio_get_level(SWITCH_M1_PIN1));
    //TEST_ASSERT_EQUAL(0, gpio_get_level(SWITCH_M1_PIN2));
}

extern "C" void app_main(void) {
    UNITY_BEGIN();
    RUN_TEST(test_switch_m1);
    UNITY_END();
}

using VSCode extension of ESP-IDF, with the command pallette and I used the command "ESP-IDF: Unit Test: Build and flash unit test app for testing". This created in the root of the project a unity-app folder with a project to start the unit tests. I modified the main file :

unity-app/main/test_app_main.c

/*
 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "unity.h"

static void print_banner(const char* text)
{
    printf("\n#### %s #####\n\n", text);
}

void app_main(void)
{
    print_banner("Unity test runner");
    printf("Total test count: %d\n", unity_get_test_count());

    UNITY_BEGIN();
    unity_run_all_tests();
    UNITY_END();
    
    unity_run_menu();
}

And also modified the CMakeLists.txt of the unit test project :

# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/version.cmake)

# Add newly added components to one of these lines:
# 1. Add here if the component is compatible with IDF >= v4.3
set(EXTRA_COMPONENT_DIRS "../components")

set(TEST_COMPONENTS switches)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(test_app_main)

When the unit test app built and flashed onto the ESP32-S3 Mini I got, it printed and ran correctly but didn't find the test I wrote for the switches. I have tried to modify the EXTRA_COMPONENT_DIRS and TEST_COMPONENTS name multiple times without success. I can't seem to understand why it doesn't work. Maybe it's because I used C++ instead of C, but I have no choice.


Solution

  • I found a solution, I added this line in the project's CMakeLists.txt and it worked. This doesn't appear in the unit test example.

    set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components" "main")
    

    This is the final CMakeLists.txt for the project (root/CMakeLists.txt) :

    cmake_minimum_required(VERSION 3.5)
    
    set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components" "main")
    
    include($ENV{IDF_PATH}/tools/cmake/project.cmake)
    project(la-mine-des-CFK)