Skip to content

TrMen/test_framework

Repository files navigation

A simple experimental C++20 unit test framework. The key feature is that tests may be run at runtime or compiletime.

Tests are just simple functions that use the testing::assert_* functions for assertions.

#include "asserts.hpp"
#include "test.hpp"

using namespace testing;

constexpr void add() { 
  assert_eq(1 + 1, 2); 
}

constexpr void fail1() {
  // Test will fail and report location and assertion arguments
  assert_eq(1, 2);
}

constexpr void fail2() {
  // Test will fail
  assert_nothrow(FnWithSource{ []() { throw std::invalid_argument("bad"); }}); 
}

struct Fixture {
  constexpr void add() const { assert_eq(1 + num, 2); }

  int num = 1;
};

int main() {
  // Runtime tests, with runtime reporting
  TEST_ALL(add, fail1, fail2);
  // Each test with a fixture is run with a new instance of that class
  TEST_ALL_FIXTURE(Fixture, &Fixture::add); 

  TestSuite suite; 
  // Tests run with the same test suite are reported together.
  TEST_ALL_SUITE_FIXTURE(suite, Fixture, &Fixture::add);
  TEST_ALL_SUITE(suite, add);

  // These tests are forced to run at compiletime.
  // If they fail, compilation will fail.
  TEST_ALL_CONSTEXPR(add, fail1, fail2);
  TEST_ALL_FIXTURE_CONSTEXPR(Fixture, &Fixture::add);
}

The experimental idea is that a lot of functions can be constexpr annotated. Especially the kind of functions you would usually use unit tests for, since they should be self-contained.

Any constexpr-annotated function can be run at compiletime with TEST_ALL_CONSTEXPR, and if any contained assertion fails, compilation will fail deliberately.

The workflow here is that you'd use some IDE with a language server that does macro expansion and constexpr variable evaluation. Then your IDE will immediately underline failed tests as you are writing them!

But you can also run tests as usual at runtime, if you want a report of run and failed tests, or have tests that you can't or don't want to run at compiletime.

The program above (after removing the failing compiletime test), will generate the following output at runtime:

Running add...
PASSED: add

Running fail1...
../main.cpp:10:0 in fail1(): ASSERT: '1' and '2' are not equal
FAILED: fail1

Running fail2...
../main.cpp:14:0 in fail2(): ASSERT: Unexpected std::exception thrown with arguments ''. what(): 'bad'
FAILED: fail2


FAILED: fail1
FAILED: fail2
SUMMARY: Ran 3 tests in 0 seconds. 2 failed.

Running Fixture::add...
PASSED: Fixture::add


SUMMARY: Ran 1 tests in 0 seconds. 0 failed.

Running Fixture::add...
PASSED: Fixture::add


SUMMARY: Ran 1 tests in 0 seconds. 0 failed.

Running add...
PASSED: add


SUMMARY: Ran 2 tests in 0 seconds. 0 failed.

For some more usage examples, look in main.cpp.

About

A simple C++20 test-framework

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published