From 3873bcf2a494d74de108c14df110f6b356a422cb Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Wed, 18 Jan 2023 08:15:08 +0100 Subject: [PATCH] AutoTest: Add option to disable derived checks Previously the quick test parser would always check each symbol its interested in to see if it might be derived from "TestCase". This is very expensive. This patch adds an option allowing the user to enable or disable the check. By default the check is disabled. Change-Id: Ia6b230b344add672e53ad7fb52845c78a2914b99 Reviewed-by: Christian Stenger --- .../howto/creator-only/creator-autotest.qdoc | 5 +++++ src/plugins/autotest/autotestunittests.cpp | 9 ++++++++ src/plugins/autotest/qtest/qttestsettings.cpp | 10 +++++++++ src/plugins/autotest/qtest/qttestsettings.h | 1 + .../autotest/quick/quicktestparser.cpp | 22 +++++++++++++++---- src/plugins/autotest/quick/quicktestparser.h | 4 +++- .../autotest/quick/quicktestvisitors.cpp | 9 ++++++-- .../autotest/quick/quicktestvisitors.h | 5 ++++- 8 files changed, 57 insertions(+), 8 deletions(-) diff --git a/doc/qtcreator/src/howto/creator-only/creator-autotest.qdoc b/doc/qtcreator/src/howto/creator-only/creator-autotest.qdoc index 336b1d29d3f..346e7a0000b 100644 --- a/doc/qtcreator/src/howto/creator-only/creator-autotest.qdoc +++ b/doc/qtcreator/src/howto/creator-only/creator-autotest.qdoc @@ -463,6 +463,11 @@ inside the spin box next to it. Set the number to 0 if you want no limit at all. The default number is 2000. + To check for Qt Quick Tests that are derived from TestCase select the + \uicontrol {Check for derived Qt Quick tests} check box. + Note: this feature is rather expensive and will increase the + scan time significantly. + \section2 Specifying Settings for Running Google Tests To specify settings for running Google tests, select \uicontrol Edit > diff --git a/src/plugins/autotest/autotestunittests.cpp b/src/plugins/autotest/autotestunittests.cpp index 52f4f5513f4..d655280d306 100644 --- a/src/plugins/autotest/autotestunittests.cpp +++ b/src/plugins/autotest/autotestunittests.cpp @@ -4,8 +4,11 @@ #include "autotestunittests.h" #include "testcodeparser.h" +#include "testframeworkmanager.h" #include "testtreemodel.h" +#include "qtest/qttestsettings.h" + #include #include #include @@ -72,6 +75,12 @@ void AutoTestUnitTests::initTestCase() m_checkBoost = true; } } + + // Enable quick check for derived tests + static const Utils::Id id = Utils::Id("AutoTest.Framework.QtTest"); + static_cast( + TestFrameworkManager::frameworkForId(id)->testSettings()) + ->quickCheckForDerivedTests.setValue(true); } void AutoTestUnitTests::cleanupTestCase() diff --git a/src/plugins/autotest/qtest/qttestsettings.cpp b/src/plugins/autotest/qtest/qttestsettings.cpp index 0feeeede2fe..b16d991726a 100644 --- a/src/plugins/autotest/qtest/qttestsettings.cpp +++ b/src/plugins/autotest/qtest/qttestsettings.cpp @@ -72,6 +72,14 @@ QtTestSettings::QtTestSettings() maxWarnings.setDefaultValue(2000); maxWarnings.setSpecialValueText(Tr::tr("Unlimited")); maxWarnings.setEnabler(&limitWarnings); + + registerAspect(&quickCheckForDerivedTests); + quickCheckForDerivedTests.setSettingsKey("QuickCheckForDerivedTests"); + quickCheckForDerivedTests.setDefaultValue(false); + quickCheckForDerivedTests.setLabelText(Tr::tr("Check for derived Qt Quick tests")); + quickCheckForDerivedTests.setToolTip( + Tr::tr("Search for Qt Quick tests that are derived from TestCase.\nWarning: Enabling this " + "feature significantly increases scan time.")); } QString QtTestSettings::metricsTypeToOption(const MetricsType type) @@ -114,6 +122,8 @@ QtTestSettingsPage::QtTestSettingsPage(QtTestSettings *settings, Id settingsId) title(Tr::tr("Benchmark Metrics")), Column { s.metrics } }, + br, + s.quickCheckForDerivedTests, }; Column { Row { col, st }, st }.attachTo(widget); diff --git a/src/plugins/autotest/qtest/qttestsettings.h b/src/plugins/autotest/qtest/qttestsettings.h index c628cd4a59f..4bbec4332df 100644 --- a/src/plugins/autotest/qtest/qttestsettings.h +++ b/src/plugins/autotest/qtest/qttestsettings.h @@ -33,6 +33,7 @@ public: Utils::BoolAspect logSignalsSlots; Utils::BoolAspect limitWarnings; Utils::IntegerAspect maxWarnings; + Utils::BoolAspect quickCheckForDerivedTests; }; class QtTestSettingsPage final : public Core::IOptionsPage diff --git a/src/plugins/autotest/quick/quicktestparser.cpp b/src/plugins/autotest/quick/quicktestparser.cpp index 5c50034623b..c5f0524a53e 100644 --- a/src/plugins/autotest/quick/quicktestparser.cpp +++ b/src/plugins/autotest/quick/quicktestparser.cpp @@ -8,6 +8,7 @@ #include "quicktest_utils.h" #include "../testcodeparser.h" #include "../testtreemodel.h" +#include "../qtest/qttestsettings.h" #include #include @@ -201,14 +202,15 @@ QList QuickTestParser::scanDirectoryForQuickTestQmlFiles(const Ut static bool checkQmlDocumentForQuickTestCode(QFutureInterface &futureInterface, const Document::Ptr &qmlJSDoc, ITestFramework *framework, - const Utils::FilePath &proFile = Utils::FilePath()) + const Utils::FilePath &proFile = Utils::FilePath(), + bool checkForDerivedTest = false) { if (qmlJSDoc.isNull()) return false; AST::Node *ast = qmlJSDoc->ast(); QTC_ASSERT(ast, return false); Snapshot snapshot = ModelManagerInterface::instance()->snapshot(); - TestQmlVisitor qmlVisitor(qmlJSDoc, snapshot); + TestQmlVisitor qmlVisitor(qmlJSDoc, snapshot, checkForDerivedTest); AST::Node::accept(ast, &qmlVisitor); if (!qmlVisitor.isValid()) return false; @@ -272,7 +274,11 @@ bool QuickTestParser::handleQtQuickTest(QFutureInterface &fu for (const Document::Ptr &qmlJSDoc : qmlDocs) { if (futureInterface.isCanceled()) break; - result |= checkQmlDocumentForQuickTestCode(futureInterface, qmlJSDoc, framework, proFile); + result |= checkQmlDocumentForQuickTestCode(futureInterface, + qmlJSDoc, + framework, + proFile, + m_checkForDerivedTests); } return result; } @@ -354,6 +360,10 @@ void QuickTestParser::init(const Utils::FilePaths &filesToParse, bool fullParse) // get rid of all cached main cpp files m_mainCppFiles.clear(); } + + auto qtSettings = static_cast(framework()->testSettings()); + m_checkForDerivedTests = qtSettings->quickCheckForDerivedTests.value(); + CppParser::init(filesToParse, fullParse); } @@ -372,7 +382,11 @@ bool QuickTestParser::processDocument(QFutureInterface &futu if (proFile.isEmpty()) return false; Document::Ptr qmlJSDoc = m_qmlSnapshot.document(fileName); - return checkQmlDocumentForQuickTestCode(futureInterface, qmlJSDoc, framework(), proFile); + return checkQmlDocumentForQuickTestCode(futureInterface, + qmlJSDoc, + framework(), + proFile, + m_checkForDerivedTests); } CPlusPlus::Document::Ptr cppdoc = document(fileName); diff --git a/src/plugins/autotest/quick/quicktestparser.h b/src/plugins/autotest/quick/quicktestparser.h index 7fd579005bb..c0fbc5a3e83 100644 --- a/src/plugins/autotest/quick/quicktestparser.h +++ b/src/plugins/autotest/quick/quicktestparser.h @@ -33,7 +33,8 @@ public: private: bool handleQtQuickTest(QFutureInterface &futureInterface, - CPlusPlus::Document::Ptr document, ITestFramework *framework); + CPlusPlus::Document::Ptr document, + ITestFramework *framework); void handleDirectoryChanged(const QString &directory); void doUpdateWatchPaths(const QStringList &directories); QString quickTestName(const CPlusPlus::Document::Ptr &doc) const; @@ -43,6 +44,7 @@ private: QFileSystemWatcher m_directoryWatcher; QMap > m_watchedFiles; QMap m_mainCppFiles; + bool m_checkForDerivedTests = false; }; } // namespace Internal diff --git a/src/plugins/autotest/quick/quicktestvisitors.cpp b/src/plugins/autotest/quick/quicktestvisitors.cpp index 0f8277121e3..158f37db839 100644 --- a/src/plugins/autotest/quick/quicktestvisitors.cpp +++ b/src/plugins/autotest/quick/quicktestvisitors.cpp @@ -18,9 +18,12 @@ namespace Internal { static QStringList specialFunctions({"initTestCase", "cleanupTestCase", "init", "cleanup"}); -TestQmlVisitor::TestQmlVisitor(QmlJS::Document::Ptr doc, const QmlJS::Snapshot &snapshot) +TestQmlVisitor::TestQmlVisitor(QmlJS::Document::Ptr doc, + const QmlJS::Snapshot &snapshot, + bool checkForDerivedTest) : m_currentDoc(doc) , m_snapshot(snapshot) + , m_checkForDerivedTest(checkForDerivedTest) { } @@ -68,8 +71,10 @@ bool TestQmlVisitor::visit(QmlJS::AST::UiObjectDefinition *ast) const QStringView name = ast->qualifiedTypeNameId->name; m_objectIsTestStack.push(false); if (name != QLatin1String("TestCase")) { - if (!isDerivedFromTestCase(ast->qualifiedTypeNameId, m_currentDoc, m_snapshot)) + if (!m_checkForDerivedTest + || !isDerivedFromTestCase(ast->qualifiedTypeNameId, m_currentDoc, m_snapshot)) { return true; + } } else if (!documentImportsQtTest(m_currentDoc.data())) { return true; // find nested TestCase items as well } diff --git a/src/plugins/autotest/quick/quicktestvisitors.h b/src/plugins/autotest/quick/quicktestvisitors.h index db776d843c0..71d4b91496f 100644 --- a/src/plugins/autotest/quick/quicktestvisitors.h +++ b/src/plugins/autotest/quick/quicktestvisitors.h @@ -26,7 +26,9 @@ public: class TestQmlVisitor : public QmlJS::AST::Visitor { public: - explicit TestQmlVisitor(QmlJS::Document::Ptr doc, const QmlJS::Snapshot &snapshot); + TestQmlVisitor(QmlJS::Document::Ptr doc, + const QmlJS::Snapshot &snapshot, + bool checkForDerivedTest); bool visit(QmlJS::AST::UiObjectDefinition *ast) override; void endVisit(QmlJS::AST::UiObjectDefinition *ast) override; @@ -48,6 +50,7 @@ private: QVector m_testCases; QStack m_objectIsTestStack; bool m_expectTestCaseName = false; + bool m_checkForDerivedTest = false; }; class QuickTestAstVisitor : public CPlusPlus::ASTVisitor