A simple C testing framework for Plan9
Go to file
jlamothe 0ffc08fc41 started writing documentation 2023-11-22 01:04:59 +00:00
test warn to log instead of stderr 2023-11-21 23:26:32 +00:00
9unit.c warn to log instead of stderr 2023-11-21 23:26:32 +00:00
9unit.h implemented log_test_context() 2023-11-20 05:03:33 +00:00
LICENSE relicenced under LGPLv3 instead of GPLv3 2023-11-09 23:24:48 +00:00
mkfile fix nuke option in mkfile 2023-11-10 09:15:02 -05:00
README.md started writing documentation 2023-11-22 01:04:59 +00:00

9unit

Copyright (C) 2023 Jonathan Lamothe jonathan@jlamothe.net

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Summary

A simple unit testing framework for C programs in Plan9

This provides the library file 9unit.a and the header 9unit.h. The header file is relatively well commented and can provide a fairly comprehensive breakdown of the API. This document will however provide a basic overview below.

This library is used to test the library itself, consequently, the test directory contains a relitively decent real-world example of how it can be used.

TestState

The entire testing framework is centred around the TestState data structure. As its name would imply, it contains the current state of the tests in progress, however it should almost never be necessary to interact with it directly. With the exception of run_tests() (described below), all functions provided by the library will take take a pointer to a TestState value as their first parameter.

run_tests()

This will typically be the first function you call in your tests. It sets up the testing framework, creates an initial TestState value, runs the tests provided to it and displays a log and summary at the end. If any of the provided tests failed, it will cause the test program to exit with status of "test(s) failed". Its prototype follows:

void run_test(void (*tests)(TestState *))

The tests parameter is a pointer to a function which then is responsible for running the actual tests. A pointer to the newly created TestState value will be passed to this function.

Simple Tests

The simplest form of test can be represented as a function resembling the follwoing:

TestResult my_test(TestState *s)
{
	// ...
}

This function should return a TestResult value representing (perhaps unsurprisingly) the result of the test. The options are as follows:

  • test_success: the test was completed successfully
  • test_failure: the test failed
  • test_pending: the test is pending and should be ignored for now

Tests of this type can be run by passing them to the run_test() function, which has the following prototype:

void run_test(
	TestState *s,
	TestResult (*test)(TestState *)
)

This function will run the provided test and update the provided TestState to reflect the result of the test.

Passing Values to Tests

Since C supports neither lambdas nor closures, this leaves one with little choice but to come up with a unique name for each test function. This, while possible, would definitely be rather inconvenient. To combat this, it is helpful to be able to pass data into a generic test so that it can be reused multiple times.

The ptr Value

The TestState struct has a value called ptr which is a void pointer that can be set prior to calling run_test(). This value can then be read by the test function, giving you the ability to essentially pass in any type of data you may need. While not ideal, it's a solution.