Skip to content

mentix02/shipyard

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

shipyard

GitHub GitHub Workflow Status Language

Shipyard is a simple and extensbile header only testing library intended to be used by extremely small C++ projects. It is meant to be a bare bones testing framework requiring almost no setup and thus comes at a cost of not being as featureful as other testing suites such as GoogleTest or CxxTest.

Motivation

As a beginner C++ programmer, I find using most C++ third party libraries extremely difficult to use, especially when it comes to unit testing frameworks. Other languages such as Python, Go, even Java, have better unit testing support than C++ and I consider C++ to be quite a high level programming language and thus sought out to create a simple testing framework for a big integer library I was writing. It evolved into a project of its own and that project now lives on as shipyard.

It's a single header only framework that is written in concise and readable C++17 that anyone can hack on easily. It's customisable in the sense that one can write his/her own Assert function to use for different data types. A number of Asserts already exist for std::vector, std::map, std::unordered_map, std::set, and many more besides assertions for primitive types like ints and floats.

Usage

There's a great tutorial over at Medium walking through most of shipyard's features. Read it here.

Download the header file for shipyard and place it inside a tests directory of your project.

Include the functions or classes that you wish to test and start writing test functions. For example, say you have the following set of functions in an imaginary prime number library.

  1. bool is_prime(uint64_t) - to check whether a number is prime.
  2. uint64_t n_prime(uint64_t) - to generate the nth prime number.
  3. std::vector<uint64_t> primes_till(uint64_t) - to generate a vector of primes up until n.

You can structure your testing directory in a more modular fashion such that each file named test_<function_or_class_name> has functions for testing said function or class but since this prime library is small enough, we'll be okay with just one file.

#include "shipyard.hpp"
#include "primelib.cpp"

void test_is_prime()
{
	sy::AssertTrue(is_prime(5), "is_prime(5) == true");
	sy::AssertFalse(is_prime(12), "is_prime(12) == false");
}

void test_n_prime()
{
	sy::Assert(n_prime(10), 29);
	sy::Assert(n_prime(100), 541);
}

void test_primes_till()
{
	const auto primes = primes_till(10);
	sy::Assert(primes, {2, 3, 5, 7, 11, 13, 17, 19, 23, 29});
}

Then you can run ship.py and let it discover all the tests in the directory and generate the runner for you -

$ ship.py -v
$ cat test.cpp
/*
	Generated by ship.py on Fri May 22 15:36:43 2020.
*/
#include "shipyard.hpp"
#include "test_primelib.cpp"

int main(int argc, char* argv[])
{
	const auto tests = sy::create_tests({
		TESTCASE(test_is_prime),
		TESTCASE(test_n_prime),
		TESTCASE(test_primes_till),
	});
	sy::run(tests, true);
	return 0;
}
$ ls
primelib.cpp		shipyard.hpp		test.cpp		test_primelib.cpp
$ clang++ test.cpp -o test -Wall
$ ./test
Running test_is_prime... done.
Running test_n_prime... done.
Running test_primes_till... done.

Extensions

Custom Asserts

shipyard ships, no pun intended, with a few inbuilt Assert functions for checking equality for various containers a custom Assert function can be easily written for any custom data type. All it needs to do it throw a AssertionError defined in the header on equality failure. For example, say you have some custom class called Person and you want to assert that two objects belong to the same "family" attribute of a class. Easily done -

void AssertSameFamily(const Person& p1, const Person& p2)
{
	if (p1.family != p2.family)
		throw AssertionError(p1.name " and " + p2.name " are not related");
}

The AssertionError exception also has an optional std::string field for extra messages that can be used for some more info on the assertion.

Selective Cases

If you wish to run only a small subset of files then you can use the script provided with shipyard ship.py. You can provide a pattern for ship using -

$ ship.py -p test_n_prime 

ship.py also detects the dependencies from functions and thus only includes the dependent files that have the function in them.

Reference

Documentation coming soon.

About

An extensible and easy to use C++ testing library.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published