summaryrefslogtreecommitdiffstats
path: root/src/testlib/doc
diff options
context:
space:
mode:
Diffstat (limited to 'src/testlib/doc')
-rw-r--r--src/testlib/doc/qttestlib.qdocconf2
-rw-r--r--src/testlib/doc/snippets/CMakeLists.txt2
-rw-r--r--src/testlib/doc/snippets/code/CMakeLists.txt3
-rw-r--r--src/testlib/doc/snippets/code/doc_src_cmakelists.txt2
-rw-r--r--src/testlib/doc/snippets/code/doc_src_qsignalspy.cpp3
-rw-r--r--src/testlib/doc/snippets/code/doc_src_qtestlib.qdoc2
-rw-r--r--src/testlib/doc/snippets/code/doc_src_qttest.cpp6
-rw-r--r--src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp20
-rw-r--r--src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core_snippet.cpp10
-rw-r--r--src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp5
-rw-r--r--src/testlib/doc/src/qt6-changes.qdoc2
-rw-r--r--src/testlib/doc/src/qttest-best-practices.qdoc21
-rw-r--r--src/testlib/doc/src/qttestlib-manual.qdoc488
-rw-r--r--src/testlib/doc/src/qttestlib-tutorial1.qdoc76
-rw-r--r--src/testlib/doc/src/qttestlib-tutorial2.qdoc132
-rw-r--r--src/testlib/doc/src/qttestlib-tutorial3.qdoc75
-rw-r--r--src/testlib/doc/src/qttestlib-tutorial4.qdoc95
-rw-r--r--src/testlib/doc/src/qttestlib-tutorial5.qdoc57
-rw-r--r--src/testlib/doc/src/qttestlib-tutorial6.qdoc50
19 files changed, 540 insertions, 511 deletions
diff --git a/src/testlib/doc/qttestlib.qdocconf b/src/testlib/doc/qttestlib.qdocconf
index 4330fe197a..8b245a864f 100644
--- a/src/testlib/doc/qttestlib.qdocconf
+++ b/src/testlib/doc/qttestlib.qdocconf
@@ -56,5 +56,5 @@ manifestmeta.thumbnail.names = "QtTestLib/Chapter *"
navigation.landingpage = "Qt Test"
navigation.cppclassespage = "Qt Test C++ Classes"
-# Fail the documentation build if there are more warnings than the limit
+# Enforce zero documentation warnings
warninglimit = 0
diff --git a/src/testlib/doc/snippets/CMakeLists.txt b/src/testlib/doc/snippets/CMakeLists.txt
index 0982732843..77e4781c44 100644
--- a/src/testlib/doc/snippets/CMakeLists.txt
+++ b/src/testlib/doc/snippets/CMakeLists.txt
@@ -1,5 +1,5 @@
# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#! [cmake_use]
find_package(Qt6 REQUIRED COMPONENTS Test)
diff --git a/src/testlib/doc/snippets/code/CMakeLists.txt b/src/testlib/doc/snippets/code/CMakeLists.txt
index 86057acde2..54c655a521 100644
--- a/src/testlib/doc/snippets/code/CMakeLists.txt
+++ b/src/testlib/doc/snippets/code/CMakeLists.txt
@@ -1,9 +1,8 @@
# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
add_library(testlib_code_snippets OBJECT
doc_src_qtqskip.cpp
- doc_src_qttest.cpp
src_corelib_kernel_qtestsupport_core.cpp
)
diff --git a/src/testlib/doc/snippets/code/doc_src_cmakelists.txt b/src/testlib/doc/snippets/code/doc_src_cmakelists.txt
index 6e19597775..946f09c09f 100644
--- a/src/testlib/doc/snippets/code/doc_src_cmakelists.txt
+++ b/src/testlib/doc/snippets/code/doc_src_cmakelists.txt
@@ -8,7 +8,7 @@ set(CMAKE_AUTOMOC ON)
enable_testing(true)
-add_executable(mytest tst_mytest.cpp)
+qt_add_executable(mytest tst_mytest.cpp)
add_test(NAME mytest COMMAND mytest)
target_link_libraries(mytest PRIVATE Qt::Test)
diff --git a/src/testlib/doc/snippets/code/doc_src_qsignalspy.cpp b/src/testlib/doc/snippets/code/doc_src_qsignalspy.cpp
index 20459f9eb4..99760ea730 100644
--- a/src/testlib/doc/snippets/code/doc_src_qsignalspy.cpp
+++ b/src/testlib/doc/snippets/code/doc_src_qsignalspy.cpp
@@ -43,9 +43,6 @@ SomeStruct result = qvariant_cast<SomeStruct>(spy.at(0).at(0));
QSignalSpy spy(myPushButton, SIGNAL(clicked(bool)));
//! [4]
-//! [5]
-QVERIFY(spy.wait(1000));
-//! [5]
//! [6]
QSignalSpy spy(myPushButton, &QPushButton::clicked);
diff --git a/src/testlib/doc/snippets/code/doc_src_qtestlib.qdoc b/src/testlib/doc/snippets/code/doc_src_qtestlib.qdoc
index 10d9cb5bee..9b592bdb6a 100644
--- a/src/testlib/doc/snippets/code/doc_src_qtestlib.qdoc
+++ b/src/testlib/doc/snippets/code/doc_src_qtestlib.qdoc
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
//! [2]
testname [options] [testfunctions[:testdata]]...
diff --git a/src/testlib/doc/snippets/code/doc_src_qttest.cpp b/src/testlib/doc/snippets/code/doc_src_qttest.cpp
deleted file mode 100644
index 06b4588268..0000000000
--- a/src/testlib/doc/snippets/code/doc_src_qttest.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-//! [0]
-#include <QTest>
-//! [0]
diff --git a/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp b/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp
index 906a88b20f..7faf40d9b7 100644
--- a/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp
+++ b/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp
@@ -5,8 +5,9 @@
// dummy class
class MyObject
{
- public:
- int isReady();
+public:
+ int isReady();
+ void startup() {}
};
// dummy function
@@ -18,9 +19,22 @@ int myNetworkServerNotResponding()
int MyObject::isReady()
{
//! [1]
+ using namespace std::chrono_literals;
int i = 0;
while (myNetworkServerNotResponding() && i++ < 50)
- QTest::qWait(250);
+ QTest::qWait(250ms);
//! [1]
return 1;
}
+
+[[maybe_unused]] static bool startup()
+{
+//! [2]
+ MyObject obj;
+ obj.startup();
+ using namespace std::chrono_literals;
+ const bool result = QTest::qWaitFor([&obj]() { return obj.isReady(); },
+ QDeadlineTimer(3s));
+//! [2]
+ return result;
+}
diff --git a/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core_snippet.cpp b/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core_snippet.cpp
deleted file mode 100644
index f2ba321a67..0000000000
--- a/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core_snippet.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-//! [0]
- MyObject obj;
- obj.startup();
- QTest::qWaitFor([&]() {
- return obj.isReady();
- }, 3000);
-//! [0]
diff --git a/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp b/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp
index 532b26b4f1..4716d06e55 100644
--- a/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp
+++ b/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp
@@ -170,10 +170,11 @@ void MyTestClass::cleanup()
}
//! [22]
-void mySleep()
+void quarterSecondSleep()
{
//! [23]
-QTest::qSleep(250);
+using namespace std::chrono_literals;
+QTest::qSleep(250ms);
//! [23]
}
diff --git a/src/testlib/doc/src/qt6-changes.qdoc b/src/testlib/doc/src/qt6-changes.qdoc
index 03a5c8db03..77e7b04afd 100644
--- a/src/testlib/doc/src/qt6-changes.qdoc
+++ b/src/testlib/doc/src/qt6-changes.qdoc
@@ -5,7 +5,7 @@
\page testlib-changes-qt6.html
\title Changes to Qt Test
\ingroup changes-qt-5-to-6
- \brief Migrate Qt Test to Qt 6.
+ \brief Touch-related functionality changes.
Qt 6 is a result of the conscious effort to make the framework more
efficient and easy to use.
diff --git a/src/testlib/doc/src/qttest-best-practices.qdoc b/src/testlib/doc/src/qttest-best-practices.qdoc
index 54a51f4ace..cea5b3a8de 100644
--- a/src/testlib/doc/src/qttest-best-practices.qdoc
+++ b/src/testlib/doc/src/qttest-best-practices.qdoc
@@ -180,14 +180,19 @@
\section2 Select Appropriate Mechanisms to Exclude Tests
It is important to select the appropriate mechanism to exclude inapplicable
- tests: \l QSKIP(), using conditional statements to exclude parts of a test
- function, or not building the test for a particular platform.
-
- Use QSKIP() to handle cases where a whole test function is found at run-time
- to be inapplicable in the current test environment. When just a part of a
- test function is to be skipped, a conditional statement can be used,
- optionally with a \c qDebug() call to report the reason for skipping the
- inapplicable part.
+ tests.
+
+ Use \l QSKIP() to handle cases where a whole test function is found at
+ run-time to be inapplicable in the current test environment. When just a
+ part of a test function is to be skipped, a conditional statement can be
+ used, optionally with a \c qDebug() call to report the reason for skipping
+ the inapplicable part.
+
+ When there are known test failures that should eventually be fixed,
+ \l QEXPECT_FAIL is recommended, as it supports running the rest of the
+ test, when possible. It also verifies that the issue still exists, and
+ lets the code's maintainer know if they unwittingly fix it, a benefit
+ which is gained even when using the \l {QTest::}{Abort} flag.
Test functions or data rows of a data-driven test can be limited to
particular platforms, or to particular features being enabled using
diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc
index 2d89693d35..1b6f534045 100644
--- a/src/testlib/doc/src/qttestlib-manual.qdoc
+++ b/src/testlib/doc/src/qttestlib-manual.qdoc
@@ -348,6 +348,16 @@
Disables the crash handler on Unix platforms.
On Windows, it re-enables the Windows Error Reporting dialog, which is
turned off by default. This is useful for debugging crashes.
+ \li \c -repeat \e n \br
+ Run the testsuite n times or until the test fails. Useful for finding
+ flaky tests. If negative, the tests are repeated forever. This is intended
+ as a developer tool, and is only supported with the plain text logger.
+ \li \c -skipblacklisted \br
+ Skip the blacklisted tests. This option is intended to allow more accurate
+ measurement of test coverage by preventing blacklisted tests from inflating
+ coverage statistics. When not measuring test coverage, it is recommended to
+ execute blacklisted tests to reveal any changes in their results, such as
+ a new crash or the issue that caused blacklisting being resolved.
\li \c -platform \e name \br
This command line argument applies to all Qt applications, but might be
@@ -405,6 +415,12 @@
to e.g. debug an unstable or intermittent failure in a test, by
launching the test in a debugger. Support for this variable was
added in Qt 6.1.
+ \li \c QTEST_THROW_ON_FAIL (since 6.8) \br
+ Setting this variable to a non-zero value will cause QCOMPARE()/QVERIFY()
+ etc to throw on failure (as opposed to just returning from the
+ immediately-surrounding function scope).
+ \li \c QTEST_THROW_ON_SKIP (since 6.8) \br
+ Same as \c QTEST_THROW_ON_FAIL, except affecting QSKIP().
\endlist
\section1 Creating a Benchmark
@@ -573,477 +589,5 @@
\li \l {Chapter 6: Skipping Tests with QSKIP}{Skipping Tests}
\endlist
- \note You can build and execute the tests from each chapter using the
- 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 Howe 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 final 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.
-*/
diff --git a/src/testlib/doc/src/qttestlib-tutorial1.qdoc b/src/testlib/doc/src/qttestlib-tutorial1.qdoc
new file mode 100644
index 0000000000..41d9264c0d
--- /dev/null
+++ b/src/testlib/doc/src/qttestlib-tutorial1.qdoc
@@ -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.
+*/
diff --git a/src/testlib/doc/src/qttestlib-tutorial2.qdoc b/src/testlib/doc/src/qttestlib-tutorial2.qdoc
new file mode 100644
index 0000000000..bd828b3963
--- /dev/null
+++ b/src/testlib/doc/src/qttestlib-tutorial2.qdoc
@@ -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
+*/
diff --git a/src/testlib/doc/src/qttestlib-tutorial3.qdoc b/src/testlib/doc/src/qttestlib-tutorial3.qdoc
new file mode 100644
index 0000000000..2b7fe25c96
--- /dev/null
+++ b/src/testlib/doc/src/qttestlib-tutorial3.qdoc
@@ -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
+*/
diff --git a/src/testlib/doc/src/qttestlib-tutorial4.qdoc b/src/testlib/doc/src/qttestlib-tutorial4.qdoc
new file mode 100644
index 0000000000..d5a0121f67
--- /dev/null
+++ b/src/testlib/doc/src/qttestlib-tutorial4.qdoc
@@ -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
+*/
diff --git a/src/testlib/doc/src/qttestlib-tutorial5.qdoc b/src/testlib/doc/src/qttestlib-tutorial5.qdoc
new file mode 100644
index 0000000000..7569019b4e
--- /dev/null
+++ b/src/testlib/doc/src/qttestlib-tutorial5.qdoc
@@ -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
+*/
diff --git a/src/testlib/doc/src/qttestlib-tutorial6.qdoc b/src/testlib/doc/src/qttestlib-tutorial6.qdoc
new file mode 100644
index 0000000000..602ca0b28e
--- /dev/null
+++ b/src/testlib/doc/src/qttestlib-tutorial6.qdoc
@@ -0,0 +1,50 @@
+// 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 \l 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, \l 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.
+
+ \sa {Select Appropriate Mechanisms to Exclude Tests}
+*/