blob: 68c5f5d94e144a735b4ecc447175a8b233176b3d [file] [log] [blame]
onqtamcb6a29f2018-08-23 16:24:06 +03001<!DOCTYPE html>
2<html>
3<title>reporters</title>
4<xmp theme="united" style="display:none;">
5
6## Reporters
7
onqtam92dce5b2019-03-23 14:24:47 +02008Doctest has a modular reporter/listener system with which users can write their own reporters and register them. The reporter interface can also be used for "listening" to events.
9
10You can list all registered reporters with ```--list-reporters```. There are a few implemented reporters in the framework:
11- ```console``` - streaming - writes normal lines of text with coloring if a capable terminal is detected
12- ```xml``` - streaming - writes in xml format tailored to doctest
13
14Streaming means that results are delivered progressively and not at the end of the test run.
15
16The output is by default written to ```stdout``` but can be redirected with the use of the ```--out=<filename>``` [**command line option**](commandline.html).
onqtam9639cee2018-10-24 17:46:32 +030017
18Example how to define your own reporter:
19
20```
onqtam92dce5b2019-03-23 14:24:47 +020021#include <doctest/doctest.h>
22
23#include <mutex>
24
onqtam9639cee2018-10-24 17:46:32 +030025using namespace doctest;
26
onqtam92dce5b2019-03-23 14:24:47 +020027struct MyXmlReporter : public IReporter
onqtam9639cee2018-10-24 17:46:32 +030028{
onqtam92dce5b2019-03-23 14:24:47 +020029 // caching pointers/references to objects of these types - safe to do
30 std::ostream& stdout_stream;
31 const ContextOptions& opt;
onqtam9639cee2018-10-24 17:46:32 +030032 const TestCaseData* tc;
onqtam92dce5b2019-03-23 14:24:47 +020033 std::mutex mutex;
onqtam9639cee2018-10-24 17:46:32 +030034
onqtam92dce5b2019-03-23 14:24:47 +020035 // constructor has to accept the ContextOptions by ref as a single argument
36 MyXmlReporter(const ContextOptions& in)
37 : stdout_stream(*in.cout)
38 , opt(in) {}
onqtam9639cee2018-10-24 17:46:32 +030039
onqtam92dce5b2019-03-23 14:24:47 +020040 void report_query(const QueryData& /*in*/) override {}
onqtam9639cee2018-10-24 17:46:32 +030041
onqtam92dce5b2019-03-23 14:24:47 +020042 void test_run_start() override {}
43
44 void test_run_end(const TestRunStats& /*in*/) override {}
onqtam9639cee2018-10-24 17:46:32 +030045
46 void test_case_start(const TestCaseData& in) override { tc = &in; }
47
onqtam92dce5b2019-03-23 14:24:47 +020048 void test_case_end(const CurrentTestCaseStats& /*in*/) override {}
onqtam9639cee2018-10-24 17:46:32 +030049
onqtam92dce5b2019-03-23 14:24:47 +020050 void test_case_exception(const TestCaseException& /*in*/) override {}
onqtam9639cee2018-10-24 17:46:32 +030051
onqtam505b05c2019-05-06 11:39:02 +030052 void subcase_start(const SubcaseSignature& /*in*/) override {
53 std::lock_guard<std::mutex> lock(mutex);
54 }
onqtam9639cee2018-10-24 17:46:32 +030055
onqtam505b05c2019-05-06 11:39:02 +030056 void subcase_end() override {
57 std::lock_guard<std::mutex> lock(mutex);
58 }
onqtam9639cee2018-10-24 17:46:32 +030059
onqtam92dce5b2019-03-23 14:24:47 +020060 void log_assert(const AssertData& in) override {
61 // don't include successful asserts by default - this is done here
62 // instead of in the framework itself because doctest doesn't know
63 // if/when a reporter/listener cares about successful results
64 if(!in.m_failed && !opt.success)
65 return;
66
67 // make sure there are no races - this is done here instead of in the
68 // framework itself because doctest doesn't know if reporters/listeners
69 // care about successful asserts and thus doesn't lock a mutex unnecessarily
70 std::lock_guard<std::mutex> lock(mutex);
71
72 // ...
73 }
74
75 void log_message(const MessageData& /*in*/) override {
76 // messages too can be used in a multi-threaded context - like asserts
77 std::lock_guard<std::mutex> lock(mutex);
78
79 // ...
80 }
onqtam9639cee2018-10-24 17:46:32 +030081
82 void test_case_skipped(const TestCaseData& /*in*/) override {}
83};
84
onqtam92dce5b2019-03-23 14:24:47 +020085// "1" is the priority - used for ordering when multiple reporters/listeners are used
86REGISTER_REPORTER("my_xml", 1, MyXmlReporter);
onqtam9639cee2018-10-24 17:46:32 +030087```
88
onqtam92dce5b2019-03-23 14:24:47 +020089Multiple reporters can be used at the same time - just specify them through the ```--reporters=...``` [**command line filtering option**](commandline.html) using commas to separate them like this: ```--reporters=myListener,xml``` and their order of execution will be based on their priority - that is the number "1" in the case of the example reporter above (lower means earlier - the default console/xml reporters from the framework have 0 as their priority and negative numbers are accepted as well).
onqtam9639cee2018-10-24 17:46:32 +030090
onqtam92dce5b2019-03-23 14:24:47 +020091When implementing a reporter users are advised to follow the comments from the example above and look at the few implemented reporters in the framework itself. Also check out the [**example**](../../examples/all_features/reporters_and_listeners.cpp).
onqtamcb6a29f2018-08-23 16:24:06 +030092
93---------------
94
95[Home](readme.html#reference)
96
97<p align="center"><img src="../../scripts/data/logo/icon_2.svg"></p>
98
99
100</xmp>
101<script src="strapdown.js/strapdown.js"></script>
102</html>