TTS v3.0.0
The Tiny Test System
Loading...
Searching...
No Matches
Tests definition macros

Macros for defining tests scenarios. More...

Scenarios Definitions

#define TTS_CASE(ID)
 Introduces a new test scenario and registers it into the current test driver.
#define TTS_CASE_TPL(ID, ...)
 Introduces a template test case and registers it into the current test driver.
#define TTS_CASE_WITH(ID, TYPES, ...)
 Introduces a template test case providing dynamically generated data to the test code.
#define TTS_XFAIL(ID)
 Tags a TTS_CASE (or TTS_CASE_TPL / TTS_CASE_WITH) ID as expected to fail.
#define TTS_MAYFAIL(ID)
 Tags a TTS_CASE (or TTS_CASE_TPL / TTS_CASE_WITH) ID as allowed to fail.
#define TTS_XINVALID(ID)
 Tags a TTS_CASE (or TTS_CASE_TPL / TTS_CASE_WITH) ID as expected to be empty.

Scoped scenarios

#define TTS_WHEN(STORY)
 Start a block of scoped environment.
#define TTS_AND_THEN(MESSAGE)
 Add a scoped tests to current scoped environment.

Macro Definition Documentation

◆ TTS_AND_THEN

#define TTS_AND_THEN ( MESSAGE)

#include <tts/test/when.hpp>

Add a scoped tests to current scoped environment.

Compared to regular local scope, whenever a scoped test is run, the data defined in the enclosing TTS_WHEN are re-initialized, thus serving as a setup/tear-down system.

See also
TTS_WHEN

Example

#define TTS_MAIN // No need for main()
#include <tts/tts.hpp>
#include <iostream>
TTS_CASE("Check test with sub-test")
{
TTS_WHEN("We start some sub-test")
{
int i = 99;
TTS_AND_THEN("We increment a variable")
{
std::cout << ">> Sub-test 1: i = " << i << "\n";
TTS_EQUAL(i, 99);
i++;
TTS_EQUAL(i, 100);
}
TTS_AND_THEN("We decrement a variable")
{
std::cout << ">> Sub-test 2: i = " << i << "\n";
TTS_EQUAL(i, 99);
i--;
TTS_EQUAL(i, 98);
}
}
};

◆ TTS_CASE

#define TTS_CASE ( ID)

#include <tts/engine/case.hpp>

Introduces a new test scenario and registers it into the current test driver.

The code block following TTS_CASE contains user-defined code for a given test case. Test cases performing no actual tests will be reported as invalid.

Parameters
IDA literal string describing the scenario intents.

Example

#define TTS_MAIN // No need for main()
#include <tts/tts.hpp>
TTS_CASE("Check basic arithmetic")
{
TTS_EQUAL(2 + 2, 4);
};

◆ TTS_CASE_TPL

#define TTS_CASE_TPL ( ID,
... )

#include <tts/engine/case.hpp>

Introduces a template test case and registers it into the current test driver.

The code block following TTS_CASE contains user-defined code for a given test case. Those tests are parametrized by a template type of your choice passed as lambda function parameters of the template type tts::type and instantiated for each type in the types list.

Such types list can be provided as:

  • a variadic list of types separated by commas
  • an instance of the tts::types template class
  • an instance of a Type Generator, ie a type exposing a public types_list type definition

Test cases performing no actual tests will be reported as invalid.

Parameters
IDA literal string describing the scenario intents.
...Lists of types to generate the test case from.

Example

#define TTS_MAIN // No need for main()
#include <tts/tts.hpp>
#include <array>
TTS_CASE_TPL("Check types using variadic list", char, short, int, double, void*)
<typename T>(tts::type<T>)
{
TTS_GREATER_EQUAL(sizeof(T), 1UL);
};
TTS_CASE_TPL("Check types using a types list", tts::types<float, double>)
<typename T>(tts::type<T>)
{
TTS_EQUAL(1 / T {2}, static_cast<T>(0.5));
};
// A Types Generator is any type exposing a types_list internal type
// In this example we use such a type to generate the list of types:
//
// tts::types<std::array<std::byte,1>,...,std::array<std::byte,N>>>;
template<int N, typename Indexes = std::make_index_sequence<N>> struct sizes;
template<int N, std::size_t... I> struct sizes<N, std::index_sequence<I...>>
{
using types_list = tts::types<std::array<std::byte, I + 1>...>;
};
TTS_CASE_TPL("Check types using a types list generator", sizes<5>)
<typename T>(tts::type<T>)
{
T x;
TTS_EQUAL(sizeof(x), x.size());
};

◆ TTS_CASE_WITH

#define TTS_CASE_WITH ( ID,
TYPES,
... )

#include <tts/engine/case.hpp>

Introduces a template test case providing dynamically generated data to the test code.

The following code block will contain tests parametrized by a template type of your choice passed as lambda function parameters and generated for each type in the types list.

Such types list can be provided as:

  • a parenthesised list of types separated by comma.
  • an instance of the tts::types template class.
  • an instance of a Type Generator, ie a type exposing a public types_list type definition

Test cases performing no actual tests will be reported as invalid.

Parameters
IDA literal string describing the scenario intents.
TYPESLists of types to generate the test case from.
...Lists of generator function

Example

#define TTS_MAIN // No need for main()
#include <tts/tts.hpp>
TTS_CASE_WITH("Check behavior for scalar types",
tts::value {37},
tts::between {0, 100},
tts::randoms {0., 10.})
<typename V, typename B, typename R>(V v, B b, R const& r)
{
TTS_EQUAL(v, V {37});
TTS_GREATER_EQUAL(b, B {0});
TTS_LESS_EQUAL(b, B {100});
TTS_GREATER_EQUAL(r, R {0});
TTS_LESS_EQUAL(r, R {10});
};

◆ TTS_MAYFAIL

#define TTS_MAYFAIL ( ID)

#include <tts/engine/case.hpp>

Tags a TTS_CASE (or TTS_CASE_TPL / TTS_CASE_WITH) ID as allowed to fail.

Unlike TTS_XFAIL, nothing specific is expected: the case may pass or fail, either is accepted and neither is reported. Useful for flagging a work-in-progress or a known issue that shouldn't block the suite without pretending to require a specific outcome.

An empty case is still reported, exactly as for an untagged TTS_CASE - TTS_MAYFAIL only relaxes the pass/fail expectation, not the "did anything actually run" one.

Parameters
IDA literal string describing the scenario intents.
See also
TTS_XFAIL
TTS_XINVALID

Example

#define TTS_MAIN // No need for main()
#include <tts/tts.hpp>
TTS_CASE(TTS_MAYFAIL("Flaky under load on some CI runners"))
{
TTS_EXPECT(true); // may occasionally fail elsewhere - either outcome is accepted here
};

◆ TTS_WHEN

#define TTS_WHEN ( STORY)

#include <tts/test/when.hpp>

Start a block of scoped environment.

Code in a scoped environment can contain:

  • Normal expressions.
  • scoped tests introduced by TTS_AND_THEN.
See also
TTS_AND_THEN

Example

#define TTS_MAIN // No need for main()
#include <tts/tts.hpp>
#include <iostream>
TTS_CASE("Check test with sub-test")
{
TTS_WHEN("We start some sub-test")
{
int i = 99;
TTS_AND_THEN("We increment a variable")
{
std::cout << ">> Sub-test 1: i = " << i << "\n";
TTS_EQUAL(i, 99);
i++;
TTS_EQUAL(i, 100);
}
TTS_AND_THEN("We decrement a variable")
{
std::cout << ">> Sub-test 2: i = " << i << "\n";
TTS_EQUAL(i, 99);
i--;
TTS_EQUAL(i, 98);
}
}
};

◆ TTS_XFAIL

#define TTS_XFAIL ( ID)

#include <tts/engine/case.hpp>

Tags a TTS_CASE (or TTS_CASE_TPL / TTS_CASE_WITH) ID as expected to fail.

Wraps the case's ID instead of changing the enclosing macro's signature, so it composes with TTS_CASE, TTS_CASE_TPL and TTS_CASE_WITH unchanged: TTS_CASE(TTS_XFAIL("...")).

The case is expected to produce at least one failing assertion. If it runs with no failures instead, that mismatch is reported and fails the suite - matching the "X = expected" naming convention already used by other test frameworks (pytest's xfail, DejaGnu, Perl's Test::More), so it reads the same way to anyone coming from one of those.

An empty case (no assertion ran at all) does not satisfy TTS_XFAIL either - use TTS_XINVALID for that.

Parameters
IDA literal string describing the scenario intents.
See also
TTS_MAYFAIL
TTS_XINVALID

Example

#define TTS_MAIN // No need for main()
#include <tts/tts.hpp>
TTS_CASE(TTS_XFAIL("Known, not-yet-fixed rounding bug"))
{
TTS_EQUAL(1 + 1, 3); // stands in for the real, currently broken behavior being tracked
};

◆ TTS_XINVALID

#define TTS_XINVALID ( ID)

#include <tts/engine/case.hpp>

Tags a TTS_CASE (or TTS_CASE_TPL / TTS_CASE_WITH) ID as expected to be empty.

The case is expected to register no assertion at all. If it runs any assertion instead (passing or failing), that mismatch is reported and fails the suite.

Parameters
IDA literal string describing the scenario intents.
See also
TTS_XFAIL
TTS_MAYFAIL

Example

#define TTS_MAIN // No need for main()
#include <tts/tts.hpp>
TTS_CASE(TTS_XINVALID("Placeholder for a scenario not written yet"))
{
// Intentionally empty - stays a visible reminder in the suite instead of silently vanishing
};