#C #Unity #testframework #Makefile #automation #conventionalcommits
Let's work through Sorting algorithms & Big O. It is a project in Holberton School Australia's C curriculum.
Learning Goals
Each Holberton project has a set of learning goals associated with it. Having goals is important. I try to set a few personal goals in addition to the provided goals.
Provided goals
For the Sorting algorithms & Big O project, Holberton provides a family of related goals. By the end of the project, I am expected to be able to explain to anyone without the help of Google:
At least four different sorting algorithms
What is the Big O notation, and how to evaluate the time complexity of an algorithm
How to select the best sorting algorithm for a given input
What is a stable sorting algorithm
Personal goals
In addition to these knowledge goals, I have also set myself a few process goals:
Set up test automation
Do Test-Driven Development
Use conventional commits
Setting up the repository
I define a project path for where I want my project files stored. I use that path to create a directory and then I initialise it is a git repository.
$ path_project='/root/holbertonschool-sorting_algorithms'
$ mkdir $path_project
$ cd $path_project
$ git init
chore(docs): add README
I add the project readme.
$ echo "Repository for 'Sorting algorithms & Big O' project" > README.md
$ git add README.md
$ git commit -m 'chore(docs): add README'
git commit -m
in this blog post for brevity, I actually prefer the flagless git commit
. When used without any flags, git commit
opens an editor session. In the editor session, Git shows what files have been staged. In my Vim editor, it also shows how many characters have been typed. Consequently, I make fewer mistakes and it is easier to create well-formatted commit bodies and satisfy line-length commit conventions (see this and this).Setting up a testing framework
chore(tests): add Unity framework
unity.c
) and two header files (unity.h
and unity_internals.h
). A C source file can act as a Unity test runner if it includes unity.h
and defines a main
function that executes Unity's test suite management macros.I install the Unity dependencies and locate the files.
$ git submodule add https://github.com/ThrowTheSwitch/Unity.git Unity
..
$ find -name unity.c -o -name unity.h -o -name unity_internals.h
./Unity/src/unity.c
./Unity/src/unity.h
./Unity/src/unity_internals.h
I define the path to the dependencies and explicitly add them to version control.
recurse-submodules
flag but that b) my version of Unity is frozen and I won't pull in any updates.$ path_unity=$path_project/Unity/src
$ git add "$path_project"/unity{.c, .h, _internals.h}
$ git commit -m 'chore(tests): add Unity framework'
chore(tests): add Unity framework
unity{.c, .h, _internals.h}
. I learned about this feature of Bash during Holberton's Unix curriculum. I am a big fan of learning simple tools that I can then apply to multiple contexts.feat(tests): add test runner template
Let's use a modified version of the file from my Unity series as our test runner template.
test_that_unity_works.c
, can be found in the Replit supplied at the end of the article.To keep the project organised, I create a directory for my tests. This is where I add the test_runner_template.c
file.
$ path_tests=$path_project/tests
$ mkdir $path_tests
I confirm that the test runner template compiles.
$ gcc -I$path_unity $path_unity/unity.c $path_tests/test_runner_template.c -o unity_test_runner.out
I confirm that the test runner executable runs as expected.
$ ./unity_test_runner.out
-----------------------
0 Tests 0 Failures 0 Ignored
OK
I add the test runner template to version control.
$ git add $path_tests/test_runner_template.c
$ git commit -m 'feat(tests): add test runner template'
Setting up test automation
Instead of building and executing the tests manually as above, let's use the GNU make utility to define rules that automatically build and run the test runner.
build(tests): automate test runner
To use GNU Make as an automated test runner, I define a Makefile with targets that contain build, run and clean recipes.
I confirm that the run target works.
$ make run
/root/holbertonschool-sorting_algorithms/tests/unity_test_runner.out
-----------------------
0 Tests 0 Failures 0 Ignored
OK
I confirm that the clean target works.
$ make clean
rm -f /root/holbertonschool-sorting_algorithms/tests/unity_test_runner.out
$ make run
...
make: *** [Makefile:17: run] Error 127
I confirm that the build target works.
$ make build
gcc -I/root/holbertonschool-sorting_algorithms/Unity/src /root/holbertonschool-sorting_algorithms/Unity/src/unity.c /root/holbertonschool-sorting_algorithms/tests/test_runner_template.c -o /root/holbertonschool-sorting_algorithms/tests/unity_test_runner.out
$ make run
/root/holbertonschool-sorting_algorithms/tests/unity_test_runner.out
-----------------------
0 Tests 0 Failures 0 Ignored
OK
Finally, I run GNU Make to confirm that the default target works as intended.
-s
flag to silence GNU Make - now it won't print the commands it executes.$ make -s
-----------------------
0 Tests 0 Failures 0 Ignored
OK
Everything works. I add the automation tool to version control.
$ git add Makefile
$ git commit -m 'build(tests): automate test runner'
Setting up supplied dependencies
A Holberton project often provides algorithms or data structures to use. Sorting Algorithms & Big O is one such project. It provides the following dependencies:
a print array algorithm
a print linked list algorithm
a linked list data structure
feat(Holberton): define linked list
I create an include guarded header file, sort.h
, and add the linked list definition supplied by Holberton to it. Then I add the file to version control.
$ git add sort.h
$ git commit -m 'feat(Holbertone): define Linked List'
After the next two commits, sort.h
will contain the following:
feat(Holberton): print arrays
I add the supplied Holberton file, print_array.c
, to version control. It contains the print_array
function. I also add the function's prototype to sort.h
.
$ git add print_array.c sort.h
$ git commit -m 'feat(Holberton): print arrays'
feat(Holberton): print linked lists
I do the same for the Holberton file, print_list.c
, which contains the print_list
function.
$ git add print_list.c sort.h
$ git commit -m 'feat(Holberton): print lists'
Adding to documentation
To finish, I add this blog post to the project README.
docs: add setup blog post to README
$ url='https://warrenmarkham.hashnode.dev/setting-up-a-holberton-school-project'
$ echo -e "\nRead about [the project setup]($url)." >> README.md
$ git add README.md
$ git commit -m 'docs: add setup blog post to README'