copper: Crash-proof unit tests for C and C++

Copper is an obsolete test framework I wrote at university. It is of historical and personal interest only. Use GoogleTest instead.

Code: https://john-millikin.com/code/copper (GitHub mirror)

History

At my university, the student mainframes ran a variety of crufty and ancient UNIX OSes with exceptionally crufty and ancient compilers[1]. Consider a class full of students learning C++ when the only[2] compilers available either (1) didn't have STL libraries like std::string, or (2) generated binaries that crashed immediately if an exception was thrown.

Writing unit tests in CppUnit under these conditions was difficult, and it was common for students to spend more time debugging their test suites than making progress on assignments.

I decided to try writing my own test framework that could adapt to the weird environment, and as a bonus would be nicer to use than CppUnit.

  • It used GNU Autoconf to detect system features and compiler capabilities. I wasn't joking about std::string.
  • I had learned from TheDailyWTF that C++ could run code before main() by clever use of static variables, and used this to auto-register tests.
  • Each test ran in a child process spawned with fork(), and communicated test results back to the parent using a simple length-prefixed packet format called netstrings. At the time I had no idea who djb was – netstrings.txt was just some useful thing that another student had found.
  • Tests could have "protectors", which tried to report fatal errors in a non-fatal way. These were used to print stack traces for compilers that supported exceptions.

The original name was simply "UnitTests" – I renamed it after realizing that CppUnit abbreviated to "CU", the chemical name for copper.

Installing

Use the standard UNIX install stanza ./configure && make && make install to install Copper. Optionally, you may run the included self-tests with make check. Copper does not have any dependencies aside from a reasonably capable C++ compiler. If present, Copper will take advantage of advanced features such as RTTI and std::stringstream.

Copper is installed as a static library and set of header files; use $(pkg-config --cflags --libs copper) when compiling tests. For example, after installing Copper, you may build and run the included sample tests with:

$ g++ -o samples tests/sample_tests.cpp tests/main.cpp $(pkg-config --cflags --libs copper)

$ ./samples
FAILURE in tests/sample_tests.cpp:111:
sample_suite.assertion_failure:
	equal("the answer", "42")
	"the answer" != "42"

ERROR in tests/sample_tests.cpp:
sample_suite.NULL_pointer_dereference:
	Segmentation fault

ERROR in tests/sample_tests.cpp:
sample_suite.division_by_zero:
	Floating point exception

10 tests passed
1 test failed
2 errors

  1. The best compiler available to us was a horrible hacked-up fork of GCC 2.95 installed on the DEC Tru64 machine.

  2. We could use modern GCC 4.1 at home, but your code had to work with whatever compiler the professor used.

Change Feed