forked from espressif/esp-idf
feat(unity): Adds unit test ordering by file path and line number
Closes https://github.com/espressif/esp-idf/issues/15529
This commit is contained in:
@ -58,4 +58,18 @@ menu "Unity unit testing library"
|
||||
jumping back to the test menu. The jumping is usually occurs in assert
|
||||
functions such as TEST_ASSERT, TEST_FAIL etc.
|
||||
|
||||
config UNITY_TEST_ORDER_BY_FILE_PATH_AND_LINE
|
||||
bool "Order unit tests by file path and line number"
|
||||
default n
|
||||
help
|
||||
If enabled, the Unity test framework will automatically insert test cases
|
||||
in a sorted order at registration time (during constructor execution),
|
||||
based on their source file path and line number.
|
||||
|
||||
This ensures consistent execution order across platforms (e.g., Linux vs. on-chip),
|
||||
preserving the logical order in which tests are written in the source files.
|
||||
|
||||
Note, the file path used for sorting follows the full absolute path format.
|
||||
/IDF/examples/system/unit_test/components/testable/test/test_mean.c
|
||||
|
||||
endmenu # "Unity unit testing library"
|
||||
|
8
components/unity/test_apps/.build-test-rules.yml
Normal file
8
components/unity/test_apps/.build-test-rules.yml
Normal file
@ -0,0 +1,8 @@
|
||||
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
||||
|
||||
components/unity/test_apps:
|
||||
enable:
|
||||
- if: IDF_TARGET in["esp32", "linux"]
|
||||
reason: need to test on a chip and linux targets
|
||||
depends_components:
|
||||
- unity
|
7
components/unity/test_apps/CMakeLists.txt
Normal file
7
components/unity/test_apps/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
#This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(COMPONENTS main)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(unity_test_app)
|
2
components/unity/test_apps/README.md
Normal file
2
components/unity/test_apps/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
| Supported Targets | ESP32 | Linux |
|
||||
| ----------------- | ----- | ----- |
|
3
components/unity/test_apps/main/CMakeLists.txt
Normal file
3
components/unity/test_apps/main/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
idf_component_register(SRC_DIRS "."
|
||||
PRIV_REQUIRES unity
|
||||
WHOLE_ARCHIVE)
|
26
components/unity/test_apps/main/test.c
Normal file
26
components/unity/test_apps/main/test.c
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "unity.h"
|
||||
|
||||
TEST_CASE("Test 1", "[test]")
|
||||
{
|
||||
TEST_ASSERT(1 == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("Test 2", "[test]")
|
||||
{
|
||||
TEST_ASSERT(1 == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("Test 3", "[test]")
|
||||
{
|
||||
TEST_ASSERT(1 == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("Test 4", "[test]")
|
||||
{
|
||||
TEST_ASSERT(1 == 1);
|
||||
}
|
11
components/unity/test_apps/main/test_app_main.c
Normal file
11
components/unity/test_apps/main/test_app_main.c
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include "unity.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
unity_run_menu();
|
||||
}
|
26
components/unity/test_apps/pytest_unit_test.py
Normal file
26
components/unity/test_apps/pytest_unit_test.py
Normal file
@ -0,0 +1,26 @@
|
||||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
def verify_test_order(dut: Dut) -> None:
|
||||
dut.expect_exact('Press ENTER to see the list of tests.')
|
||||
dut.write('\n')
|
||||
dut.expect('Test 1')
|
||||
dut.expect('Test 2')
|
||||
dut.expect('Test 3')
|
||||
dut.expect('Test 4')
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('target', ['esp32'], indirect=['target'])
|
||||
def test_unit_test_order(dut: Dut) -> None:
|
||||
verify_test_order(dut)
|
||||
|
||||
|
||||
@pytest.mark.host_test
|
||||
@idf_parametrize('target', ['linux'], indirect=['target'])
|
||||
def test_unit_test_order_linux(dut: Dut) -> None:
|
||||
verify_test_order(dut)
|
2
components/unity/test_apps/sdkconfig.defaults
Normal file
2
components/unity/test_apps/sdkconfig.defaults
Normal file
@ -0,0 +1,2 @@
|
||||
CONFIG_ESP_TASK_WDT_EN=n
|
||||
CONFIG_UNITY_TEST_ORDER_BY_FILE_PATH_AND_LINE=y
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -11,6 +11,7 @@
|
||||
#include <stdio.h>
|
||||
#include "unity.h"
|
||||
#include "esp_system.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/* similar to UNITY_PRINT_EOL */
|
||||
#define UNITY_PRINT_TAB() UNITY_OUTPUT_CHAR('\t')
|
||||
@ -24,11 +25,37 @@ void unity_testcase_register(test_desc_t *desc)
|
||||
if (!s_unity_tests_first) {
|
||||
s_unity_tests_first = desc;
|
||||
s_unity_tests_last = desc;
|
||||
} else {
|
||||
test_desc_t *temp = s_unity_tests_first;
|
||||
s_unity_tests_first = desc;
|
||||
s_unity_tests_first->next = temp;
|
||||
return;
|
||||
}
|
||||
#if CONFIG_UNITY_TEST_ORDER_BY_FILE_PATH_AND_LINE
|
||||
test_desc_t *prev = NULL;
|
||||
test_desc_t *current = s_unity_tests_first;
|
||||
|
||||
while (current) {
|
||||
int file_cmp = strcmp(desc->file, current->file);
|
||||
if (file_cmp < 0 || (file_cmp == 0 && desc->line < current->line)) {
|
||||
// Insert before current
|
||||
if (prev) {
|
||||
prev->next = desc;
|
||||
} else {
|
||||
// Inserting at the head
|
||||
s_unity_tests_first = desc;
|
||||
}
|
||||
desc->next = current;
|
||||
return;
|
||||
}
|
||||
prev = current;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
// Insert at the end
|
||||
prev->next = desc;
|
||||
s_unity_tests_last = desc;
|
||||
#else
|
||||
// Insert at head (original behavior)
|
||||
desc->next = s_unity_tests_first;
|
||||
s_unity_tests_first = desc;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* print the multiple function case name and its sub-menu
|
||||
|
Reference in New Issue
Block a user