# Cmock ## use ceedling ``` $ ceedling new simmple_prog create simmple_prog create simmple_prog/src create simmple_prog/test create simmple_prog/test/support create simmple_prog/project.yml 🌱 New project 'simmple_prog' created at ./simmple_prog/ ``` ## create first UT for C 1. create the UT file ceedling module:create[{test_ut_file_name}] ``` $ ceedling module:create[mock_name] 🚧 Loaded project configuration from working directory. > Using: /home/roy/src_code/ut_sample/simmple_prog/project.yml > Working directory: /home/roy/src_code/ut_sample/simmple_prog Ceedling set up completed in 192 milliseconds File src/mock_name.c already exists! File src/mock_name.h created File test/test_mock_name.c created Generate Complete Ceedling operations completed in 17 milliseconds ``` 2. write the test and mock code ```c #ifdef TEST #include "unity.h" #include "utility.h" #include "utility2.h" #include "mock_get_tempature.h" void setUp(void) { } void tearDown(void) { } void test_utility_NeedToImplement(void) { uint8_t testTempature = 0; get_tempature_ExpectAndReturn(0x3E, 42); set_tempature_ExpectAndReturn(0x3E, 42); testTempature = mainget1(); TEST_ASSERT_EQUAL(testTempature, 42 ); testTempature = mainget2(); TEST_ASSERT_EQUAL(testTempature, 32 ); } void test_utility2_NeedToImplement(void) { uint8_t testTempature = 0; get_tempature_ExpectAndReturn(0x3E, 42); set_tempature_ExpectAndReturn(0x3E, 42); testTempature = utility3(); TEST_ASSERT_EQUAL(testTempature, 42 ); testTempature = utility4(); TEST_ASSERT_EQUAL(testTempature, 32 ); } #endif // TEST ``` 3. start test ceedling test:all :::spoiler result ``` 🚧 Loaded project configuration from working directory. > Using: /home/roy/src_code/ut_sample/simmple_prog/project.yml > Working directory: /home/roy/src_code/ut_sample/simmple_prog ......skip .... 👟 Building Objects ------------------- Compiling test_mock_name.c... Compiling test_mock_name::utility.c... Compiling test_mock_name::utility2.c... Compiling test_mock_name::mock_get_tempature.c... Compiling test_mock_name::test_mock_name_runner.c... Compiling test_mock_name::unity.c... Compiling test_mock_name::cmock.c... 👟 Building Test Executables ---------------------------- Linking test_mock_name.out... 👟 Executing ------------ Running test_mock_name.out... ------------------- FAILED TEST SUMMARY ------------------- [test/test_mock_name.c] Test: test_utility_NeedToImplement At line (25): "Expected 42 Was 32" Test: test_utility2_NeedToImplement At line (36): "Expected 42 Was 32" ----------------------- ❌ OVERALL TEST SUMMARY ----------------------- TESTED: 2 PASSED: 0 FAILED: 2 IGNORED: 0 --------------------- BUILD FAILURE SUMMARY --------------------- Unit test failures. Ceedling operations completed in 1.44 seconds ``` ::: So you will get ``` ------------------- FAILED TEST SUMMARY ------------------- [test/test_mock_name.c] Test: test_utility_NeedToImplement At line (25): "Expected 42 Was 32" Test: test_utility2_NeedToImplement At line (36): "Expected 42 Was 32" ----------------------- ❌ OVERALL TEST SUMMARY ----------------------- TESTED: 2 PASSED: 0 FAILED: 2 IGNORED: 0 --------------------- BUILD FAILURE SUMMARY --------------------- Unit test failures. ``` ## Code coverage 1. apt install gcovr 2. turn gcov :::spoiler project.yml ```yaml :plugins: :load_paths: [] :enabled: #- beep # beeps when finished, so you don't waste time waiting for ceedling - module_generator # handy for quickly creating source, header, and test templates - gcov <---- Turn on this ``` ::: 3. execute: ceedling gcov:all ```log --------------------------- GCOV: CODE COVERAGE SUMMARY --------------------------- test_mock_name -------------- utility.c | Lines executed:100.00% of 12 utility.c | No branches utility.c | Calls executed:100.00% of 2 utility.c | Lines executed:100.00% of 12 utility2.c | Lines executed:100.00% of 10 utility2.c | No branches utility2.c | Calls executed:100.00% of 2 utility2.c | Lines executed:100.00% of 10 Running Gcovr Coverage Reports ------------------------------ Generating HTML coverage report in 'build/artifacts/gcov/gcovr'... Done in 0.607 seconds. ``` :::info HTML coverage report in 'build/artifacts/gcov/gcovr' ::: ## Ref :::spoiler utility.c ```c #include "get_tempature.h" #include "stdint.h" uint8_t mainget1(void) { uint8_t nowTempature = 0; uint8_t I2C_address = 0x3E; nowTempature = get_tempature(I2C_address); return nowTempature; } uint8_t mainget2(void) { uint8_t nowTempature = 0; uint8_t I2C_address = 0x3E; nowTempature = set_tempature(I2C_address); return nowTempature; } ``` ::: :::spoiler utility2.c ```c #include "get_tempature.h" #include "stdint.h" uint8_t utility3(void) { uint8_t nowTempature = 0; uint8_t I2C_address = 0x3E; nowTempature = get_tempature(I2C_address); return nowTempature; } uint8_t utility4(void) { uint8_t nowTempature = 0; uint8_t I2C_address = 0x3E; nowTempature = set_tempature(I2C_address); return nowTempature; } ``` ::: :::spoiler get_tempature.c ```c #include "get_tempature.h" uint8_t get_tempature(uint8_t I2C_address) { return I2C_GetData(I2C_address) * 5 / 10; // 5/10 就是除與2 } ``` ::: :::spoiler get_tempature.h ```c #include <stdint.h> uint8_t get_tempature(uint8_t I2C_address); uint8_t set_tempature(uint8_t I2C_address); ``` ::: https://embetronicx.com/tutorials/unit_testing/unit-testing-in-c-testing-with-unity/