Doc: Change the Qt Testlib example pages
These pages are designed as tutorials, so they can be \page instead of \example. Also, reorganized the tutorials, moving them out of the testlib manual, into several qdoc files. Task-number: QTBUG-115248 Change-Id: I2cbd66ecc1082ecc9d3d1742b621ee009daf1031 Reviewed-by: Kai Köhne <kai.koehne@qt.io> Reviewed-by: Topi Reiniö <topi.reinio@qt.io> (cherry picked from commit 28defcfb78f3f70ad91a43a641012bd914e4e6b6) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
aea3d99a39
commit
023aecc885
@ -577,473 +577,3 @@
|
||||
available source code, which is linked to at the end of each chapter.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\example tutorial1
|
||||
|
||||
\previouspage {Qt Test Tutorial}{Qt Test Tutorial Overview}
|
||||
\nextpage {Chapter 2: Data Driven Testing}{Chapter 2}
|
||||
|
||||
\title Chapter 1: Writing a Unit Test
|
||||
\brief How to write a unit test.
|
||||
|
||||
This first chapter demonstrates how to write a simple unit test and how to
|
||||
run the test case as a stand-alone executable.
|
||||
|
||||
\section1 Writing a Test
|
||||
|
||||
Let's assume you want to test the behavior of our QString class.
|
||||
First, you need a class that contains your test functions. This class
|
||||
has to inherit from QObject:
|
||||
|
||||
\snippet tutorial1/testqstring.cpp 0
|
||||
|
||||
\note You need to include the QTest header and declare the test functions as
|
||||
private slots so the test framework finds and executes it.
|
||||
|
||||
Then you need to implement the test function itself. The
|
||||
implementation could look like this:
|
||||
|
||||
\snippet code/doc_src_qtestlib.cpp 8
|
||||
|
||||
The \l QVERIFY() macro evaluates the expression passed as its
|
||||
argument. If the expression evaluates to true, the execution of
|
||||
the test function continues. Otherwise, a message describing the
|
||||
failure is appended to the test log, and the test function stops
|
||||
executing.
|
||||
|
||||
But if you want a more verbose output to the test log, you should
|
||||
use the \l QCOMPARE() macro instead:
|
||||
|
||||
\snippet tutorial1/testqstring.cpp 1
|
||||
|
||||
If the strings are not equal, the contents of both strings are
|
||||
appended to the test log, making it immediately visible why the
|
||||
comparison failed.
|
||||
|
||||
\section1 Preparing the Stand-Alone Executable
|
||||
|
||||
Finally, to make our test case a stand-alone executable, the
|
||||
following two lines are needed:
|
||||
|
||||
\snippet tutorial1/testqstring.cpp 2
|
||||
|
||||
The \l QTEST_MAIN() macro expands to a simple \c main()
|
||||
method that runs all the test functions. Note that if both the
|
||||
declaration and the implementation of our test class are in a \c
|
||||
.cpp file, we also need to include the generated moc file to make
|
||||
Qt's introspection work.
|
||||
|
||||
\section1 Building the Executable
|
||||
|
||||
\include {building-examples.qdocinc} {building the executable} {tutorial1}
|
||||
|
||||
\note If you're using windows, replace \c make with \c
|
||||
nmake or whatever build tool you use.
|
||||
|
||||
\section1 Running the Executable
|
||||
|
||||
Running the resulting executable should give you the following
|
||||
output:
|
||||
|
||||
\snippet code/doc_src_qtestlib.qdoc 10
|
||||
|
||||
Congratulations! You just wrote and executed your first unit test
|
||||
using the Qt Test framework.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\example tutorial2
|
||||
|
||||
\previouspage {Chapter 1: Writing a Unit Test}{Chapter 1}
|
||||
\nextpage {Chapter 3: Simulating Gui Events}{Chapter 3}
|
||||
|
||||
\title Chapter 2: Data Driven Testing
|
||||
\brief How to create data driven tests.
|
||||
|
||||
This chapter demonstrates how to execute a test multiple times with
|
||||
different test data.
|
||||
|
||||
So far, we have hard coded the data we wanted to test into our
|
||||
test function. If we add more test data, the function might look like
|
||||
this:
|
||||
|
||||
\snippet code/doc_src_qtestlib.cpp 11
|
||||
|
||||
To prevent the function from being cluttered with repetitive code, Qt Test
|
||||
supports adding test data to a test function. All we need is to add another
|
||||
private slot to our test class:
|
||||
|
||||
\snippet tutorial2/testqstring.cpp 0
|
||||
|
||||
\section1 Writing the Data Function
|
||||
|
||||
A test function's associated data function has \c _data appended to its
|
||||
name. Our data function looks like this:
|
||||
|
||||
\snippet tutorial2/testqstring.cpp 1
|
||||
|
||||
First, we define the two elements of our test table using the \l
|
||||
QTest::addColumn() function: a test string and the
|
||||
expected result of applying the QString::toUpper() function to
|
||||
that string.
|
||||
|
||||
Then, we add some data to the table using the \l QTest::newRow()
|
||||
function. We can also use \l QTest::addRow() if we need to format some data
|
||||
in the row name, for example when generating many data rows iteratively.
|
||||
Each row of data will become a separate row in the test table.
|
||||
|
||||
\l QTest::newRow() takes one argument: a name that will be associated with
|
||||
the data set and used in the test log to identify the data row. \l
|
||||
QTest::addRow() takes a (\c{printf}-style) format string followed by the
|
||||
parameters to be represented in place of the formatting tokens in the format
|
||||
string. Then, we stream the data set into the new table row. First an
|
||||
arbitrary string, and then the expected result of applying the
|
||||
QString::toUpper() function to that string.
|
||||
|
||||
You can think of the test data as a two-dimensional table. In
|
||||
our case, it has two columns called \c string and \c result and
|
||||
three rows. In addition, a name and an index are associated
|
||||
with each row:
|
||||
|
||||
\table
|
||||
\header
|
||||
\li index
|
||||
\li name
|
||||
\li string
|
||||
\li result
|
||||
\row
|
||||
\li 0
|
||||
\li all-lower
|
||||
\li "hello"
|
||||
\li HELLO
|
||||
\row
|
||||
\li 1
|
||||
\li mixed
|
||||
\li "Hello"
|
||||
\li HELLO
|
||||
\row
|
||||
\li 2
|
||||
\li all-upper
|
||||
\li "HELLO"
|
||||
\li HELLO
|
||||
\endtable
|
||||
|
||||
When data is streamed into the row, each datum is asserted to match
|
||||
the type of the column whose value it supplies. If any assertion fails,
|
||||
the test is aborted.
|
||||
|
||||
The names of rows and columns, in a given test function's data table, should
|
||||
be unique: if two rows share a name, or two columns share a name, a warning
|
||||
will (since Qt 6.5) be produced. See \l qWarning() for how you can cause
|
||||
warnings to be treated as errors and \l {Test for Warnings} for how to get
|
||||
your tests clear of other warnings.
|
||||
|
||||
\section1 Rewriting the Test Function
|
||||
|
||||
Our test function can now be rewritten:
|
||||
|
||||
\snippet tutorial2/testqstring.cpp 2
|
||||
|
||||
The TestQString::toUpper() function will be executed three times,
|
||||
once for each entry in the test table that we created in the
|
||||
associated TestQString::toUpper_data() function.
|
||||
|
||||
First, we fetch the two elements of the data set using the \l
|
||||
QFETCH() macro. \l QFETCH() takes two arguments: The data type of
|
||||
the element and the element name. Then, we perform the test using
|
||||
the \l QCOMPARE() macro.
|
||||
|
||||
This approach makes it very easy to add new data to the test
|
||||
without modifying the test itself.
|
||||
|
||||
\section1 Preparing the Stand-Alone Executable
|
||||
|
||||
And again, to make our test case a stand-alone executable,
|
||||
the following two lines are needed:
|
||||
|
||||
\snippet tutorial2/testqstring.cpp 3
|
||||
|
||||
As before, the QTEST_MAIN() macro expands to a simple main()
|
||||
method that runs all the test functions, and since both the
|
||||
declaration and the implementation of our test class are in a .cpp
|
||||
file, we also need to include the generated moc file to make Qt's
|
||||
introspection work.
|
||||
|
||||
\section1 Building the Executable
|
||||
|
||||
\include {building-examples.qdocinc} {building the executable} {tutorial2}
|
||||
|
||||
\section1 Running the Executable
|
||||
|
||||
Running the resulting executable should give you the following
|
||||
output:
|
||||
|
||||
\snippet code/doc_src_qtestlib.qdoc 11
|
||||
*/
|
||||
|
||||
/*!
|
||||
\example tutorial3
|
||||
|
||||
\previouspage {Chapter 2: Data Driven Testing}{Chapter 2}
|
||||
\nextpage {Chapter 4: Replaying GUI Events}{Chapter 4}
|
||||
|
||||
\title Chapter 3: Simulating GUI Events
|
||||
\brief How to simulate GUI events.
|
||||
|
||||
Qt Test features some mechanisms to test graphical user
|
||||
interfaces. Instead of simulating native window system events,
|
||||
Qt Test sends internal Qt events. That means there are no
|
||||
side-effects on the machine the tests are running on.
|
||||
|
||||
This chapter demonstrates how to write a simple GUI test.
|
||||
|
||||
\section1 Writing a GUI Test
|
||||
|
||||
This time, let's assume you want to test the behavior of our
|
||||
QLineEdit class. As before, you will need a class that contains
|
||||
your test function:
|
||||
|
||||
\snippet tutorial3/testgui.cpp 0
|
||||
|
||||
The only difference is that you need to include the Qt GUI class
|
||||
definitions in addition to the QTest namespace.
|
||||
|
||||
\snippet tutorial3/testgui.cpp 1
|
||||
|
||||
In the implementation of the test function, we first create a
|
||||
QLineEdit. Then, we simulate writing "hello world" in the line edit
|
||||
using the \l QTest::keyClicks() function.
|
||||
|
||||
\note The widget must also be shown in order to correctly test keyboard
|
||||
shortcuts.
|
||||
|
||||
QTest::keyClicks() simulates clicking a sequence of keys on a
|
||||
widget. Optionally, a keyboard modifier can be specified as well
|
||||
as a delay (in milliseconds) of the test after each key click. In
|
||||
a similar way, you can use the QTest::keyClick(),
|
||||
QTest::keyPress(), QTest::keyRelease(), QTest::mouseClick(),
|
||||
QTest::mouseDClick(), QTest::mouseMove(), QTest::mousePress()
|
||||
and QTest::mouseRelease() functions to simulate the associated
|
||||
GUI events.
|
||||
|
||||
Finally, we use the \l QCOMPARE() macro to check if the line edit's
|
||||
text is as expected.
|
||||
|
||||
\section1 Preparing the Stand-Alone Executable
|
||||
|
||||
As before, to make our test case a stand-alone executable, the
|
||||
following two lines are needed:
|
||||
|
||||
\snippet tutorial3/testgui.cpp 2
|
||||
|
||||
The QTEST_MAIN() macro expands to a simple main() method that
|
||||
runs all the test functions, and since both the declaration and
|
||||
the implementation of our test class are in a .cpp file, we also
|
||||
need to include the generated moc file to make Qt's introspection
|
||||
work.
|
||||
|
||||
\section1 Building the Executable
|
||||
|
||||
\include {building-examples.qdocinc} {building the executable} {tutorial3}
|
||||
|
||||
\section1 Running the Executable
|
||||
|
||||
Running the resulting executable should give you the following
|
||||
output:
|
||||
|
||||
\snippet code/doc_src_qtestlib.qdoc 12
|
||||
*/
|
||||
|
||||
/*!
|
||||
\example tutorial4
|
||||
|
||||
\previouspage {Chapter 3: Simulating GUI Events}{Chapter 3}
|
||||
\nextpage {Chapter 5: Writing a Benchmark}{Chapter 5}
|
||||
|
||||
\title Chapter 4: Replaying GUI Events
|
||||
\brief How to replay GUI events.
|
||||
|
||||
In this chapter, we will show how to simulate a GUI event,
|
||||
and how to store a series of GUI events as well as replay them on
|
||||
a widget.
|
||||
|
||||
The approach to storing a series of events and replaying them is
|
||||
quite similar to the approach explained in \l {Chapter 2:
|
||||
Data Driven Testing}{chapter 2}. All you need to do is to add a data
|
||||
function to your test class:
|
||||
|
||||
\snippet tutorial4/testgui.cpp 0
|
||||
|
||||
\section1 Writing the Data Function
|
||||
|
||||
As before, a test function's associated data function carries the
|
||||
same name, appended by \c{_data}.
|
||||
|
||||
\snippet tutorial4/testgui.cpp 1
|
||||
|
||||
First, we define the elements of the table using the
|
||||
QTest::addColumn() function: A list of GUI events, and the
|
||||
expected result of applying the list of events on a QWidget. Note
|
||||
that the type of the first element is \l QTestEventList.
|
||||
|
||||
A QTestEventList can be populated with GUI events that can be
|
||||
stored as test data for later usage, or be replayed on any
|
||||
QWidget.
|
||||
|
||||
In our current data function, we create two \l
|
||||
{QTestEventList} elements. The first list consists of a single click to
|
||||
the 'a' key. We add the event to the list using the
|
||||
QTestEventList::addKeyClick() function. Then we use the
|
||||
QTest::newRow() function to give the data set a name, and
|
||||
stream the event list and the expected result into the table.
|
||||
|
||||
The second list consists of two key clicks: an 'a' with a
|
||||
following 'backspace'. Again we use the
|
||||
QTestEventList::addKeyClick() to add the events to the list, and
|
||||
QTest::newRow() to put the event list and the expected
|
||||
result into the table with an associated name.
|
||||
|
||||
\section1 Rewriting the Test Function
|
||||
|
||||
Our test can now be rewritten:
|
||||
|
||||
\snippet tutorial4/testgui.cpp 2
|
||||
|
||||
The TestGui::testGui() function will be executed two times,
|
||||
once for each entry in the test data that we created in the
|
||||
associated TestGui::testGui_data() function.
|
||||
|
||||
First, we fetch the two elements of the data set using the \l
|
||||
QFETCH() macro. \l QFETCH() takes two arguments: the data type of
|
||||
the element and the element name. Then we create a QLineEdit, and
|
||||
apply the list of events on that widget using the
|
||||
QTestEventList::simulate() function.
|
||||
|
||||
Finally, we use the QCOMPARE() macro to check if the line edit's
|
||||
text is as expected.
|
||||
|
||||
\section1 Preparing the Stand-Alone Executable
|
||||
|
||||
As before, to make our test case a stand-alone executable,
|
||||
the following two lines are needed:
|
||||
|
||||
\snippet tutorial4/testgui.cpp 3
|
||||
|
||||
The QTEST_MAIN() macro expands to a simple main() method that
|
||||
runs all the test functions, and since both the declaration and
|
||||
the implementation of our test class are in a .cpp file, we also
|
||||
need to include the generated moc file to make Qt's introspection
|
||||
work.
|
||||
|
||||
\section1 Building the Executable
|
||||
|
||||
\include {building-examples.qdocinc} {building the executable} {tutorial4}
|
||||
|
||||
\section1 Running the Executable
|
||||
|
||||
Running the resulting executable should give you the following
|
||||
output:
|
||||
|
||||
\snippet code/doc_src_qtestlib.qdoc 13
|
||||
*/
|
||||
|
||||
/*!
|
||||
\example tutorial5
|
||||
|
||||
\previouspage {Chapter 4: Replaying GUI Events}{Chapter 4}
|
||||
\nextpage {Chapter 6: Skipping Tests with QSKIP}{Chapter 6}
|
||||
|
||||
\title Chapter 5: Writing a Benchmark
|
||||
\brief How to write a benchmark.
|
||||
|
||||
This chapter demonstrates how to write benchmarks using Qt Test.
|
||||
|
||||
\section1 Writing a Benchmark
|
||||
To create a benchmark we extend a test function with a QBENCHMARK macro.
|
||||
A benchmark test function will then typically consist of setup code and
|
||||
a QBENCHMARK macro that contains the code to be measured. This test
|
||||
function benchmarks QString::localeAwareCompare().
|
||||
|
||||
\snippet tutorial5/benchmarking.cpp 0
|
||||
|
||||
Setup can be done at the beginning of the function. At this point, the clock
|
||||
is not running. The code inside the QBENCHMARK macro will be
|
||||
measured, and possibly repeated several times in order to get an
|
||||
accurate measurement.
|
||||
|
||||
Several \l {testlib-benchmarking-measurement}{back-ends} are available
|
||||
and can be selected on the command line.
|
||||
|
||||
\section1 Data Functions
|
||||
|
||||
Data functions are useful for creating benchmarks that compare
|
||||
multiple data inputs, for example locale aware compare against standard
|
||||
compare.
|
||||
|
||||
\snippet tutorial5/benchmarking.cpp 1
|
||||
|
||||
The test function then uses the data to determine what to benchmark.
|
||||
|
||||
\snippet tutorial5/benchmarking.cpp 2
|
||||
|
||||
The \c{if (useLocaleCompare)} switch is placed outside the QBENCHMARK
|
||||
macro to avoid measuring its overhead. Each benchmark test function
|
||||
can have one active QBENCHMARK macro.
|
||||
|
||||
\section1 Building the Executable
|
||||
|
||||
\include {building-examples.qdocinc} {building the executable} {tutorial5}
|
||||
|
||||
\section1 Running the Executable
|
||||
|
||||
Running the resulting executable should give you the following
|
||||
output:
|
||||
|
||||
\snippet code/doc_src_qtestlib.qdoc 14
|
||||
*/
|
||||
/*!
|
||||
\page qttestlib-tutorial6.html
|
||||
|
||||
\previouspage {Chapter 5: Writing a Benchmark}{Chapter 5}
|
||||
|
||||
\title Chapter 6: Skipping Tests with QSKIP
|
||||
\brief How to skip tests in certain cases.
|
||||
|
||||
\section2 Using QSKIP(\a description) in a test function
|
||||
|
||||
If the QSKIP() macro is called from a test function, it stops
|
||||
the execution of the test without adding a failure to the test log.
|
||||
It can be used to skip tests that are certain to fail. The text in
|
||||
the QSKIP \a description parameter is appended to the test log,
|
||||
and should explain why the test was not carried out.
|
||||
|
||||
QSKIP can be used to skip testing when the implementation is not yet
|
||||
complete or not supported on a certain platform. When there are known
|
||||
failures, QEXPECT_FAIL is recommended, as it supports running the rest
|
||||
of the test, when possible.
|
||||
|
||||
Example of QSKIP in a test function:
|
||||
|
||||
\snippet code/doc_src_qtqskip_snippet.cpp 0
|
||||
|
||||
In a data-driven test, each call to QSKIP() skips only the current
|
||||
row of test data. If the data-driven test contains an unconditional
|
||||
call to QSKIP, it produces a skip message for each row of test data.
|
||||
|
||||
\section2 Using QSKIP in a _data function
|
||||
|
||||
If called from a _data function, the QSKIP() macro stops
|
||||
execution of the _data function. This prevents execution of the
|
||||
associated test function.
|
||||
|
||||
See below for an example:
|
||||
|
||||
\snippet code/doc_src_qtqskip.cpp 1
|
||||
|
||||
\section2 Using QSKIP from initTestCase() or initTestCase_data()
|
||||
|
||||
If called from \c initTestCase() or \c initTestCase_data(), the
|
||||
QSKIP() macro will skip all test and _data functions.
|
||||
*/
|
||||
|
76
src/testlib/doc/src/qttestlib-tutorial1.qdoc
Normal file
76
src/testlib/doc/src/qttestlib-tutorial1.qdoc
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// Copyright (C) 2016 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\page qttestlib-tutorial1-example.html
|
||||
\previouspage {Qt Test Tutorial}{Qt Test Tutorial Overview}
|
||||
\nextpage {Chapter 2: Data Driven Testing}{Chapter 2}
|
||||
|
||||
\title Chapter 1: Writing a Unit Test
|
||||
\brief How to write a unit test.
|
||||
|
||||
This first chapter demonstrates how to write a simple unit test and how to
|
||||
run the test case as a stand-alone executable.
|
||||
|
||||
\section1 Writing a Test
|
||||
|
||||
Let's assume you want to test the behavior of our QString class.
|
||||
First, you need a class that contains your test functions. This class
|
||||
has to inherit from QObject:
|
||||
|
||||
\snippet tutorial1/testqstring.cpp 0
|
||||
|
||||
\note You need to include the QTest header and declare the test functions as
|
||||
private slots so the test framework finds and executes it.
|
||||
|
||||
Then you need to implement the test function itself. The
|
||||
implementation could look like this:
|
||||
|
||||
\snippet code/doc_src_qtestlib.cpp 8
|
||||
|
||||
The \l QVERIFY() macro evaluates the expression passed as its
|
||||
argument. If the expression evaluates to true, the execution of
|
||||
the test function continues. Otherwise, a message describing the
|
||||
failure is appended to the test log, and the test function stops
|
||||
executing.
|
||||
|
||||
But if you want a more verbose output to the test log, you should
|
||||
use the \l QCOMPARE() macro instead:
|
||||
|
||||
\snippet tutorial1/testqstring.cpp 1
|
||||
|
||||
If the strings are not equal, the contents of both strings are
|
||||
appended to the test log, making it immediately visible why the
|
||||
comparison failed.
|
||||
|
||||
\section1 Preparing the Stand-Alone Executable
|
||||
|
||||
Finally, to make our test case a stand-alone executable, the
|
||||
following two lines are needed:
|
||||
|
||||
\snippet tutorial1/testqstring.cpp 2
|
||||
|
||||
The \l QTEST_MAIN() macro expands to a simple \c main()
|
||||
method that runs all the test functions. Note that if both the
|
||||
declaration and the implementation of our test class are in a \c
|
||||
.cpp file, we also need to include the generated moc file to make
|
||||
Qt's introspection work.
|
||||
|
||||
\section1 Building the Executable
|
||||
|
||||
\include {building-examples.qdocinc} {building the executable} {tutorial1}
|
||||
|
||||
\note If you're using windows, replace \c make with \c
|
||||
nmake or whatever build tool you use.
|
||||
|
||||
\section1 Running the Executable
|
||||
|
||||
Running the resulting executable should give you the following
|
||||
output:
|
||||
|
||||
\snippet code/doc_src_qtestlib.qdoc 10
|
||||
|
||||
Congratulations! You just wrote and executed your first unit test
|
||||
using the Qt Test framework.
|
||||
*/
|
132
src/testlib/doc/src/qttestlib-tutorial2.qdoc
Normal file
132
src/testlib/doc/src/qttestlib-tutorial2.qdoc
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// Copyright (C) 2016 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\page qttestlib-tutorial2-example.html
|
||||
\previouspage {Chapter 1: Writing a Unit Test}{Chapter 1}
|
||||
\nextpage {Chapter 3: Simulating Gui Events}{Chapter 3}
|
||||
|
||||
\title Chapter 2: Data Driven Testing
|
||||
\brief How to create data driven tests.
|
||||
|
||||
This chapter demonstrates how to execute a test multiple times with
|
||||
different test data.
|
||||
|
||||
So far, we have hard coded the data we wanted to test into our
|
||||
test function. If we add more test data, the function might look like
|
||||
this:
|
||||
|
||||
\snippet code/doc_src_qtestlib.cpp 11
|
||||
|
||||
To prevent the function from being cluttered with repetitive code, Qt Test
|
||||
supports adding test data to a test function. All we need is to add another
|
||||
private slot to our test class:
|
||||
|
||||
\snippet tutorial2/testqstring.cpp 0
|
||||
|
||||
\section1 Writing the Data Function
|
||||
|
||||
A test function's associated data function has \c _data appended to its
|
||||
name. Our data function looks like this:
|
||||
|
||||
\snippet tutorial2/testqstring.cpp 1
|
||||
|
||||
First, we define the two elements of our test table using the \l
|
||||
QTest::addColumn() function: a test string and the
|
||||
expected result of applying the QString::toUpper() function to
|
||||
that string.
|
||||
|
||||
Then, we add some data to the table using the \l QTest::newRow()
|
||||
function. We can also use \l QTest::addRow() if we need to format some data
|
||||
in the row name, for example when generating many data rows iteratively.
|
||||
Each row of data will become a separate row in the test table.
|
||||
|
||||
\l QTest::newRow() takes one argument: a name that will be associated with
|
||||
the data set and used in the test log to identify the data row. \l
|
||||
QTest::addRow() takes a (\c{printf}-style) format string followed by the
|
||||
parameters to be represented in place of the formatting tokens in the format
|
||||
string. Then, we stream the data set into the new table row. First an
|
||||
arbitrary string, and then the expected result of applying the
|
||||
QString::toUpper() function to that string.
|
||||
|
||||
You can think of the test data as a two-dimensional table. In
|
||||
our case, it has two columns called \c string and \c result and
|
||||
three rows. In addition, a name and an index are associated
|
||||
with each row:
|
||||
|
||||
\table
|
||||
\header
|
||||
\li index
|
||||
\li name
|
||||
\li string
|
||||
\li result
|
||||
\row
|
||||
\li 0
|
||||
\li all-lower
|
||||
\li "hello"
|
||||
\li HELLO
|
||||
\row
|
||||
\li 1
|
||||
\li mixed
|
||||
\li "Hello"
|
||||
\li HELLO
|
||||
\row
|
||||
\li 2
|
||||
\li all-upper
|
||||
\li "HELLO"
|
||||
\li HELLO
|
||||
\endtable
|
||||
|
||||
When data is streamed into the row, each datum is asserted to match
|
||||
the type of the column whose value it supplies. If any assertion fails,
|
||||
the test is aborted.
|
||||
|
||||
The names of rows and columns, in a given test function's data table, should
|
||||
be unique: if two rows share a name, or two columns share a name, a warning
|
||||
will (since Qt 6.5) be produced. See \l qWarning() for how you can cause
|
||||
warnings to be treated as errors and \l {Test for Warnings} for how to get
|
||||
your tests clear of other warnings.
|
||||
|
||||
\section1 Rewriting the Test Function
|
||||
|
||||
Our test function can now be rewritten:
|
||||
|
||||
\snippet tutorial2/testqstring.cpp 2
|
||||
|
||||
The TestQString::toUpper() function will be executed three times,
|
||||
once for each entry in the test table that we created in the
|
||||
associated TestQString::toUpper_data() function.
|
||||
|
||||
First, we fetch the two elements of the data set using the \l
|
||||
QFETCH() macro. \l QFETCH() takes two arguments: The data type of
|
||||
the element and the element name. Then, we perform the test using
|
||||
the \l QCOMPARE() macro.
|
||||
|
||||
This approach makes it very easy to add new data to the test
|
||||
without modifying the test itself.
|
||||
|
||||
\section1 Preparing the Stand-Alone Executable
|
||||
|
||||
And again, to make our test case a stand-alone executable,
|
||||
the following two lines are needed:
|
||||
|
||||
\snippet tutorial2/testqstring.cpp 3
|
||||
|
||||
As before, the QTEST_MAIN() macro expands to a simple main()
|
||||
method that runs all the test functions, and since both the
|
||||
declaration and the implementation of our test class are in a .cpp
|
||||
file, we also need to include the generated moc file to make Qt's
|
||||
introspection work.
|
||||
|
||||
\section1 Building the Executable
|
||||
|
||||
\include {building-examples.qdocinc} {building the executable} {tutorial2}
|
||||
|
||||
\section1 Running the Executable
|
||||
|
||||
Running the resulting executable should give you the following
|
||||
output:
|
||||
|
||||
\snippet code/doc_src_qtestlib.qdoc 11
|
||||
*/
|
75
src/testlib/doc/src/qttestlib-tutorial3.qdoc
Normal file
75
src/testlib/doc/src/qttestlib-tutorial3.qdoc
Normal file
@ -0,0 +1,75 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// Copyright (C) 2016 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\page qttestlib-tutorial3-example.html
|
||||
\previouspage {Chapter 2: Data Driven Testing}{Chapter 2}
|
||||
\nextpage {Chapter 4: Replaying GUI Events}{Chapter 4}
|
||||
|
||||
\title Chapter 3: Simulating GUI Events
|
||||
\brief How to simulate GUI events.
|
||||
|
||||
Qt Test features some mechanisms to test graphical user
|
||||
interfaces. Instead of simulating native window system events,
|
||||
Qt Test sends internal Qt events. That means there are no
|
||||
side-effects on the machine the tests are running on.
|
||||
|
||||
This chapter demonstrates how to write a simple GUI test.
|
||||
|
||||
\section1 Writing a GUI Test
|
||||
|
||||
This time, let's assume you want to test the behavior of our
|
||||
QLineEdit class. As before, you will need a class that contains
|
||||
your test function:
|
||||
|
||||
\snippet tutorial3/testgui.cpp 0
|
||||
|
||||
The only difference is that you need to include the Qt GUI class
|
||||
definitions in addition to the QTest namespace.
|
||||
|
||||
\snippet tutorial3/testgui.cpp 1
|
||||
|
||||
In the implementation of the test function, we first create a
|
||||
QLineEdit. Then, we simulate writing "hello world" in the line edit
|
||||
using the \l QTest::keyClicks() function.
|
||||
|
||||
\note The widget must also be shown in order to correctly test keyboard
|
||||
shortcuts.
|
||||
|
||||
QTest::keyClicks() simulates clicking a sequence of keys on a
|
||||
widget. Optionally, a keyboard modifier can be specified as well
|
||||
as a delay (in milliseconds) of the test after each key click. In
|
||||
a similar way, you can use the QTest::keyClick(),
|
||||
QTest::keyPress(), QTest::keyRelease(), QTest::mouseClick(),
|
||||
QTest::mouseDClick(), QTest::mouseMove(), QTest::mousePress()
|
||||
and QTest::mouseRelease() functions to simulate the associated
|
||||
GUI events.
|
||||
|
||||
Finally, we use the \l QCOMPARE() macro to check if the line edit's
|
||||
text is as expected.
|
||||
|
||||
\section1 Preparing the Stand-Alone Executable
|
||||
|
||||
As before, to make our test case a stand-alone executable, the
|
||||
following two lines are needed:
|
||||
|
||||
\snippet tutorial3/testgui.cpp 2
|
||||
|
||||
The QTEST_MAIN() macro expands to a simple main() method that
|
||||
runs all the test functions, and since both the declaration and
|
||||
the implementation of our test class are in a .cpp file, we also
|
||||
need to include the generated moc file to make Qt's introspection
|
||||
work.
|
||||
|
||||
\section1 Building the Executable
|
||||
|
||||
\include {building-examples.qdocinc} {building the executable} {tutorial3}
|
||||
|
||||
\section1 Running the Executable
|
||||
|
||||
Running the resulting executable should give you the following
|
||||
output:
|
||||
|
||||
\snippet code/doc_src_qtestlib.qdoc 12
|
||||
*/
|
95
src/testlib/doc/src/qttestlib-tutorial4.qdoc
Normal file
95
src/testlib/doc/src/qttestlib-tutorial4.qdoc
Normal file
@ -0,0 +1,95 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// Copyright (C) 2016 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\page qttestlib-tutorial4-example.html
|
||||
\previouspage {Chapter 3: Simulating GUI Events}{Chapter 3}
|
||||
\nextpage {Chapter 5: Writing a Benchmark}{Chapter 5}
|
||||
|
||||
\title Chapter 4: Replaying GUI Events
|
||||
\brief How to replay GUI events.
|
||||
|
||||
In this chapter, we will show how to simulate a GUI event,
|
||||
and how to store a series of GUI events as well as replay them on
|
||||
a widget.
|
||||
|
||||
The approach to storing a series of events and replaying them is
|
||||
quite similar to the approach explained in \l {Chapter 2:
|
||||
Data Driven Testing}{chapter 2}. All you need to do is to add a data
|
||||
function to your test class:
|
||||
|
||||
\snippet tutorial4/testgui.cpp 0
|
||||
|
||||
\section1 Writing the Data Function
|
||||
|
||||
As before, a test function's associated data function carries the
|
||||
same name, appended by \c{_data}.
|
||||
|
||||
\snippet tutorial4/testgui.cpp 1
|
||||
|
||||
First, we define the elements of the table using the
|
||||
QTest::addColumn() function: A list of GUI events, and the
|
||||
expected result of applying the list of events on a QWidget. Note
|
||||
that the type of the first element is \l QTestEventList.
|
||||
|
||||
A QTestEventList can be populated with GUI events that can be
|
||||
stored as test data for later usage, or be replayed on any
|
||||
QWidget.
|
||||
|
||||
In our current data function, we create two \l
|
||||
{QTestEventList} elements. The first list consists of a single click to
|
||||
the 'a' key. We add the event to the list using the
|
||||
QTestEventList::addKeyClick() function. Then we use the
|
||||
QTest::newRow() function to give the data set a name, and
|
||||
stream the event list and the expected result into the table.
|
||||
|
||||
The second list consists of two key clicks: an 'a' with a
|
||||
following 'backspace'. Again we use the
|
||||
QTestEventList::addKeyClick() to add the events to the list, and
|
||||
QTest::newRow() to put the event list and the expected
|
||||
result into the table with an associated name.
|
||||
|
||||
\section1 Rewriting the Test Function
|
||||
|
||||
Our test can now be rewritten:
|
||||
|
||||
\snippet tutorial4/testgui.cpp 2
|
||||
|
||||
The TestGui::testGui() function will be executed two times,
|
||||
once for each entry in the test data that we created in the
|
||||
associated TestGui::testGui_data() function.
|
||||
|
||||
First, we fetch the two elements of the data set using the \l
|
||||
QFETCH() macro. \l QFETCH() takes two arguments: the data type of
|
||||
the element and the element name. Then we create a QLineEdit, and
|
||||
apply the list of events on that widget using the
|
||||
QTestEventList::simulate() function.
|
||||
|
||||
Finally, we use the QCOMPARE() macro to check if the line edit's
|
||||
text is as expected.
|
||||
|
||||
\section1 Preparing the Stand-Alone Executable
|
||||
|
||||
As before, to make our test case a stand-alone executable,
|
||||
the following two lines are needed:
|
||||
|
||||
\snippet tutorial4/testgui.cpp 3
|
||||
|
||||
The QTEST_MAIN() macro expands to a simple main() method that
|
||||
runs all the test functions, and since both the declaration and
|
||||
the implementation of our test class are in a .cpp file, we also
|
||||
need to include the generated moc file to make Qt's introspection
|
||||
work.
|
||||
|
||||
\section1 Building the Executable
|
||||
|
||||
\include {building-examples.qdocinc} {building the executable} {tutorial4}
|
||||
|
||||
\section1 Running the Executable
|
||||
|
||||
Running the resulting executable should give you the following
|
||||
output:
|
||||
|
||||
\snippet code/doc_src_qtestlib.qdoc 13
|
||||
*/
|
57
src/testlib/doc/src/qttestlib-tutorial5.qdoc
Normal file
57
src/testlib/doc/src/qttestlib-tutorial5.qdoc
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// Copyright (C) 2016 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\page qttestlib-tutorial5-example.html
|
||||
\previouspage {Chapter 4: Replaying GUI Events}{Chapter 4}
|
||||
\nextpage {Chapter 6: Skipping Tests with QSKIP}{Chapter 6}
|
||||
|
||||
\title Chapter 5: Writing a Benchmark
|
||||
\brief How to write a benchmark.
|
||||
|
||||
This chapter demonstrates how to write benchmarks using Qt Test.
|
||||
|
||||
\section1 Writing a Benchmark
|
||||
To create a benchmark we extend a test function with a QBENCHMARK macro.
|
||||
A benchmark test function will then typically consist of setup code and
|
||||
a QBENCHMARK macro that contains the code to be measured. This test
|
||||
function benchmarks QString::localeAwareCompare().
|
||||
|
||||
\snippet tutorial5/benchmarking.cpp 0
|
||||
|
||||
Setup can be done at the beginning of the function. At this point, the clock
|
||||
is not running. The code inside the QBENCHMARK macro will be
|
||||
measured, and possibly repeated several times in order to get an
|
||||
accurate measurement.
|
||||
|
||||
Several \l {testlib-benchmarking-measurement}{back-ends} are available
|
||||
and can be selected on the command line.
|
||||
|
||||
\section1 Data Functions
|
||||
|
||||
Data functions are useful for creating benchmarks that compare
|
||||
multiple data inputs, for example locale aware compare against standard
|
||||
compare.
|
||||
|
||||
\snippet tutorial5/benchmarking.cpp 1
|
||||
|
||||
The test function then uses the data to determine what to benchmark.
|
||||
|
||||
\snippet tutorial5/benchmarking.cpp 2
|
||||
|
||||
The \c{if (useLocaleCompare)} switch is placed outside the QBENCHMARK
|
||||
macro to avoid measuring its overhead. Each benchmark test function
|
||||
can have one active QBENCHMARK macro.
|
||||
|
||||
\section1 Building the Executable
|
||||
|
||||
\include {building-examples.qdocinc} {building the executable} {tutorial5}
|
||||
|
||||
\section1 Running the Executable
|
||||
|
||||
Running the resulting executable should give you the following
|
||||
output:
|
||||
|
||||
\snippet code/doc_src_qtestlib.qdoc 14
|
||||
*/
|
48
src/testlib/doc/src/qttestlib-tutorial6.qdoc
Normal file
48
src/testlib/doc/src/qttestlib-tutorial6.qdoc
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// Copyright (C) 2016 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\page qttestlib-tutorial6.html
|
||||
|
||||
\previouspage {Chapter 5: Writing a Benchmark}{Chapter 5}
|
||||
|
||||
\title Chapter 6: Skipping Tests with QSKIP
|
||||
\brief How to skip tests in certain cases.
|
||||
|
||||
\section2 Using QSKIP(\a description) in a test function
|
||||
|
||||
If the QSKIP() macro is called from a test function, it stops
|
||||
the execution of the test without adding a failure to the test log.
|
||||
It can be used to skip tests that are certain to fail. The text in
|
||||
the QSKIP \a description parameter is appended to the test log,
|
||||
and should explain why the test was not carried out.
|
||||
|
||||
QSKIP can be used to skip testing when the implementation is not yet
|
||||
complete or not supported on a certain platform. When there are known
|
||||
failures, QEXPECT_FAIL is recommended, as it supports running the rest
|
||||
of the test, when possible.
|
||||
|
||||
Example of QSKIP in a test function:
|
||||
|
||||
\snippet code/doc_src_qtqskip_snippet.cpp 0
|
||||
|
||||
In a data-driven test, each call to QSKIP() skips only the current
|
||||
row of test data. If the data-driven test contains an unconditional
|
||||
call to QSKIP, it produces a skip message for each row of test data.
|
||||
|
||||
\section2 Using QSKIP in a _data function
|
||||
|
||||
If called from a _data function, the QSKIP() macro stops
|
||||
execution of the _data function. This prevents execution of the
|
||||
associated test function.
|
||||
|
||||
See below for an example:
|
||||
|
||||
\snippet code/doc_src_qtqskip.cpp 1
|
||||
|
||||
\section2 Using QSKIP from initTestCase() or initTestCase_data()
|
||||
|
||||
If called from \c initTestCase() or \c initTestCase_data(), the
|
||||
QSKIP() macro will skip all test and _data functions.
|
||||
*/
|
Loading…
x
Reference in New Issue
Block a user