Document QAbstractTestLogger's virtual method API

Provide the information an implementor needs in order to be able to
implement an logging backend.

Change-Id: I7bb522de57149dad843e01a8afa9f8891d011d29
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Edward Welbourne 2021-09-21 16:23:46 +02:00
parent 78c8f0cd4d
commit 2c2cdb959f

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtTest module of the Qt Toolkit.
@ -57,7 +57,53 @@
#endif
QT_BEGIN_NAMESPACE
/*!
\internal
\class QAbstractTestLogger
\inmodule QtTest
\brief Base class for test loggers
Implementations of logging for QtTest should implement all pure virtual
methods of this class and may implement the other virtual methods. This
class's documentation of each virtual method sets out how those
implementations are invoked by the QtTest code and offers guidance on how
the logging class should use the data. Actual implementations may have
different requirements - such as a file format with a defined schema, or a
target audience to serve - that affect how it interprets that guidance.
*/
/*!
\enum QAbstractTestLogger::IncidentTypes
\value Pass
\value XFail
\value Fail
\value XPass
\value BlacklistedPass
\value BlacklistedFail
\value BlacklistedXPass
\value BlacklistedXFail
*/
/*!
\enum QAbstractTestLogger::MessageTypes
\value Warn
\value QWarning
\value QDebug
\value QCritical
\value QFatal
\value Skip
\value Info
\value QInfo
*/
/*!
Constructs the base-class parts of the logger.
Derived classes should pass this base-constructor the \a filename of the
file to which they shall log test results, or \nullptr to write to standard
output. The protected member \c stream is set to the open file desriptor.
*/
QAbstractTestLogger::QAbstractTestLogger(const char *filename)
{
if (!filename) {
@ -81,20 +127,34 @@ QAbstractTestLogger::QAbstractTestLogger(const char *filename)
#endif
}
/*!
Destroys the logger object.
If the protected \c stream is not standard output, it is closed. In any
case it is cleared.
*/
QAbstractTestLogger::~QAbstractTestLogger()
{
QTEST_ASSERT(stream);
if (stream != stdout) {
if (stream != stdout)
fclose(stream);
}
stream = nullptr;
}
/*!
Returns true precisely if the \c output stream is standard output.
*/
bool QAbstractTestLogger::isLoggingToStdout() const
{
return stream == stdout;
}
/*!
Helper utility to blot out unprintable characters in \a str.
Takes a \c{'\0'}-terminated mutable string and changes any characters of it
that are not suitable for printing to \c{'?'} characters.
*/
void QAbstractTestLogger::filterUnprintable(char *str) const
{
unsigned char *idx = reinterpret_cast<unsigned char *>(str);
@ -105,6 +165,13 @@ void QAbstractTestLogger::filterUnprintable(char *str) const
}
}
/*!
Convenience method to write \a msg to the output stream.
The output \a msg must be a \c{'\0'}-terminated string (and not \nullptr).
A copy of it is passed to \l filterUnprintable() and the result written to
the output \c stream, which is then flushed.
*/
void QAbstractTestLogger::outputString(const char *msg)
{
QTEST_ASSERT(stream);
@ -120,14 +187,153 @@ void QAbstractTestLogger::outputString(const char *msg)
delete [] filtered;
}
/*!
Called before the start of a test run.
This virtual method is called before the first tests are run. A logging
implementation might open a file, write some preamble or prepare in other
ways, such as setting up initial values of variables. It can use the usual
Qt logging infrastucture, since it is also called before QtTest installs its
own custom message handler.
\sa stopLogging()
*/
void QAbstractTestLogger::startLogging()
{
}
/*!
Called after the end of a test run.
This virtual method is called after all tests have run. A logging
implementation might collate information gathered from the run, write a
summary or close a file. It can use the usual Qt logging infrastucture,
since it is also called after QtTest has restored the default message
handler it replaced with its own custom message handler.
\sa startLogging()
*/
void QAbstractTestLogger::stopLogging()
{
}
/*!
\fn void QAbstractTestLogger::enterTestFunction(const char *function)
This virtual method is called before each test function is invoked. It is
passed the name of the test function (without its class prefix) as \a
function. It is likewise called for \c{initTestCase()} at the start of
testing, after \l startLogging(), and for \c{cleanupTestCase()} at the end
of testing, in each case passing the name of the function. It is also called
with \nullptr as \function after the last of these functions, or in the
event of an early end to testing, before \l stopLogging().
For data-driven test functions, this is called only once, before the data
function is called to set up the table of datasets and the test is run with
its first dataset.
Every logging implementation must implement this method. It shall typically
need to record the name of the function for later use in log messages.
\sa leaveTestFunction(), enterTestData()
*/
/*!
\fn void QAbstractTestLogger::leaveTestFunction()
This virtual method is called after a test function has completed, to match
\l enterTestFunction(). For data-driven test functions, this is called only
once, after the test is run with its last dataset.
Every logging implementation must implement this method. In some cases it
may be called more than once without an intervening call to \l
enterTestFunction(); in such cases, the implementation should ignore the
second (and later) calls.
\sa enterTestFunction(), enterTestData()
*/
/*!
\fn void QAbstractTestLogger::enterTestData(QTestData *)
This virtual method is called before and after each call to a test
function. For a data-driven test, the call before is passed the name of the
test data row. This may combine a global data row name with a local data row
name. For non-data-driven tests and for the call after a test function,
\nullptr is passed
A logging implementation might chose to record the data row name for
reporting of results from the test for that data row. It should, in such a
case, clear its record of the name when called with \nullptr.
\sa enterTestFunction(), leaveTestFunction()
*/
/*!
\fn void QAbstractTestLogger::addIncident(IncidentTypes type, const char *description, const char *file, int line)
This virtual method is called when an event occurs that bears on whether the
test passes or fails. The \a type indicates whether this was a pass or a
fail, whether a failure was expected and whether the test being run is
blacklisted. The \a description may be empty (for a pass), a message
describing the failure or, for an expected failure, the explanation of why a
failure was expected. Where the location in code of the incident is known,
it is indicated by \a file and \a line; otherwise, these are \a nullptr and
0, respectively.
Every logging implementation must implement this method. Note that there are
circumstances where more than one incident may be reported, in this way, for
a single run of a test on a single dataset. It is (for now) the
implementation's responsibility to recognize such cases and decide what to
do about them.
\sa addMessage(), addBenchmarkResult()
*/
/*!
\fn void QAbstractTestLogger::addBenchmarkResult(const QBenchmarkResult &result)
This virtual method is called after a benchmark has been run enough times to
produce usable data. It is passed the median \a result from all cycles of
the code controlled by the test's QBENCHMARK loop.
Every logging implementation must implement this method.
\sa addIncident(), addMessage()
*/
/*!
\overload
\fn void QAbstractTestLogger::addMessage(MessageTypes type, const QString &message, const char *file, int line)
This virtual method is called, via its \c QtMsgType overload, from the
custom message handler QtTest installs. It is also used by the
implementations of QSKIP(), to warn about various situations detected by
QtTest itself, such as \e failure to see a message anticipated by
QTest::ignoreMessage() and, particularly when verbosity options have been
enabled via the command-line, to log some extra information.
Every logging implementation must implement this method. The \a type
indicates the category of message and the \a message is the content to be
reported. When the message is associated with specific code, the name of the
\a file and \a line number within it are also supplied (otherwise, these are
\nullptr and 0, respectively).
\sa QTest::ignoreMessage(), addIncident()
*/
/*!
\overload
This virtual method is called from the custom message handler QtTest
installs in place of Qt's default message handler for the duration of
testing, unless QTest::ignoreMessage() was used to ignore it, or too many
messages have previously been processed. (The limiting number of messages is
controlled by the -maxwarnings option to a test and defaults to 2002.)
Logging implementation should not normally need to over-ride this method.
The base implementation converts \a type to the matching \l MessageType,
formats the given \a message suitably for the specified \a context and
forwards the converted type and formatted message to the overload taking
MessageType and QString.
\sa QTest::ignoreMessage(), addIncident()
*/
void QAbstractTestLogger::addMessage(QtMsgType type, const QMessageLogContext &context,
const QString &message)
{