From fc9fb2c77505cf1dcf5d1f50dd61a980471b3494 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Sun, 25 Jul 2021 17:18:09 +0100 Subject: [PATCH] Allow output of logging when running unit tests (#13556) * Initial pass at enabling logging for unit tests * Add to docs * Bind debug for more test types * Force everything * Tidy up slightly --- build_test.mk | 13 ++++++++++-- docs/faq_debug.md | 2 +- docs/unit_testing.md | 10 +++++++++- tests/test_common/main.cpp | 32 ++++++++++++++++++++++++++++++ tests/test_common/test_fixture.cpp | 8 ++++++-- 5 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 tests/test_common/main.cpp diff --git a/build_test.mk b/build_test.mk index 77c4265f93716fee9e833b778be0c73eb6b89167..519c142c4230ecfd8e975750c5da1ad59b442026 100644 --- a/build_test.mk +++ b/build_test.mk @@ -24,7 +24,6 @@ GTEST_INTERNAL_INC :=\ $(GTEST_OUTPUT)_SRC :=\ googletest/src/gtest-all.cc\ - googletest/src/gtest_main.cc\ googlemock/src/gmock-all.cc $(GTEST_OUTPUT)_DEFS := @@ -35,7 +34,8 @@ CREATE_MAP := no VPATH +=\ $(LIB_PATH)/googletest\ - $(LIB_PATH)/googlemock + $(LIB_PATH)/googlemock\ + $(LIB_PATH)/printf all: elf @@ -43,6 +43,10 @@ VPATH += $(COMMON_VPATH) PLATFORM:=TEST PLATFORM_KEY:=test +ifeq ($(strip $(DEBUG)), 1) +CONSOLE_ENABLE = yes +endif + ifneq ($(filter $(FULL_TESTS),$(TEST)),) include tests/$(TEST)/rules.mk endif @@ -55,6 +59,11 @@ ifneq ($(filter $(FULL_TESTS),$(TEST)),) include build_full_test.mk endif +$(TEST)_SRC += \ + tests/test_common/main.c \ + $(LIB_PATH)/printf/printf.c \ + $(COMMON_DIR)/printf.c + $(TEST_OBJ)/$(TEST)_SRC := $($(TEST)_SRC) $(TEST_OBJ)/$(TEST)_INC := $($(TEST)_INC) $(VPATH) $(GTEST_INC) $(TEST_OBJ)/$(TEST)_DEFS := $($(TEST)_DEFS) diff --git a/docs/faq_debug.md b/docs/faq_debug.md index 13a649bfa2f3973b957829817ddf734e78368f59..1afa38a6243b1d8caf67a558169fdb3afe106579 100644 --- a/docs/faq_debug.md +++ b/docs/faq_debug.md @@ -28,7 +28,7 @@ For compatible platforms, [QMK Toolbox](https://github.com/qmk/qmk_toolbox) can Prefer a terminal based solution? [hid_listen](https://www.pjrc.com/teensy/hid_listen.html), provided by PJRC, can also be used to display debug messages. Prebuilt binaries for Windows,Linux,and MacOS are available. -## Sending Your Own Debug Messages +## Sending Your Own Debug Messages :id=debug-api Sometimes it's useful to print debug messages from within your [custom code](custom_quantum_functions.md). Doing so is pretty simple. Start by including `print.h` at the top of your file: diff --git a/docs/unit_testing.md b/docs/unit_testing.md index 82073a2016552c064f6c7b3953c999605e597b6b..a0eef51cb63822aecf270f6322a531329899b712 100644 --- a/docs/unit_testing.md +++ b/docs/unit_testing.md @@ -36,12 +36,20 @@ Note how there's several different tests, each mocking out a separate part. Also ## Running the Tests -To run all the tests in the codebase, type `make test`. You can also run test matching a substring by typing `make test:matchingsubstring` Note that the tests are always compiled with the native compiler of your platform, so they are also run like any other program on your computer. +To run all the tests in the codebase, type `make test:all`. You can also run test matching a substring by typing `make test:matchingsubstring` Note that the tests are always compiled with the native compiler of your platform, so they are also run like any other program on your computer. ## Debugging the Tests If there are problems with the tests, you can find the executable in the `./build/test` folder. You should be able to run those with GDB or a similar debugger. +To forward any [debug messages](unit_testing.md#debug-api) to `stderr`, the tests can run with `DEBUG=1`. For example + +```console +make test:all DEBUG=1 +``` + +Alternatively, add `CONSOLE_ENABLE=yes` to the tests `rules.mk`. + ## Full Integration Tests It's not yet possible to do a full integration test, where you would compile the whole firmware and define a keymap that you are going to test. However there are plans for doing that, because writing tests that way would probably be easier, at least for people that are not used to unit testing. diff --git a/tests/test_common/main.cpp b/tests/test_common/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3e4b4c0f9540b712d543775c760265215fd04048 --- /dev/null +++ b/tests/test_common/main.cpp @@ -0,0 +1,32 @@ +#include "gtest/gtest.h" + +extern "C" { +#include "stdio.h" +#include "debug.h" + +int8_t sendchar(uint8_t c) { + fprintf(stderr, "%c", c); + return 0; +} + +__attribute__((weak)) debug_config_t debug_config = {0}; + +void init_logging(void) { + print_set_sendchar(sendchar); + + // Customise these values to desired behaviour + // debug_enable = true; + // debug_matrix = true; + // debug_keyboard = true; + // debug_mouse = true; + debug_config.raw = 0xFF; +} +} + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + + init_logging(); + + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/tests/test_common/test_fixture.cpp b/tests/test_common/test_fixture.cpp index 20ed838eb6a9f158de7defcce9c56ca4e1144bd8..e041df7128df9e59e48622ea1a4266932619c0bf 100644 --- a/tests/test_common/test_fixture.cpp +++ b/tests/test_common/test_fixture.cpp @@ -7,10 +7,10 @@ #include "action_tapping.h" extern "C" { +#include "debug.h" +#include "eeconfig.h" #include "action_layer.h" -} -extern "C" { void set_time(uint32_t t); void advance_time(uint32_t ms); } @@ -21,6 +21,10 @@ using testing::Between; using testing::Return; void TestFixture::SetUpTestCase() { + // The following is enough to bootstrap the values set in main + eeconfig_init_quantum(); + eeconfig_update_debug(debug_config.raw); + TestDriver driver; EXPECT_CALL(driver, send_keyboard_mock(_)); keyboard_init();