summaryrefslogtreecommitdiffstats
path: root/src/testlib/qtestcase.cpp
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2022-06-03 09:27:27 +0200
committerMarc Mutz <marc.mutz@qt.io>2022-06-03 20:37:51 +0000
commit0681a2dd5a8095baddb5905fb21a58ce19b958c5 (patch)
treee9a8a67e50f817e3f48cebd5294fa4a96bee8945 /src/testlib/qtestcase.cpp
parent1e36eedb7f6d312f439aa3d1b1529e7fd672d81a (diff)
QTestLib: rework QTest::compare_helper()
[ChangeLog][QTestLib] QCOMPARE now evaluates toString() on its arguments lazily, speeding up the general case where the comparison doesn't fail. This is true for the QCOMPARE functionality provided by Qt. If you specialized qCompare() for your own types, then you need to change its implementation in line with Qt's own qCompare() specializations in order to enable this feature. [ChangeLog][QTestLib] QCOMPARE calls with nullptr argument(s) will now print the actual and expected values upon failure. Previously it was not like that because of the compareHelper() overload in qtestresult.cpp that treated the presence of nullptr-arguments as a reason to ignore formatFailMessage() call. New implementation does not have this check, and correctly executes formatFailMessage() for all arguments. Note that the qCompare() overloads that call QTestResult::compare() internally were not affected by this patch, because they already defer toString() invocation until the comparison fails. Some numbers, collected against shared release developer build. I checked how this change affects the test execution. The idea was to pick some tests for types that do not have a specific QTestResult::compare overload, so I picked a couple of QByteArray tests. The comparison is done by running a test 10 times and taking the average execution duration, as reported in the log. tst_qbytearrayapisymmetry: Before: 15.6 ms After: 14.2 ms tst_qbytearray: Before: 41 ms After: 36 ms The benefit is around 9% and 12% respectively. Fixes: QTBUG-98874 Change-Id: I7d59ddc760168b15974e7720930f629fb34efa13 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Diffstat (limited to 'src/testlib/qtestcase.cpp')
-rw-r--r--src/testlib/qtestcase.cpp62
1 files changed, 56 insertions, 6 deletions
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 919447cce3..7eeacccf39 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -2904,7 +2904,9 @@ void QTest::setMainSourcePath(const char *file, const char *builddir)
QTest::mainSourcePath = fi.absolutePath();
}
+#if QT_DEPRECATED_SINCE(6, 4)
/*! \internal
+ \deprecated [6.4]
This function is called by various specializations of QTest::qCompare
to decide whether to report a failure and to produce verbose test output.
@@ -2912,15 +2914,61 @@ void QTest::setMainSourcePath(const char *file, const char *builddir)
will be output if the compare fails. If the compare succeeds, failureMsg
will not be output.
- If the caller has already passed a failure message showing the compared
- values, or if those values cannot be stringified, val1 and val2 can be null.
+ Using this function is not optimal, because it requires the string
+ representations of \a actualVal and \a expectedVal to be pre-calculated,
+ even though they will be used only if the comparison fails. Prefer using the
+ \l compare_helper() overload that takes qxp::function_ref() for such cases.
+
+ If the caller creates a custom failure message showing the compared values,
+ or if those values cannot be stringified, use the overload of the function
+ that takes no \a actualVal and \a expecetedVal parameters.
*/
bool QTest::compare_helper(bool success, const char *failureMsg,
- char *val1, char *val2,
+ char *actualVal, char *expectedVal,
const char *actual, const char *expected,
const char *file, int line)
{
- return QTestResult::compare(success, failureMsg, val1, val2, actual, expected, file, line);
+ return QTestResult::compare(success, failureMsg, actualVal, expectedVal,
+ actual, expected, file, line);
+}
+#endif // QT_DEPRECATED_SINCE(6, 4)
+
+/*! \internal
+ This function is called by various specializations of QTest::qCompare
+ to decide whether to report a failure and to produce verbose test output.
+
+ The \a failureMsg parameter can be \c {nullptr}, in which case a default
+ message will be output if the compare fails. If the comparison succeeds,
+ \a failureMsg will not be output.
+
+ This overload of the function uses qxp::function_ref to defer conversion of
+ \a actualVal and \a expectedVal to strings until that is really needed
+ (when the comparison fails). This speeds up test case execution on success.
+*/
+bool QTest::compare_helper(bool success, const char *failureMsg,
+ qxp::function_ref<const char *()> actualVal,
+ qxp::function_ref<const char *()> expectedVal,
+ const char *actual, const char *expected,
+ const char *file, int line)
+{
+ return QTestResult::reportResult(success, actualVal, expectedVal, actual, expected,
+ QTest::ComparisonOperation::CustomCompare,
+ file, line, failureMsg);
+}
+
+/*! \internal
+ This function is called by various specializations of QTest::qCompare
+ to decide whether to report a failure and to produce verbose test output.
+
+ This overload should be used when there is no string representation of
+ actual and expected values, so only the \a failureMsg is shown when the
+ comparison fails. Because of that, \a failureMsg can't be \c {nullptr}.
+ If the comparison succeeds, \a failureMsg will not be output.
+*/
+bool QTest::compare_helper(bool success, const char *failureMsg, const char *actual,
+ const char *expected, const char *file, int line)
+{
+ return QTestResult::compare(success, failureMsg, actual, expected, file, line);
}
template <typename T>
@@ -2950,7 +2998,8 @@ bool QTest::qCompare(qfloat16 const &t1, qfloat16 const &t2, const char *actual,
{
return compare_helper(floatingCompare(t1, t2),
"Compared qfloat16s are not the same (fuzzy compare)",
- toString(t1), toString(t2), actual, expected, file, line);
+ [&t1] { return toString(t1); }, [&t2] { return toString(t2); },
+ actual, expected, file, line);
}
/*! \fn bool QTest::qCompare(const float &t1, const float &t2, const char *actual, const char *expected, const char *file, int line)
@@ -3272,7 +3321,8 @@ bool QTest::compare_string_helper(const char *t1, const char *t2, const char *ac
const char *expected, const char *file, int line)
{
return compare_helper(qstrcmp(t1, t2) == 0, "Compared strings are not the same",
- toString(t1), toString(t2), actual, expected, file, line);
+ [t1] { return toString(t1); }, [t2] { return toString(t2); },
+ actual, expected, file, line);
}
/*!