Skip to content
Stefano Famà edited this page May 31, 2017 · 14 revisions

AutoCheck is a QuickCheck (and later, SmallCheck) clone for C++11.

Introduction

QuickCheck is a Haskell library for quickly and easily building unit tests. I will give a brief summary of it here, but if you need more detail, please consult the HaskellWiki.

Unit tests are expressed as properties: functions that perform some computation and return the Boolean value of a post-condition. The arguments of the function form a test case. A canonical example of a property tests that reversing a list twice preserves the original order of the list. In C++, it may be expressed like this:

template <typename Container>
bool reverse_prop(const Container& xs) {
  Container ys(xs);
  std::reverse(ys.begin(), ys.end());
  std::reverse(ys.begin(), ys.end());
  return ys == xs;
}

The purpose of QuickCheck is to test such properties with a set of randomly-generated test cases. After the property passes a certain number of tests, it succeeds, and the programmer can, with some level of confidence, presume it works in the general case. If it fails a test, the counterexample is printed to allow the programmer to investigate and debug. Test cases have a notion of growth: they start "small" and grow larger with the hope that the smallest counterexample will be found should the property fail.

Acknowledgments

Besides the original authors of QuickCheck, I want to thank two related projects for inspiration:

I think I was able to make numerous improvements with C++11 features (lambdas, variadic templates, rvalue references), a more functional style, and an extensible architecture, but these two projects deserve credit.

Notation

The rest of this documentation follows some conventions:

  • Concepts are capitalized, proper nouns, e.g., Arbitrary.
  • Type and function names are lowercase and formatted as code, e.g., check or arbitrary.
  • Template type parameters model the concepts after which they are named, if any.
  • Several higher-order functions exist in this library. Any callable value (function pointer, function object, closure, etc.) can be passed. The parameter declarations for them will look like this:
return_type parameter_name(arg_type1, arg_type2)

Tutorial

Get a quick introduction with the tutorial.

Primary Components