From 2e12825b0b4457d709d6d467c84f30ce35336ff3 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 2 Oct 2019 13:22:39 +0200 Subject: Doc: Describe initTestCase_data() function and QFETCH_GLOBAL macro Fixes: QTBUG-24342 Change-Id: I8f8f3726c5d31e34af9bfe054572c08fc07e01e0 Reviewed-by: Edward Welbourne --- .../doc/snippets/code/src_qtestlib_qtestcase.cpp | 30 ++++++++++++- src/testlib/doc/src/qttestlib-manual.qdoc | 49 ++++++++++++++++++---- src/testlib/qtestcase.qdoc | 33 +++++++++++++-- 3 files changed, 100 insertions(+), 12 deletions(-) diff --git a/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp b/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp index 202f87af52..5f71828595 100644 --- a/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp +++ b/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -296,3 +296,31 @@ QTest::keyClick(myWindow, Qt::Key_Escape, Qt::ShiftModifier, 200); } +//! [30] +void TestQLocale::initTestCase_data() +{ + QTest::addColumn("locale"); + QTest::newRow("C") << QLocale::c(); + QTest::newRow("UKish") << QLocale("en_GB"); + QTest::newRow("USAish") << QLocale(QLocale::English); +} + +void TestQLocale::roundTripInt_data() +{ + QTest::addColumn("number"); + QTest::newRow("one") << 1; + QTest::newRow("two") << 2; + QTest::newRow("ten") << 10; +} +//! [30] + +//! [31] +void TestQLocale::roundTripInt() +{ + QFETCH_GLOBAL(QLocale, locale); + QFETCH(int, number); + bool ok; + QCOMPARE(locale.toInt(locale.toString(number), &ok), number); + QVERIFY(ok); +} +//! [31] diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc index 71b4541313..a3644c1623 100644 --- a/src/testlib/doc/src/qttestlib-manual.qdoc +++ b/src/testlib/doc/src/qttestlib-manual.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** @@ -89,12 +89,14 @@ private slot is a test function in your test. QTest::qExec() can be used to execute all test functions in the test object. - In addition, there are four private slots that are \e not treated as test functions. - They will be executed by the testing framework and can be used to initialize and - clean up either the entire test or the current test function. + In addition, you can define the following private slots that are \e not + treated as test functions. When present, they will be executed by the + testing framework and can be used to initialize and clean up either the + entire test or the current test function. \list \li \c{initTestCase()} will be called before the first test function is executed. + \li \c{initTestCase_data()} will be called to create a global test data table. \li \c{cleanupTestCase()} will be called after the last test function was executed. \li \c{init()} will be called before each test function is executed. \li \c{cleanup()} will be called after every test function. @@ -365,6 +367,34 @@ See \l {Chapter 5: Writing a Benchmark}{Writing a Benchmark} in the Qt Test Tutorial for more benchmarking examples. + + \section1 Using Global Test Data + + You can define \c{initTestCase_data()} to set up a global test data table. + Each test is run once for each row in the global test data table. When the + test function itself \l{Chapter 2: Data-driven Testing}{is data-driven}, + it is run for each local data row, for each global data row. So, if there + are \c g rows in the global data table and \c d rows in the test's own + data-table, the number of runs of this test is \c g times \c d. + + Global data is fetched from the table using the \l QFETCH_GLOBAL() macro. + + The following are typical use cases for global test data: + + \list + \li Selecting among the available database backends in QSql tests to run + every test against every database. + \li Doing all networking tests with and without SSL (HTTP versus HTTPS) + and proxying. + \li Testing a timer with a high precision clock and with a coarse one. + \li Selecting whether a parser shall read from a QByteArray or from a + QIODevice. + \endlist + + For example, to test each number provided by \c {roundTripInt_data()} with + each locale provided by \c {initTestCase_data()}: + + \snippet code/src_qtestlib_qtestcase.cpp 31 */ /*! @@ -508,10 +538,9 @@ QTest::newRow() function. Each set 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. If the test fails, the name will be - used in the test log, referencing the failed data. Then we - stream the data set into the new table row. First an arbitrary + \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 set. + 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. @@ -543,6 +572,10 @@ \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. + \section1 Rewriting the Test Function Our test function can now be rewritten: diff --git a/src/testlib/qtestcase.qdoc b/src/testlib/qtestcase.qdoc index 2af016304d..f3761cdfa8 100644 --- a/src/testlib/qtestcase.qdoc +++ b/src/testlib/qtestcase.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -220,8 +220,8 @@ \relates QTest The fetch macro creates a local variable named \a name with the type \a type - on the stack. \a name has to match the element name from the test's data. - If no such element exists, the test will assert. + on the stack. The \a name and \a type must match a column from the test's + data table. This is asserted and the test will abort if the assertion fails. Assuming a test has the following data: @@ -239,6 +239,33 @@ by the test framework. The test function must have a _data function. */ +/*! \macro QFETCH_GLOBAL(type, name) + + \relates QTest + + This macro fetches a variable named \a name with the type \a type from + a row in the global data table. The \a name and \a type must match a + column in the global data table. This is asserted and the test will abort + if the assertion fails. + + Assuming a test has the following data: + + \snippet code/src_qtestlib_qtestcase.cpp 30 + + The test's own data is a single number per row. In this case, + \c initTestCase_data() also supplies a locale per row. Therefore, + this test will be run with every combination of locale from the + latter and number from the former. + + \snippet code/src_qtestlib_qtestcase.cpp 31 + + The locale is read from the global data table using QFETCH_GLOBAL(), + and the number is read from the local data table using QFETCH(). + + \note This macro can only be used in test methods of a class with an + \c initTestCase_data() method. +*/ + /*! \macro QWARN(message) \relates QTest -- cgit v1.2.3