micro-test-plus 4.1.0
µTest++ Testing Framework
Loading...
Searching...
No Matches
test.h
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2021-2026 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can be
9 * obtained from https://opensource.org/licenses/mit.
10 *
11 * Major parts of the code are inspired from v1.1.8 of the Boost UT project,
12 * released under the terms of the Boost Version 1.0 Software License,
13 * which can be obtained from https://www.boost.org/LICENSE_1_0.txt.
14 */
15
16// ----------------------------------------------------------------------------
17
47
48#ifndef MICRO_TEST_PLUS_TEST_H_
49#define MICRO_TEST_PLUS_TEST_H_
50
51// ----------------------------------------------------------------------------
52
53#ifdef __cplusplus
54
55// ----------------------------------------------------------------------------
56
57#include <functional>
58#include <memory>
59
60#include "runner-totals.h"
61#include "type-traits.h"
62#include "timings.h"
63#include "reflection.h"
64
65// ----------------------------------------------------------------------------
66
67#if defined(__GNUC__)
68#pragma GCC diagnostic push
69#pragma GCC diagnostic ignored "-Wpadded"
70#if defined(__clang__)
71#pragma clang diagnostic ignored "-Wc++98-compat"
72#else // GCC only
73#pragma GCC diagnostic ignored "-Wsuggest-final-types"
74#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
75#pragma GCC diagnostic ignored "-Wredundant-tags"
76#endif
77#endif
78
79// =============================================================================
80
82{
83 // --------------------------------------------------------------------------
84
85 class runner;
86 class static_runner;
87 class reporter;
88 class runner_totals;
89 class subtest;
90 class suite;
91 class static_suite;
92
93 namespace detail
94 {
95 // ========================================================================
96
108 runner&
109 to_runner (static_runner& static_runner_ref) noexcept;
110
121 void
122 register_static_suite (static_runner& static_runner_ref,
123 static_suite& static_suite_ref);
124
146 {
147 public:
153 test_node (const char* name);
154
158 test_node (const test_node&) = delete;
159
163 test_node (test_node&&) = delete;
164
168 test_node&
170 = delete;
171
175 test_node&
177 = delete;
178
182 virtual ~test_node ();
183
184 // ----------------------------------------------------------------------
185
193 [[nodiscard]] const char*
194 name (void) const noexcept;
195
196 public:
204 [[nodiscard]] runner_totals&
205 totals () noexcept;
206
214 [[nodiscard]] const runner_totals&
215 totals () const noexcept;
216
217 protected:
224 const char* name_;
225
230 };
231
232 // ========================================================================
233
254 {
255 public:
264 runnable_base (const char* name, runner& runner, size_t own_index);
265
269 runnable_base (const runnable_base&) = delete;
270
275
281 = delete;
282
288 = delete;
289
293 virtual ~runnable_base () override;
294
295 // ----------------------------------------------------------------------
296
304 [[nodiscard]] size_t
305 own_index () const noexcept;
306
318 void
319 own_index (size_t index) noexcept;
320
328 [[nodiscard]] size_t
329 current_subtest_index () const noexcept;
330
338 size_t
339 increment_subtest_index () noexcept;
340
348 [[nodiscard]] size_t
349 children_subtests_count (void) const noexcept;
350
358 [[nodiscard]] class reporter&
359 reporter (void) const noexcept;
360
368 [[noreturn]] void
369 abort (const reflection::source_location& sl
370 = reflection::source_location::current ());
371
379 [[nodiscard]] class runner&
380 runner (void) const noexcept;
381
382 protected:
393 void
394 after_subtest_create_ (std::unique_ptr<subtest> child_test,
395 suite& suite);
396
397 protected:
402
407
418
427 std::vector<std::unique_ptr<subtest>> children_subtests_;
428 };
429
430 // ========================================================================
431
442 template <typename Self_T>
444 {
445 public:
459 template <typename Callable_T, typename... Args_T>
460 runnable (const char* name, class runner& runner, size_t own_index,
461 Callable_T&& callable, Args_T&&... arguments);
462
466 runnable (const runnable&) = delete;
467
471 runnable (runnable&&) = delete;
472
476 runnable&
478 = delete;
479
483 runnable&
485 = delete;
486
490 virtual ~runnable () override;
491
492 // ----------------------------------------------------------------------
493
503 virtual void
504 run (void)
505 = 0;
506
507 protected:
512 std::function<void (Self_T&)> callable_;
513 };
514
515 // ------------------------------------------------------------------------
516 } // namespace detail
517
518 // ==========================================================================
519
541 class subtest : public detail::runnable<subtest>
542 {
543 public:
562 template <typename Callable_T, typename... Args_T>
563 subtest (const char* name, class runner& runner, suite& parent_suite,
564 size_t own_index, size_t nesting_depth, Callable_T&& callable,
565 Args_T&&... arguments);
566
570 subtest (const subtest&) = delete;
571
575 subtest (subtest&&) = delete;
576
580 subtest&
581 operator= (const subtest&)
582 = delete;
583
587 subtest&
588 operator= (subtest&&)
589 = delete;
590
594 virtual ~subtest () override;
595
596 // ------------------------------------------------------------------------
597
610 template <typename Callable_T, typename... Args_T>
611 void
612 test (const char* name, Callable_T&& callable, Args_T&&... arguments);
613
614 // ------------------------------------------------------------------------
615
630 template <class Expr_T>
632 auto
633 expect (const Expr_T& expr, const reflection::source_location& sl
635
650 template <class Expr_T>
652 auto
653 assume (const Expr_T& expr, const reflection::source_location& sl
655
656 // ------------------------------------------------------------------------
657
666 virtual void
667 run (void) override;
668
676 [[nodiscard]] size_t
677 nesting_depth () const noexcept;
678
679 protected:
684
689 };
690
691 // ==========================================================================
692
713 class suite : public detail::runnable<suite>
714 {
715 public:
730 template <typename Callable_T, typename... Args_T>
731 suite (const char* name, class runner& runner, Callable_T&& callable,
732 Args_T&&... arguments);
733
737 suite (const suite&) = delete;
738
742 suite (suite&&) = delete;
743
747 suite&
748 operator= (const suite&)
749 = delete;
750
754 suite&
755 operator= (suite&&)
756 = delete;
757
761 virtual ~suite () override;
762
763 // ------------------------------------------------------------------------
764
777 template <typename Callable_T, typename... Args_T>
778 void
779 test (const char* name, Callable_T&& callable, Args_T&&... arguments);
780
781 // ------------------------------------------------------------------------
782
790 [[nodiscard]] detail::timestamps&
791 timings () noexcept;
792
800 [[nodiscard]] const detail::timestamps&
801 timings () const noexcept;
802
811 virtual void
812 run (void) override;
813
814 protected:
818 detail::timestamps timings_;
819 };
820
821 // ==========================================================================
822
838 class top_suite : public suite
839 {
840 public:
841 // Expose the accessor for the suite name from the base test_node class,
842 // since the top_suite may need to change its name after construction, and
843 // the base class provides the necessary interface for that purpose.
845
852 top_suite (const char* name, class runner& runner);
853
857 top_suite (const top_suite&) = delete;
858
862 top_suite (top_suite&&) = delete;
863
867 top_suite&
868 operator= (const top_suite&)
869 = delete;
870
874 top_suite&
875 operator= (top_suite&&)
876 = delete;
877
881 virtual ~top_suite () override;
882
888 void
889 name (const char* new_name) noexcept;
890 };
891
892 // ==========================================================================
893
923 class static_suite : public suite
924 {
925 public:
939 template <typename Callable_T, typename... Args_T>
940 static_suite (const char* name, static_runner& runner,
941 Callable_T&& callable, Args_T&&... arguments);
942
946 static_suite (const static_suite&) = delete;
947
952
957 operator= (const static_suite&)
958 = delete;
959
964 operator= (static_suite&&)
965 = delete;
966
970 virtual ~static_suite () override;
971
972 // ------------------------------------------------------------------------
973
982 virtual void
983 run (void) override;
984
985 protected:
990 std::function<void (static_suite&)> static_callable_;
991 };
992
993 // --------------------------------------------------------------------------
994} // namespace micro_os_plus::micro_test_plus
995
996#if defined(__GNUC__)
997#pragma GCC diagnostic pop
998#endif
999
1000// ----------------------------------------------------------------------------
1001
1002#endif // __cplusplus
1003
1004// ============================================================================
1005// Templates & constexpr implementations.
1006
1007#include "inlines/test-inlines.h"
1008
1009// ----------------------------------------------------------------------------
1010
1011#endif // MICRO_TEST_PLUS_TEST_H_
1012
1013// ----------------------------------------------------------------------------
runnable_base(const runnable_base &)=delete
Deleted copy constructor to prevent copying.
class runner & runner(void) const noexcept
Gets the test runner associated with this test runnable.
size_t current_subtest_index() const noexcept
Returns the index of the most recently created child subtest.
runnable_base(const char *name, runner &runner, size_t own_index)
Constructs a runnable_base with a name, runner, and index.
Definition test.cpp:136
runnable_base(runnable_base &&)=delete
Deleted move constructor to prevent moving.
void after_subtest_create_(std::unique_ptr< subtest > child_test, suite &suite)
Registers a newly constructed child subtest and executes it immediately.
Definition test.cpp:215
size_t own_index_
The test index, counting from 1.
Definition test.h:406
size_t own_index() const noexcept
Returns the positional index of this object within its parent.
size_t current_subtest_index_
The subtest index, counting from 1.
Definition test.h:417
class reporter & reporter(void) const noexcept
Gets the test reporter associated with this test runnable.
Definition test.cpp:187
size_t children_subtests_count(void) const noexcept
Returns the number of direct child subtests owned by this node.
class runner & runner_
Reference to the test runner that owns this object.
Definition test.h:401
void abort(const reflection::source_location &sl=reflection::source_location::current())
Aborts test execution via the owning runner.
Definition test.cpp:199
size_t increment_subtest_index() noexcept
Increments and returns the child subtest sequential index.
std::vector< std::unique_ptr< subtest > > children_subtests_
Owning collection of direct child subtests.
Definition test.h:427
CRTP base class factoring out callable storage, rule-of-five, and run() logic shared by subtest and s...
Definition test.h:444
std::function< void(Self_T &)> callable_
Callable storing the test body and any bound arguments. Invoked with a reference to the derived Self_...
Definition test.h:512
runnable(const char *name, class runner &runner, size_t own_index, Callable_T &&callable, Args_T &&... arguments)
Class template constructor.
runnable(const runnable &)=delete
Deleted copy constructor to prevent copying.
runnable(runnable &&)=delete
Deleted move constructor to prevent moving.
virtual void run(void)=0
Runs the test function by invoking the stored callable with the derived self instance.
Aggregated pass/fail/subtest counters for a node in the test tree.
const char * name(void) const noexcept
Gets the node name.
virtual ~test_node()
Virtual destructor for the test_node class.
Definition test.cpp:107
runner_totals totals_
Totals for the test node, including nested cases.
Definition test.h:229
runner_totals & totals() noexcept
Gets the totals for the test.
test_node(const char *name)
Constructs a test node.
Definition test.cpp:84
test_node(test_node &&)=delete
Deleted move constructor to prevent moving.
const char * name_
The test node name.
Definition test.h:224
test_node(const test_node &)=delete
Deleted copy constructor to prevent copying.
test_node & operator=(const test_node &)=delete
Deleted copy assignment operator to prevent copying.
A begin/end timestamp pair used to measure elapsed time.
Definition timings.h:205
Local implementation of source location information for diagnostics.
Definition reflection.h:138
static constexpr source_location current(const char *file="unknown", unsigned int line={}) noexcept
Obtain the current source location.
Reporter to display test results, including operand values and types for failures.
Definition reporter.h:186
The test runner for the µTest++ framework.
Definition runner.h:111
A runner variant that also manages statically-registered test suites.
Definition runner.h:345
A test suite designed for static (namespace-scope) registration with a static_runner.
Definition test.h:924
std::function< void(static_suite &)> static_callable_
Callable storing the static suite body and any bound arguments. Invoked with a reference to the concr...
Definition test.h:990
static_suite(static_suite &&)=delete
Deleted move constructor to prevent moving.
virtual void run(void) override
Executes the static suite body using the stored static callable.
Definition test.cpp:473
static_suite(const char *name, static_runner &runner, Callable_T &&callable, Args_T &&... arguments)
Class template constructor for static_suite.
static_suite(const static_suite &)=delete
Deleted copy constructor to prevent copying.
A named, runnable test case that lives inside a suite.
Definition test.h:542
suite & parent_suite_
Reference to the parent suite that owns this subtest.
Definition test.h:683
subtest(subtest &&)=delete
Deleted move constructor to prevent moving.
void test(const char *name, Callable_T &&callable, Args_T &&... arguments)
Adds a test case to the suite.
subtest(const char *name, class runner &runner, suite &parent_suite, size_t own_index, size_t nesting_depth, Callable_T &&callable, Args_T &&... arguments)
Constructs a subtest with a name, runner, parent suite, index, nesting depth, and callable.
virtual void run(void) override
Executes the subtest body by invoking the stored callable.
Definition test.cpp:298
subtest(const subtest &)=delete
Deleted copy constructor to prevent copying.
size_t nesting_depth_
The nesting depth of this subtest within the suite.
Definition test.h:688
size_t nesting_depth() const noexcept
Returns the nesting depth of this subtest.
A named, runnable test suite registered with the test runner.
Definition test.h:714
suite(const char *name, class runner &runner, Callable_T &&callable, Args_T &&... arguments)
Constructs a suite with a name, runner, and callable body.
virtual void run(void) override
Executes the suite body by invoking the stored callable.
Definition test.cpp:359
suite(const suite &)=delete
Deleted copy constructor to prevent copying.
detail::timestamps timings_
Timing measurements for this suite's execution.
Definition test.h:818
detail::timestamps & timings() noexcept
Gets the timings for this suite.
suite(suite &&)=delete
Deleted move constructor to prevent moving.
void test(const char *name, Callable_T &&callable, Args_T &&... arguments)
Adds a test case to the suite.
top_suite(top_suite &&)=delete
Deleted move constructor to prevent moving.
void name(const char *new_name) noexcept
Sets the name of the top-level suite.
top_suite(const char *name, class runner &runner)
Constructs the top-level suite with a name and runner reference.
Definition test.cpp:397
top_suite(const top_suite &)=delete
Deleted copy constructor to prevent copying.
C++20 concept satisfied when a type can be used as a test expression in expect() or assume().
auto assume(const Expr_T &expr, const reflection::source_location &sl=reflection::source_location::current())
Check a condition and, if false, abort test execution.
auto expect(const Expr_T &expr, const reflection::source_location &sl=reflection::source_location::current())
Evaluate a generic condition and report the results.
Internal implementation details for the µTest++ framework.
runner & to_runner(static_runner &static_runner_ref) noexcept
Converts a static_runner reference to a runner reference.
Definition runner.cpp:81
void register_static_suite(static_runner &static_runner_ref, static_suite &static_suite_ref)
Registers a static suite with a static runner.
Definition runner.cpp:93
Reflection utilities for the µTest++ testing framework.
Primary namespace for the µTest++ testing framework.
C++ header file with declarations for the µTest++ reflection utilities.
C++ header file with declarations for the µTest++ runner totals.
C++ header file with inline implementations for the µTest++ test suite.
C++ header file with declarations for the µTest++ timing utilities.
C++ header file with declarations for the µTest++ type trait utilities and metaprogramming support.