C — Basic Testing

Rostyslav Druzhchenko
5 min readApr 11, 2020

In god we trust — the rest we test

Photo by Chris Ried on Unsplash

It’s a very short and applicable piece about basics C code testing. It does not cover many topics and may look too simple for someone. But it gives an ability to write simple tests to them who are at the beginning of their software development way.

Why

When you write your code, you have to be sure if it works correctly. You probably plenty of times found yourself changing your code, writing ,and deleting debugging lines, rerun your application a lot of times to be sure if your tiny change did not break the work that you spent several hours. In this piece, we will consider a simple approach to how you make your life easier and be more confident in your work.

How

Let’s consider a very simple case. You need to implement a couple of functions from C standard library and ensure that they act in the same manner as original functions do. Let’s say you have strcmp and pow — pretty standard input.

Root folders

You may find the git repository here and use it while reading. The content of the repository you may see in the picture below. Let’s discuss its content.

You may see two folders in the root directory — clib and test . clib contains the functions we need to implement, tests folder test environments for them. Pay your attention — tests folder is out of clib folder. It’s a dramatically important, your production code, the code that you are going to ship somewhere, should not contain any other code and/or resources inside. You should be ready to ship the code any moment, and you should not spend time cleaning it up because in a hurry, you may break something, and it may cost you too much.

Test environment

We also won’t discuss functions from clib here — they are pretty simple and are not a target of our investigation. Let’s concentrate on tests folder. tests folder contains two folder — one per function under testing. Moreover, every folder contains a fully prepared and independent environment to test each function with different cases. That’s another important point — tests must be independent and mustn’t rely on each other. You should be able to remove any folder any time, but others should still work correctly.

Every test folder contains three files — main.c file, a file with tests, and a run script. Let’s consider a main.c file.

The first line includes the function under test. Well, it’s not the neatest way to write C code, but for tests, it’s often possible to break some rules to make life easier. But you should remember that you shouldn’t do these tricks in the production code.

Lines 3–6 include all common includes to make them available in tests. Just handy and shorten your code.

Then we have the main function that runs all the tests we wrote for our function.

Line 8 — again, includes a .c file, this time it’s our file with tests. Let’s look at it closer.

Test file

The heart of this file — test_run_all() function. It runs all the other test functions in this file. The main idea — you should not test everything in one function. We create small functions that run simple checks and easy to read and understand. In our case, we have three test functions that test three usual cases for strcmp — strings are equal, the first string is bigger, the other string is bigger.

Let’s look at test_equal_strings function. As we may see, it’s pretty simple — it declares two equal strings and passes them to the function under test. Then it checks the result and prints a descriptive error message if something went wrong. If the test passed, it prints nothing. It’s a typical command-line tool behavior.
Well, that’s pretty it. The other function act in the same manner, just check the function with different parameters and check other results. You may discover the repository by yourself trying to rut the tests, changing functions behavior, adding new tests, and so on.

Run

Now open your terminal and navigate to any test folder with cd command. Type there ./run.sh and wait a couple of seconds. The script will run the compiler and then runs the compiled binary with the tests. You should see nothing in the terminal but just script finished. It’s ok. That means all tests passed, and there are no mistakes there.

Try to change some conditions in the test and run again. If the condition failed, you would see the output in the terminal. For instance:

Conclusion

Okey, we just discussed a very simple approach to test your code. It’s maybe isn’t the most elegant way, but it gives you an understanding of the process and full control. It’s only beginning. You may build a much powerful testing system in your project. And most likely it’ll make your product better.

Summary

  • The code should be tested.
  • Tests must be out of your code.
  • Tests must be independent.
  • Tests must be simple.

Resources

--

--

Rostyslav Druzhchenko

An experienced software engineer with over 17 years in mobile development. Interested in Swift, iOS, Java and music programming. Skydive as a hobby.