micro-test-plus 5.0.0
µTest++ Testing Framework
Loading...
Searching...
No Matches
test.cpp
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
43
44// ----------------------------------------------------------------------------
45
46#if __has_include(<micro-os-plus/project-config.h>)
47#include <micro-os-plus/project-config.h>
48#elif __has_include(<micro-os-plus/config.h>)
49#pragma message \
50 "micro-os-plus/config.h is deprecated, rename to micro-os-plus/project-config.h and include it instead of micro-os-plus/config.h"
51#include <micro-os-plus/config.h>
52#endif // __has_include(<micro-os-plus/project-config.h>)
53
54#if __has_include(<micro-os-plus/micro-test-plus-defines.h>)
55#include <micro-os-plus/micro-test-plus-defines.h>
56#endif // __has_include(<micro-os-plus/micro-test-plus-defines.h>)
57
58#include <micro-os-plus/diag/trace.h>
59
62
63// ----------------------------------------------------------------------------
64
65#if defined(__GNUC__)
66#if defined(__clang__)
67#pragma clang diagnostic ignored "-Wunknown-warning-option"
68#pragma clang diagnostic ignored "-Wc++98-compat"
69#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
70#else // GCC only
71#pragma GCC diagnostic ignored "-Wredundant-tags"
72#pragma GCC diagnostic ignored "-Wsuggest-final-types"
73#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
74#endif
75#endif
76
77// ============================================================================
78
80{
81 namespace detail
82 {
83 // ========================================================================
84
92 {
93#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
94#if defined(__GNUC__)
95#pragma GCC diagnostic push
96#if defined(__clang__)
97#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
98#endif
99#endif
100 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name);
101#if defined(__GNUC__)
102#pragma GCC diagnostic pop
103#endif
104#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
105 }
106
114 {
115#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
116#if defined(__GNUC__)
117#pragma GCC diagnostic push
118#if defined(__clang__)
119#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
120#endif
121#endif
122 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name_);
123#if defined(__GNUC__)
124#pragma GCC diagnostic pop
125#endif
126#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
127 }
128
129 // ========================================================================
130
142 size_t own_index)
144 {
145#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
146#if defined(__GNUC__)
147#pragma GCC diagnostic push
148#if defined(__clang__)
149#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
150#endif
151#endif
152 trace::printf ("%s '%s' %zu\n", __PRETTY_FUNCTION__, name, own_index_);
153#if defined(__GNUC__)
154#pragma GCC diagnostic pop
155#endif
156#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
157 }
158
167 {
168#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
169#if defined(__GNUC__)
170#pragma GCC diagnostic push
171#if defined(__clang__)
172#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
173#endif
174#endif
175 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name_);
176#if defined(__GNUC__)
177#pragma GCC diagnostic pop
178#endif
179#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
180
181 // children_subtests_ holds unique_ptrs; destroyed automatically.
182 }
183
189 [[nodiscard]] reporter&
190 runnable_base::reporter (void) const noexcept
191 {
192 return runner_.reporter ();
193 }
194
201 [[noreturn]] void
203 {
204 runner_.abort (sl);
205 }
206
217 void
219 std::unique_ptr<class subtest> child_test, suite& suite)
220 {
221 // Transfer ownership into the vector.
222 children_subtests_.push_back (std::move (child_test));
223
224 // Run the child test case immediately.
225 class subtest& subtest = *children_subtests_.back ();
226 subtest.run ();
227
228 // This test executed one more subtest.
229#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
230#if defined(__GNUC__)
231#pragma GCC diagnostic push
232#if defined(__clang__)
233#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
234#endif
235#endif
236 trace::printf ("%s subtest '%s' executed one more subtest\n",
237 __PRETTY_FUNCTION__, name ());
238#if defined(__GNUC__)
239#pragma GCC diagnostic pop
240#endif
241#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
243 // Do not accumulate the totals from the child test into the current test
244 // totals, each subtest shows only its counters.
245
246#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
247#if defined(__GNUC__)
248#pragma GCC diagnostic push
249#if defined(__clang__)
250#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
251#endif
252#endif
253 trace::printf ("%s suite '%s' totals\n", __PRETTY_FUNCTION__,
254 suite.name ());
255#if defined(__GNUC__)
256#pragma GCC diagnostic pop
257#endif
258#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
259
260 // Accumulate the totals from the child test into the suite totals.
261 suite.totals () += subtest.totals ();
262 }
263 } // namespace detail
264
265 // ==========================================================================
266
277 {
278#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
279#if defined(__GNUC__)
280#pragma GCC diagnostic push
281#if defined(__clang__)
282#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
283#endif
284#endif
285 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name_);
286#if defined(__GNUC__)
287#pragma GCC diagnostic pop
288#endif
289#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
290 }
291
297 void
299 {
300#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED)
301#if defined(__GNUC__)
302#pragma GCC diagnostic push
303#if defined(__clang__)
304#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
305#endif
306#endif
307 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name_);
308#if defined(__GNUC__)
309#pragma GCC diagnostic pop
310#endif
311#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED
312
313 class reporter& reporter = this->reporter ();
314
315 // For now, subtests do not record the time.
316 // this->timings.timestamp_begin ();
317 reporter.begin_subtest (*this);
318
319 // Invoke the callable, passing the self reference followed by the variadic
320 // arguments.
321 callable_ (*this);
322
323 // this->timings.timestamp_end ();
324 reporter.end_subtest (*this);
325 }
326
327 // ==========================================================================
328
336 {
337#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
338#if defined(__GNUC__)
339#pragma GCC diagnostic push
340#if defined(__clang__)
341#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
342#endif
343#endif
344 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name_);
345#if defined(__GNUC__)
346#pragma GCC diagnostic pop
347#endif
348#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
349 }
350
356 void
358 {
359#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED)
360#if defined(__GNUC__)
361#pragma GCC diagnostic push
362#if defined(__clang__)
363#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
364#endif
365#endif
366 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name_);
367#if defined(__GNUC__)
368#pragma GCC diagnostic pop
369#endif
370#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED
371
372 class reporter& reporter = this->reporter ();
373
374 this->timings ().timestamp_begin ();
375 reporter.begin_suite (*this);
376
377 // Invoke the callable, passing the self reference followed by the variadic
378 // arguments.
379 callable_ (*this);
380
381 this->timings ().timestamp_end ();
382 reporter.end_suite (*this);
383 }
384
385 // ==========================================================================
386
395 : suite{ name, runner, [] (suite&) noexcept {} }
396 {
397#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
398#if defined(__GNUC__)
399#pragma GCC diagnostic push
400#if defined(__clang__)
401#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
402#endif
403#endif
404 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name);
405#if defined(__GNUC__)
406#pragma GCC diagnostic pop
407#endif
408#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
409
410 own_index (1);
411 }
412
420 {
421#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
422#if defined(__GNUC__)
423#pragma GCC diagnostic push
424#if defined(__clang__)
425#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
426#endif
427#endif
428 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name_);
429#if defined(__GNUC__)
430#pragma GCC diagnostic pop
431#endif
432#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
433 }
434
435 // ==========================================================================
436
444 {
445#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
446#if defined(__GNUC__)
447#pragma GCC diagnostic push
448#if defined(__clang__)
449#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
450#endif
451#endif
452 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name_);
453#if defined(__GNUC__)
454#pragma GCC diagnostic pop
455#endif
456#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
457 }
458
466 void
468 {
469#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED)
470#if defined(__GNUC__)
471#pragma GCC diagnostic push
472#if defined(__clang__)
473#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
474#endif
475#endif
476 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name_);
477#if defined(__GNUC__)
478#pragma GCC diagnostic pop
479#endif
480#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED
481
482 class reporter& reporter = this->reporter ();
483
484 this->timings ().timestamp_begin ();
485 reporter.begin_suite (*this);
486
487 static_callable_ (*this);
488
489 this->timings ().timestamp_end ();
490 reporter.end_suite (*this);
491 }
492
493 // --------------------------------------------------------------------------
494} // namespace micro_os_plus::micro_test_plus
495
496// ----------------------------------------------------------------------------
class runner & runner(void) const noexcept
Gets the test runner associated with this test runnable.
runnable_base(const char *name, runner &runner, size_t own_index)
Constructs a runnable_base with a name, runner, and index.
Definition test.cpp:141
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:218
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.
class reporter & reporter(void) const noexcept
Gets the test reporter associated with this test runnable.
Definition test.cpp:190
class runner & runner_
Reference to the test runner that owns this object.
Definition test.h:401
virtual ~runnable_base() override
Virtual destructor.
Definition test.cpp:166
void abort(const reflection::source_location &sl=reflection::source_location::current())
Aborts test execution via the owning runner.
Definition test.cpp:202
std::vector< std::unique_ptr< subtest > > children_subtests_
Owning collection of direct child subtests.
Definition test.h:427
void increment_executed_subtests(size_t count=1) noexcept
Increments the executed-subtests counter.
const char * name(void) const noexcept
Gets the node name.
virtual ~test_node()
Virtual destructor for the test_node class.
Definition test.cpp:113
runner_totals & totals() noexcept
Gets the totals for the test.
test_node(const char *name)
Constructs a test node.
Definition test.cpp:91
const char * name_
The test node name.
Definition test.h:224
void timestamp_begin(void) noexcept
Records the begin timestamp using the current system clock.
Definition timings.cpp:110
void timestamp_end(void) noexcept
Records the end timestamp using the current system clock.
Definition timings.cpp:143
Local implementation of source location information for diagnostics.
Definition reflection.h:138
Reporter to display test results, including operand values and types for failures.
Definition reporter.h:186
virtual void begin_subtest(subtest &subtest)=0
Mark the beginning of a subtest.
virtual void begin_suite(suite &suite)=0
Mark the beginning of a test suite.
virtual void end_suite(suite &suite)=0
Mark the end of a test suite.
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
virtual void run(void) override
Executes the static suite body using the stored static callable.
Definition test.cpp:467
virtual ~static_suite() override
Virtual destructor.
Definition test.cpp:443
A named, runnable test case that lives inside a suite.
Definition test.h:542
virtual ~subtest() override
Virtual destructor.
Definition test.cpp:276
virtual void run(void) override
Executes the subtest body by invoking the stored callable.
Definition test.cpp:298
A named, runnable test suite registered with the test runner.
Definition test.h:714
virtual void run(void) override
Executes the suite body by invoking the stored callable.
Definition test.cpp:357
detail::timestamps & timings() noexcept
Gets the timings for this suite.
virtual ~suite() override
Virtual destructor.
Definition test.cpp:335
top_suite(const char *name, class runner &runner)
Constructs the top-level suite with a name and runner reference.
Definition test.cpp:394
virtual ~top_suite() override
Virtual destructor.
Definition test.cpp:419
Internal implementation details for the µTest++ framework.
Primary namespace for the µTest++ testing framework.
C++ header file with declarations for the µTest++ test runner.
C++ header file with declarations for the µTest++ test suite.