This post is continuation of previous post on how to mock local variable in ceedling, please check out previous post before continuing with this article. Another issue is having to add all the microchip files.
When CMock gets a hold of the header file it looks at all the functions defined there and generates several mock functions for each.
In one program, we are dealing with 4 pins of microcontroller. The pin numbers and its functions are defined in file ‘atmel_start_pins.h’ which is included in our project. But inside this file there are definitions for all the pins and ‘hal.gpio.h’ file is included. Inside ‘hal.gpio.h’ file, another files are included. The original atmel_start_pins.h file is like below, We need only 4 pins from this file:
The function under test is :
Instead of wasting memory we can create our own file ‘atmel_start_pins.h’ for unit testing. The file will contain The function declarations we want to mock and only the required data.
In above function INPUT_ENTER_KEY,INPUT_BACK_KEY etc are having values as follwing :
These PB_1,PB_2,PB_3,PB_4 are defined in file ‘atmel_start_pins.h’. So we can create our own ‘atmel_start_pins.h’ file which is having only requied data .The new file is like:
Now we can mock this required function and interfaces. We can just assign any numbers for PB_1,PB_2,PB_3,PB_4 . Pass these pin numbers in test cases.
Unit testing is code that calls some other code to check if it performing as expected.Ceedling is a build system specifically designed for running unit tests in c. Unity and CMock are open source tools for testing c.Ceedling has feature of automatic generation of mock.
Unity is a unit test framework.
CMock creates the fake versions of other modules.Using these fake versions we can verify whether our module is working correctly or not.
Ceedling include unit test framework(Unity) and Mocking framework(CMock).
It requires Ruby to run and it uses GCC to build each test.
Ceedling comes with a command line tool that can be used to generate the project.
‘Ceedling’ is open source tool used in unit testing, in our project which involves embedded system development we are using ‘ceedling’ framework. There are other unit test frameworks like google gTest but they are more suited for application software written high level languages like c++. Being embedded system software written in ‘C’ language we are using ‘Ceedling’ for our unit testing.
I was testing function for one module which is using the modbus APIs defined in modbus.c file. For ceedling unit testing I mocked low level APIs like modbus_read_registers() and modbus_write_register().
In our code we defined function int _readModbusRegister( ) and function int _writeModbusRegister() inside which mobus_read/write_registers APIs were used :
The function under test is:
In above function I need to test all the possible conditions for different value of ‘drvStatus’ variable. But ‘drvStatus’ is local variable. How can I mock the local variable in Ceedling?? We cannot directly mock local variable using Ceedling. So in this case if we made our mock function modbus_read_registers() return 1 then user defined function _readModbusRegister() will always return ‘regValue’ as zero. Because right now we are testing the code without using hardware. So always ‘drvStatus’ variable will become zero and code will not get execute further. And we cannot change the value of drvStatus with this conditions.
In ‘Ceedling’ generally we have to mock API but for getting different value for local variable ‘drvStatus’ in this case we have to mock the function which is returning value to local variable, i.e. in this case we will mock ‘_readModbusRegister()’. The actual function which we need to mock is always returning the register value. So add these two user defined function declarations to a file and add this file prefixing _mock .Ceedling will automatically create the mock versions of given functions.
When we mock the function whose definition is present we have to comment that definition otherwise ceedling will throw error for ‘ found multiple definitions’. I commented the definitions for these two mocked functions. Now I can use these _readModbusRegister_ExpectAndReturn() function with any return value and can generate test case for every possible condition. Like in first test case we are returning 8 to ‘drivestatus’ .
Here in second test case we can return 16 to ‘drivestatus variable’.