Simple Unit Testing for Types in C11

Sometimes I find myself doing coding tests to keep my problem-solving skills sharp. One of the platforms I use is CodeWars, a platform owned by Andela. My current stack is JavaScript (including NodeJS), PHP, and C/C++. I noticed the tests for the C and C++ exercises were written using a library called Criterion, which brings us to the topic of Unit testing in C and C++.  I did some intense C and C++ work a while back on embedded Linux systems and one of the tools I lacked was a simple library to do testing in. Looking at the criterion I realized I had just found an easy-to-use tool for testing my C/C++ work.

I decided to put this simplicity to test and in order to do so I decided to use a toy CLI app I wrote in C some years ago. This app has a function for random number generation.

In file app.c:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>
#include "app.h"
........
int generateAccountNumber(){
    srand(time(NULL));
    return rand();
}
........

Testing this is as simple as the code below:

In file tests.c:

#include <stdio.h>
#include <criterion/criterion.h>
#include "app.h"
#include <string.h>

#define DETERMINE_TYPE(x) _Generic((x), \
    int: "int", \
    float: "float", \
    double: "double", \
    char: "char", \
    long: "long", \
    default: "unknown")

Test(bankapp, random_num) {
    cr_assert(!strcmp("int", DETERMINE_TYPE(generateAccountNumber())));
}

All you need to do now is compile the test using:

gcc tests.c app.c -o tests -lcriterion

One thing to note is that the main function of the application you are testing must be in a separate file to prevent clashing with the main file provided by the Criterion testing framework. And that is it! You have a test.


I added the C11 _Generic macro feature to highlight a new C language feature that allows you to “return” a select value or function based on the type provided. This can be used for implementing programming features such as function overloading, Generics, Type checking like I used here, and many more. We will be looking more into this C11 feature in future articles. Thanks for reading.

References

  1. Criterion Testing Framework Documentation.
  2. Blog on how to use Generic Macros in C.

strlen vs mb_strlen in PHP

As a PHP developer, I am sure you use strlen often to check for the length of strings. strlen does not return the length of a string but the number of bytes in a string. In PHP, one character is one byte therefore for characters that fall within the 0 – 255 range in ASCII/UTF-8 all seem well; that is string length matches the number of bytes. There is nothing wrong with this approach of checking the length of a string using strlen if you are checking the length of string that you typed in Latin characters for your program because ASCII and some basic UTF-8 characters fall within the range of a single byte.


The problem with using strlen occurs when there is a character outside of the 1-byte range, then strlen returns values greater than the string length, which can lead to bugs and general confusion. The solution to this is to use mb_strlen, which returns the exact length of the character by checking the encoding set. Check out the snippet displaying this:

 // strlen okay: Result is 4
echo strlen('Rose');

// strlen not okay: Result is 7
echo strlen('Michał');

// mb_strlen okay: Result is 6
echo mb_strlen('Michał');

A rule of thumb I use when checking length of character input from user especially from a web browser I use mb_strlen but when I need to use the actual size of the string I use strlen for example when transferring string through or saving them in a database or if it is a string I typed out myself.

Next time you want to check the length of a string in PHP or any language it is best to know the appropriate function to use for the type of string characters.

Follow me on Twitter / Mastodon / LinkedIn or check out my code on Github or my other articles.

Quick one on Python random numbers sampling

I have been working on a project to generate random data using Python. Since I am not using this project for any security application I opted for the Python pseudo-random number generator random .

In order to randomly select items from a list three option presented themselves to me random.choice, random.choices and random.sample .

random.choice

Selects one item randomly from list of length n.

>>> import random
>>> random.choice([4,2,6,7,1])
6
>>> random.choice([4,2,6,7,1])
4
>>>

random.choices

Selects k items randomly from list of length n.

>>> import random
>>> random.choices([4,2,6,7,1],k=2)
[2, 6]
>>> random.choices([4,2,6,7,1],k=20)
[6, 4, 1, 6, 1, 1, 6, 7, 7, 2, 4, 4, 2, 2, 6, 1, 4, 6, 7, 4]

random.sample

Select k items randomly from list of length n, without replacement. Randomly select items are removed from the list, therefore if k > n there is an error.

>>> import random
>>> random.sample([4,2,6,7,1],k=3)
[6, 4, 1]
>>> random.sample([4,2,6,7,1],k=20)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.8/random.py", line 363, in sample
    raise ValueError("Sample larger than population or is negative")
ValueError: Sample larger than population or is negative

Hopefully , I have given a concise introduction random item selection from a list in Python. Refer to the documentation for more functions and information.