Большая часть кода моей библиотеки C может быть скомпилирована с помощью -DTEST
, чтобы представить main()
(и часто некоторые вспомогательные функции тоже) в исходном файле с реализацией. Так что если у меня есть набор функций, объявленных в source.h
и определенных в source.c
, то source.c
может выглядеть так:
#include "source.h"
#include …other headers…
…code defining functions declared in source.h
#ifdef TEST
#include <stdio.h>
int main(void)
{
…test code…
}
#endif /* TEST */
Это работает, когда набор тестов достаточно мал, чтобы поместиться в исходный файл. Если тесты становятся больше, чем код, тогда я создаю один или несколько отдельных исходных файлов, содержащих тестовый код. Каждый из этих файлов может иметь свой собственный main()
, или они могут быть спроектированы для связывания вместе - в зависимости от того, что кажется более удобным.
Что подходит, зависит от размера и сложности тестов. Некоторые функции заканчиваются фиксированными - жесткими - тестами; некоторые тратят время на чтение данных со стандартного ввода; другие обрабатывают списки аргументов, если они предоставляются, и используют минимальный тест, если аргументов нет. Тестовый код может использовать инфраструктуру модульного тестирования или может быть более или менее специальным, опять же, в зависимости от сложности (и древности) кода.