# 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/