Unit Testing - C

Thread Starter

Kittu20

Joined Oct 12, 2022
470
I'm currently trying to grasp the concept of unit testing, particularly in the context of c program. I've gone through some resources, but I'm still struggling to fully understand how to apply it practically.

https://www.geeksforgeeks.org/embedded-c-cpp-unit-testing-basics/

From what I gather, unit testing is important for identifying bugs and errors in code. However, I'm having trouble figuring out the process of implementing unit testing for a program.

Take a simple example

C:
#include<stdio.h>

int ADD ( int x, int y);

int main()
{
    int a = 10;
    int b = 2;
    int result;
    
    result = ADD ( a, b);
    
    printf(" Result : %d", result);
    
    return 0;
}

int ADD ( int x, int y)
{
    int r = x + y;
    return r;
}

Could someone kindly provide a straightforward explanation or perhaps a simple example to illustrate how unit testing works?
 

BobTPH

Joined Jun 5, 2013
8,967
Seeing as there is no input to the program, the concept of unit testing does not really make sense. There is only one test needed for this program, run it, and check the output. If the output is correct and it doesn’t crash it passes.

Unit testing is best understood for library functions which take an input and produce a predictable output from that input.

For example, you could write a set of unit tests for the ADD function in your example. You would pass it different input values and check the output. You would want to test both positive and negative values in all combinations. You would also want to test cases where the result overflows. But that would require a specification of what is supposed to happen in such cases. Actually, unit tests only make sense if you have a complete specification for what should happen in all cases.
 

ApacheKid

Joined Jan 12, 2015
1,610
I'm currently trying to grasp the concept of unit testing, particularly in the context of c program. I've gone through some resources, but I'm still struggling to fully understand how to apply it practically.

https://www.geeksforgeeks.org/embedded-c-cpp-unit-testing-basics/

From what I gather, unit testing is important for identifying bugs and errors in code. However, I'm having trouble figuring out the process of implementing unit testing for a program.

Take a simple example

C:
#include<stdio.h>

int ADD ( int x, int y);

int main()
{
    int a = 10;
    int b = 2;
    int result;
  
    result = ADD ( a, b);
  
    printf(" Result : %d", result);
  
    return 0;
}

int ADD ( int x, int y)
{
    int r = x + y;
    return r;
}

Could someone kindly provide a straightforward explanation or perhaps a simple example to illustrate how unit testing works?
Unit testing has come a long way the past twenty years. Today, I can check a changed source file into GitHub, and perhaps an entire complex build will automatically take place, but if any unit test case fails in one library, the build fails.

Microsoft use this hugely.

Unit testing in your example involve defining test cases for ADD, a number of distinct cases that weed out bugs. Also with unit testing, every time a bug or change gets made to ADD we'd add test cases. Consider for example how ADD is expected to behave if each arg has the value 2147483647, what is it expected to do? does it actually do as expected?
 
Last edited:

ApacheKid

Joined Jan 12, 2015
1,610
I'm currently trying to grasp the concept of unit testing, particularly in the context of c program. I've gone through some resources, but I'm still struggling to fully understand how to apply it practically.

https://www.geeksforgeeks.org/embedded-c-cpp-unit-testing-basics/

From what I gather, unit testing is important for identifying bugs and errors in code. However, I'm having trouble figuring out the process of implementing unit testing for a program.

Take a simple example

C:
#include<stdio.h>

int ADD ( int x, int y);

int main()
{
    int a = 10;
    int b = 2;
    int result;
 
    result = ADD ( a, b);
 
    printf(" Result : %d", result);
 
    return 0;
}

int ADD ( int x, int y)
{
    int r = x + y;
    return r;
}

Could someone kindly provide a straightforward explanation or perhaps a simple example to illustrate how unit testing works?
I don't know what kind of tooling you use, but this might interest you:

https://learn.microsoft.com/en-us/visualstudio/test/writing-unit-tests-for-c-cpp?view=vs-2022

If your project includes unit tests, then those get run every time you build the project.
 

Thread Starter

Kittu20

Joined Oct 12, 2022
470
Consider for example how ADD is expected to behave if each arg has the value 2147483647, what is it expected to do? does it actually do as expected?
The maximum value an int can hold is typically 2147483647 on systems with 32-bit integers.

So, if we pass 2147483647 as both arguments to the ADD function:

int a = 2147483647;
int b = 2147483647;

The sum a + b would be 4294967294, which is beyond the maximum value that can be represented by an int type. This would result in an overflow

I don't know what kind of tooling you use, but this might interest you:
What kind of tool do you use for Unite testing
 

MrChips

Joined Oct 2, 2009
30,810
For 32-bit integer, the maximum positive value is 2 147 483 647.
What happens when you add 1 to this value?

int a = 2147483647;
a = a + 1;
 

Thread Starter

Kittu20

Joined Oct 12, 2022
470
For 32-bit integer, the maximum positive value is 2 147 483 647.
What happens when you add 1 to this value?

int a = 2147483647;
a = a + 1;
When we add 1 to the maximum positive value for a 32-bit integer (2147483647), it will result in an overflow.

In implementations using two's complement representation, which is common, the result of adding 1 to the maximum positive value would wrap around and become the most negative value for a signed 32-bit integer, which is -2147483648.

So, after executing a = a + 1; the variable a would contain -2147483648.
 

MrChips

Joined Oct 2, 2009
30,810
That is your simple test of unit size.

127 + 1 for 8-bit integer
32 767 + 1 for 16-bit integer
2 147 483 647 for 32-bit integer
18 446 744 073 709 551 615 + 1 for 64-bit integer
 

Thread Starter

Kittu20

Joined Oct 12, 2022
470
That is your simple test of unit size.

127 + 1 for 8-bit integer
32 767 + 1 for 16-bit integer
2 147 483 647 for 32-bit integer
18 446 744 073 709 551 615 + 1 for 64-bit integer
I have already function ADD. I want to verify its behavior when the arguments reach or exceed the maximum positive value for a 32-bit integer (2147483647)
How to do unit testing for the ADD function in program. Do I need to create separate function in new source file?
 

ApacheKid

Joined Jan 12, 2015
1,610
What kind of tool do you use for Unite testing
I use Visual Studio professionally (C#) and also for hobby work (C). Today Visual Studio stands head and shoulders above any comparable IDE for software development.

In Visual Studio you have a "solution" and that often consists of multiple "projects". You can add a unit test project to a solution.

The unit test project will contain classes that represent groups of tests and inside that class are as many test methods as one wants to add. When a solution is built the projects get build and if they build, every test is then run automatically.

I use C# a great deal but this is also available for C and C++ and other languages too.

Here's a small example, these C# unit tests verify that an API designed to return a Type from a Type Name, works as expected:

1707494236686.png

Don't worry about what this does, its related to an API I wrote for work, but you can see how it looks. In .Net languages we can apply attributes to classes and methods, e.g. [TestMethod] these end up decorating the generated functions in such a way that tools can identify and run the tests, Java has a similar thing but it's much more powerful with .Net.

I've never written a C unit test so don't quite know how that's done.

It seems pretty decent but I'd have to try it out in order to say much more.

Once you accumulated a good solid set of tests, they become invaluable, you can make a subtle seemingly safe change to your code and rerun the tests, if you broke anything it will be detected. If you add features or fix bugs not detected by the unit tests, you can (should) add a new unit test for the fixed bug.

These suites of unit tests are often used by GitHub actions, so that when you push code it automatically builds it and runs the tests, then it becomes impossible to merge that branch until all tests are passing, leads to very high safety and robustness.

Microsoft have huge sets of unit tests for all of their .Net code, including the C++ runtime part, also their compilers for C#, F# etc are all supported by huge suites of tests, so that code is routinely hammered very hard all the time.
 
Last edited:

ApacheKid

Joined Jan 12, 2015
1,610
Thank you very much for your explanation. I only work with the C language and don't have knowledge about C#.

Have you done unit testing using C in Visual Studio?
No I haven't actually but I do play around with C a great deal writing code for STM32, I might just try adding a test project and see how that goes.

Do you work in C or C++?
 

Thread Starter

Kittu20

Joined Oct 12, 2022
470
So, I can see there are two possible ways to perform unit testing: one is using pre-defined libraries like Unity, Google Test, etc., and the other is creating our own library. In my case, it would be a good idea to create our own library for unit testing because my code is small. That's why I was asking for more help with developing the unit testing code.
 

Thread Starter

Kittu20

Joined Oct 12, 2022
470
You can’t write a program that passes various arguments to an add() function and checks the results?
Program
C:
#include <stdio.h>

// Function to add two integers
int add(int x, int y) {
    return x + y;
}

// Function to run tests
void run_tests() {
    // Test case 1: Testing addition of positive numbers
    int result = add(5, 7);
    printf("Test case 1: Expected result: 12, Actual result: %d\n", result);
    
    // Test case 2: Testing addition of negative numbers
    result = add(-3, -9);
    printf("Test case 2: Expected result: -12, Actual result: %d\n", result);
    
    // Test case 3: Testing addition of positive and negative numbers
    result = add(10, -5);
    printf("Test case 3: Expected result: 5, Actual result: %d\n", result);
}

int main() {
    // Run tests
    run_tests();
    return 0;
}
Output

Code:
Test case 1: Expected result: 12, Actual result: 12
Test case 2: Expected result: -12, Actual result: -12
Test case 3: Expected result: 5, Actual result: 5
 

ApacheKid

Joined Jan 12, 2015
1,610
I only work with the C language.

Which software IDE and compiler do you use for STM32?
I discovered a product named VisualGDB a few years ago, it's pretty inexpensive so I was skeptical about what it would be like, but tried the trial edition.

I can say its a first class product, it a sophisticated Visual Studio extension that supports all kinds of MCU projects.

When you install it it downloads and install all sorts of build tools like compilers, linkers and so on, and even though I had very little knowledge at the time, I was able to get a simple demo running and debuggable in no time.

So I do all my editing and building within Visual Studio with its powerful debugging tools.

Here's how it looks:

1707501353143.png

Here's what I see when I look at the project's properties:

1707501415083.png

and look on the left, Unit Tests, I never even looked at that before!

I'm sure professional developers might need more than VisualGDB, I simply can't say, but for my use, it is excellent and seems very professionally designed and very robust.

You can take an existing Cube or Keil project too and VisualGDB can convert and import that as well, from my experience the guys that run this firm are very experienced engineers themselves, not hobbyists.
 

ApacheKid

Joined Jan 12, 2015
1,610
I work with the PIC18F45K80 microcontroller using MPLAB IDE, XC8 compiler, C language and window
I've never used PIC. Several years ago I was fascinated by MCUs and wanted to "get into them" so I bought a book, this book:

1707503213865.png


But I never did much back then, hardly even read the book !
 
Top