forked from qt-creator/qt-creator
AutoTest: Add minimum support for debugging tests
This adds another context menu entry for items on the test tree to allow debugging of a single test. Task-number: QTCREATORBUG-16070 Change-Id: I98f56b0f22c94ad71f0b91d690383043ed27f1c7 Reviewed-by: hjk <hjk@theqtcompany.com> Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
This commit is contained in:
@@ -91,7 +91,8 @@ HEADERS += \
|
|||||||
quick/quicktest_utils.h \
|
quick/quicktest_utils.h \
|
||||||
quick/quicktestvisitors.h \
|
quick/quicktestvisitors.h \
|
||||||
quick/quicktestframework.h \
|
quick/quicktestframework.h \
|
||||||
testframeworkmanager.h
|
testframeworkmanager.h \
|
||||||
|
testrunconfiguration.h
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
autotest.qrc
|
autotest.qrc
|
||||||
|
@@ -10,6 +10,7 @@ QtcPlugin {
|
|||||||
Depends { name: "QmlJS" }
|
Depends { name: "QmlJS" }
|
||||||
Depends { name: "QmlJSTools" }
|
Depends { name: "QmlJSTools" }
|
||||||
Depends { name: "Utils" }
|
Depends { name: "Utils" }
|
||||||
|
Depends { name: "Debugger" }
|
||||||
|
|
||||||
pluginTestDepends: [
|
pluginTestDepends: [
|
||||||
"QbsProjectManager",
|
"QbsProjectManager",
|
||||||
@@ -71,7 +72,8 @@ QtcPlugin {
|
|||||||
"itestparser.h",
|
"itestparser.h",
|
||||||
"itestframework.h",
|
"itestframework.h",
|
||||||
"testframeworkmanager.cpp",
|
"testframeworkmanager.cpp",
|
||||||
"testframeworkmanager.h"
|
"testframeworkmanager.h",
|
||||||
|
"testrunconfiguration.h"
|
||||||
]
|
]
|
||||||
|
|
||||||
Group {
|
Group {
|
||||||
|
@@ -4,7 +4,8 @@ QTC_PLUGIN_DEPENDS += \
|
|||||||
coreplugin \
|
coreplugin \
|
||||||
projectexplorer \
|
projectexplorer \
|
||||||
cpptools \
|
cpptools \
|
||||||
qmljstools
|
qmljstools \
|
||||||
|
debugger
|
||||||
|
|
||||||
QTC_LIB_DEPENDS += \
|
QTC_LIB_DEPENDS += \
|
||||||
cplusplus \
|
cplusplus \
|
||||||
|
@@ -162,7 +162,7 @@ void AutotestPlugin::onRunAllTriggered()
|
|||||||
TestRunner *runner = TestRunner::instance();
|
TestRunner *runner = TestRunner::instance();
|
||||||
TestTreeModel *model = TestTreeModel::instance();
|
TestTreeModel *model = TestTreeModel::instance();
|
||||||
runner->setSelectedTests(model->getAllTestCases());
|
runner->setSelectedTests(model->getAllTestCases());
|
||||||
runner->prepareToRunTests();
|
runner->prepareToRunTests(TestRunner::Run);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutotestPlugin::onRunSelectedTriggered()
|
void AutotestPlugin::onRunSelectedTriggered()
|
||||||
@@ -170,7 +170,7 @@ void AutotestPlugin::onRunSelectedTriggered()
|
|||||||
TestRunner *runner = TestRunner::instance();
|
TestRunner *runner = TestRunner::instance();
|
||||||
TestTreeModel *model = TestTreeModel::instance();
|
TestTreeModel *model = TestTreeModel::instance();
|
||||||
runner->setSelectedTests(model->getSelectedTests());
|
runner->setSelectedTests(model->getSelectedTests());
|
||||||
runner->prepareToRunTests();
|
runner->prepareToRunTests(TestRunner::Run);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutotestPlugin::updateMenuItemsEnabledState()
|
void AutotestPlugin::updateMenuItemsEnabledState()
|
||||||
|
@@ -133,6 +133,11 @@ TestConfiguration *GTestTreeItem::testConfiguration() const
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestConfiguration *GTestTreeItem::debugConfiguration() const
|
||||||
|
{
|
||||||
|
return testConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
// used as key inside getAllTestCases()/getSelectedTestCases() for Google Tests
|
// used as key inside getAllTestCases()/getSelectedTestCases() for Google Tests
|
||||||
class ProFileWithDisplayName
|
class ProFileWithDisplayName
|
||||||
{
|
{
|
||||||
|
@@ -53,7 +53,9 @@ public:
|
|||||||
|
|
||||||
QVariant data(int column, int role) const override;
|
QVariant data(int column, int role) const override;
|
||||||
bool canProvideTestConfiguration() const override { return type() != Root; }
|
bool canProvideTestConfiguration() const override { return type() != Root; }
|
||||||
|
bool canProvideDebugConfiguration() const override { return type() != Root; }
|
||||||
TestConfiguration *testConfiguration() const override;
|
TestConfiguration *testConfiguration() const override;
|
||||||
|
TestConfiguration *debugConfiguration() const override;
|
||||||
QList<TestConfiguration *> getAllTestConfigurations() const override;
|
QList<TestConfiguration *> getAllTestConfigurations() const override;
|
||||||
QList<TestConfiguration *> getSelectedTestConfigurations() const override;
|
QList<TestConfiguration *> getSelectedTestConfigurations() const override;
|
||||||
TestTreeItem *find(const TestParseResult *result) override;
|
TestTreeItem *find(const TestParseResult *result) override;
|
||||||
|
@@ -38,7 +38,9 @@ TestOutputReader *QtTestConfiguration::outputReader(const QFutureInterface<TestR
|
|||||||
|
|
||||||
QStringList QtTestConfiguration::argumentsForTestRunner(const TestSettings &settings) const
|
QStringList QtTestConfiguration::argumentsForTestRunner(const TestSettings &settings) const
|
||||||
{
|
{
|
||||||
QStringList arguments({"-xml"});
|
QStringList arguments;
|
||||||
|
if (m_runMode == Run)
|
||||||
|
arguments.append("-xml");
|
||||||
|
|
||||||
const QString &metricsOption = TestSettings::metricsTypeToOption(settings.metrics);
|
const QString &metricsOption = TestSettings::metricsTypeToOption(settings.metrics);
|
||||||
if (!metricsOption.isEmpty())
|
if (!metricsOption.isEmpty())
|
||||||
|
@@ -33,10 +33,20 @@ namespace Internal {
|
|||||||
class QtTestConfiguration : public TestConfiguration
|
class QtTestConfiguration : public TestConfiguration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit QtTestConfiguration() {}
|
enum RunMode
|
||||||
|
{
|
||||||
|
Run,
|
||||||
|
Debug
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit QtTestConfiguration(RunMode mode = Run) : m_runMode(mode) {}
|
||||||
TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi,
|
TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi,
|
||||||
QProcess *app) const override;
|
QProcess *app) const override;
|
||||||
QStringList argumentsForTestRunner(const TestSettings &settings) const override;
|
QStringList argumentsForTestRunner(const TestSettings &settings) const override;
|
||||||
|
void setRunMode(RunMode mode) { m_runMode = mode; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
RunMode m_runMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -84,6 +84,11 @@ bool QtTestTreeItem::canProvideTestConfiguration() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QtTestTreeItem::canProvideDebugConfiguration() const
|
||||||
|
{
|
||||||
|
return canProvideTestConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
TestConfiguration *QtTestTreeItem::testConfiguration() const
|
TestConfiguration *QtTestTreeItem::testConfiguration() const
|
||||||
{
|
{
|
||||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
||||||
@@ -128,6 +133,13 @@ TestConfiguration *QtTestTreeItem::testConfiguration() const
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestConfiguration *QtTestTreeItem::debugConfiguration() const
|
||||||
|
{
|
||||||
|
QtTestConfiguration *config = static_cast<QtTestConfiguration *>(testConfiguration());
|
||||||
|
config->setRunMode(QtTestConfiguration::Debug);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
QList<TestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
|
QList<TestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
|
||||||
{
|
{
|
||||||
QList<TestConfiguration *> result;
|
QList<TestConfiguration *> result;
|
||||||
|
@@ -40,7 +40,9 @@ public:
|
|||||||
|
|
||||||
QVariant data(int column, int role) const override;
|
QVariant data(int column, int role) const override;
|
||||||
bool canProvideTestConfiguration() const override;
|
bool canProvideTestConfiguration() const override;
|
||||||
|
bool canProvideDebugConfiguration() const override;
|
||||||
TestConfiguration *testConfiguration() const override;
|
TestConfiguration *testConfiguration() const override;
|
||||||
|
TestConfiguration *debugConfiguration() const override;
|
||||||
QList<TestConfiguration *> getAllTestConfigurations() const override;
|
QList<TestConfiguration *> getAllTestConfigurations() const override;
|
||||||
QList<TestConfiguration *> getSelectedTestConfigurations() const override;
|
QList<TestConfiguration *> getSelectedTestConfigurations() const override;
|
||||||
TestTreeItem *find(const TestParseResult *result) override;
|
TestTreeItem *find(const TestParseResult *result) override;
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include "testconfiguration.h"
|
#include "testconfiguration.h"
|
||||||
#include "testoutputreader.h"
|
#include "testoutputreader.h"
|
||||||
|
#include "testrunconfiguration.h"
|
||||||
|
#include "testrunner.h"
|
||||||
#include "testsettings.h"
|
#include "testsettings.h"
|
||||||
|
|
||||||
#include <cpptools/cppmodelmanager.h>
|
#include <cpptools/cppmodelmanager.h>
|
||||||
@@ -84,7 +86,7 @@ static bool isLocal(RunConfiguration *runConfiguration)
|
|||||||
return DeviceTypeKitInformation::deviceTypeId(kit) == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE;
|
return DeviceTypeKitInformation::deviceTypeId(kit) == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestConfiguration::completeTestInformation()
|
void TestConfiguration::completeTestInformation(int runMode)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!m_proFile.isEmpty(), return);
|
QTC_ASSERT(!m_proFile.isEmpty(), return);
|
||||||
|
|
||||||
@@ -99,6 +101,7 @@ void TestConfiguration::completeTestInformation()
|
|||||||
QString buildDir;
|
QString buildDir;
|
||||||
Project *targetProject = 0;
|
Project *targetProject = 0;
|
||||||
Utils::Environment env;
|
Utils::Environment env;
|
||||||
|
Target *runConfigTarget = 0;
|
||||||
bool hasDesktopTarget = false;
|
bool hasDesktopTarget = false;
|
||||||
bool guessedRunConfiguration = false;
|
bool guessedRunConfiguration = false;
|
||||||
setProject(0);
|
setProject(0);
|
||||||
@@ -152,6 +155,7 @@ void TestConfiguration::completeTestInformation()
|
|||||||
workDir = Utils::FileUtils::normalizePathName(stdRunnable.workingDirectory);
|
workDir = Utils::FileUtils::normalizePathName(stdRunnable.workingDirectory);
|
||||||
env = stdRunnable.environment;
|
env = stdRunnable.environment;
|
||||||
hasDesktopTarget = true;
|
hasDesktopTarget = true;
|
||||||
|
runConfigTarget = rc->target();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,6 +186,8 @@ void TestConfiguration::completeTestInformation()
|
|||||||
setEnvironment(env);
|
setEnvironment(env);
|
||||||
setProject(project);
|
setProject(project);
|
||||||
setGuessedConfiguration(guessedRunConfiguration);
|
setGuessedConfiguration(guessedRunConfiguration);
|
||||||
|
if (!guessedRunConfiguration && runMode == TestRunner::Debug)
|
||||||
|
m_runConfig = new TestRunConfiguration(runConfigTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -44,6 +44,7 @@ namespace Internal {
|
|||||||
|
|
||||||
class TestOutputReader;
|
class TestOutputReader;
|
||||||
class TestResult;
|
class TestResult;
|
||||||
|
class TestRunConfiguration;
|
||||||
struct TestSettings;
|
struct TestSettings;
|
||||||
|
|
||||||
using TestResultPtr = QSharedPointer<TestResult>;
|
using TestResultPtr = QSharedPointer<TestResult>;
|
||||||
@@ -55,7 +56,7 @@ public:
|
|||||||
explicit TestConfiguration();
|
explicit TestConfiguration();
|
||||||
virtual ~TestConfiguration();
|
virtual ~TestConfiguration();
|
||||||
|
|
||||||
void completeTestInformation();
|
void completeTestInformation(int runMode);
|
||||||
|
|
||||||
void setTestCases(const QStringList &testCases);
|
void setTestCases(const QStringList &testCases);
|
||||||
void setTestCaseCount(int count);
|
void setTestCaseCount(int count);
|
||||||
@@ -79,6 +80,7 @@ public:
|
|||||||
QString displayName() const { return m_displayName; }
|
QString displayName() const { return m_displayName; }
|
||||||
Utils::Environment environment() const { return m_environment; }
|
Utils::Environment environment() const { return m_environment; }
|
||||||
ProjectExplorer::Project *project() const { return m_project.data(); }
|
ProjectExplorer::Project *project() const { return m_project.data(); }
|
||||||
|
TestRunConfiguration *runConfiguration() const { return m_runConfig; }
|
||||||
bool guessedConfiguration() const { return m_guessedConfiguration; }
|
bool guessedConfiguration() const { return m_guessedConfiguration; }
|
||||||
|
|
||||||
virtual TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi,
|
virtual TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi,
|
||||||
@@ -97,6 +99,7 @@ private:
|
|||||||
Utils::Environment m_environment;
|
Utils::Environment m_environment;
|
||||||
QPointer<ProjectExplorer::Project> m_project;
|
QPointer<ProjectExplorer::Project> m_project;
|
||||||
bool m_guessedConfiguration = false;
|
bool m_guessedConfiguration = false;
|
||||||
|
TestRunConfiguration *m_runConfig = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -120,6 +120,7 @@ void TestNavigationWidget::contextMenuEvent(QContextMenuEvent *event)
|
|||||||
|
|
||||||
QMenu menu;
|
QMenu menu;
|
||||||
QAction *runThisTest = 0;
|
QAction *runThisTest = 0;
|
||||||
|
QAction *debugThisTest = 0;
|
||||||
const QModelIndexList list = m_view->selectionModel()->selectedIndexes();
|
const QModelIndexList list = m_view->selectionModel()->selectedIndexes();
|
||||||
if (list.size() == 1) {
|
if (list.size() == 1) {
|
||||||
const QModelIndex index = list.first();
|
const QModelIndex index = list.first();
|
||||||
@@ -131,7 +132,17 @@ void TestNavigationWidget::contextMenuEvent(QContextMenuEvent *event)
|
|||||||
runThisTest = new QAction(tr("Run This Test"), &menu);
|
runThisTest = new QAction(tr("Run This Test"), &menu);
|
||||||
runThisTest->setEnabled(enabled);
|
runThisTest->setEnabled(enabled);
|
||||||
connect(runThisTest, &QAction::triggered,
|
connect(runThisTest, &QAction::triggered,
|
||||||
this, &TestNavigationWidget::onRunThisTestTriggered);
|
this, [this] () {
|
||||||
|
onRunThisTestTriggered(TestRunner::Run);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (item->canProvideDebugConfiguration()) {
|
||||||
|
debugThisTest = new QAction(tr("Debug This Test"), &menu);
|
||||||
|
debugThisTest->setEnabled(enabled);
|
||||||
|
connect(debugThisTest, &QAction::triggered,
|
||||||
|
this, [this] () {
|
||||||
|
onRunThisTestTriggered(TestRunner::Debug);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,10 +163,13 @@ void TestNavigationWidget::contextMenuEvent(QContextMenuEvent *event)
|
|||||||
deselectAll->setEnabled(enabled && hasTests);
|
deselectAll->setEnabled(enabled && hasTests);
|
||||||
rescan->setEnabled(enabled);
|
rescan->setEnabled(enabled);
|
||||||
|
|
||||||
if (runThisTest) {
|
if (runThisTest)
|
||||||
menu.addAction(runThisTest);
|
menu.addAction(runThisTest);
|
||||||
|
if (debugThisTest)
|
||||||
|
menu.addAction(debugThisTest);
|
||||||
|
if (runThisTest || debugThisTest)
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
}
|
|
||||||
menu.addAction(runAll);
|
menu.addAction(runAll);
|
||||||
menu.addAction(runSelected);
|
menu.addAction(runSelected);
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
@@ -260,21 +274,32 @@ void TestNavigationWidget::initializeFilterMenu()
|
|||||||
m_filterMenu->addAction(action);
|
m_filterMenu->addAction(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestNavigationWidget::onRunThisTestTriggered()
|
void TestNavigationWidget::onRunThisTestTriggered(TestRunner::Mode runMode)
|
||||||
{
|
{
|
||||||
const QModelIndexList selected = m_view->selectionModel()->selectedIndexes();
|
const QModelIndexList selected = m_view->selectionModel()->selectedIndexes();
|
||||||
// paranoia
|
|
||||||
if (selected.isEmpty())
|
if (selected.isEmpty())
|
||||||
return;
|
return;
|
||||||
const QModelIndex sourceIndex = m_sortFilterModel->mapToSource(selected.first());
|
const QModelIndex &sourceIndex = m_sortFilterModel->mapToSource(selected.first());
|
||||||
if (!sourceIndex.isValid())
|
if (!sourceIndex.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TestTreeItem *item = static_cast<TestTreeItem *>(sourceIndex.internalPointer());
|
TestTreeItem *item = static_cast<TestTreeItem *>(sourceIndex.internalPointer());
|
||||||
if (TestConfiguration *configuration = item->testConfiguration()) {
|
TestConfiguration *configuration;
|
||||||
|
switch (runMode) {
|
||||||
|
case TestRunner::Run:
|
||||||
|
configuration = item->testConfiguration();
|
||||||
|
break;
|
||||||
|
case TestRunner::Debug:
|
||||||
|
configuration = item->debugConfiguration();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
configuration = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configuration) {
|
||||||
TestRunner *runner = TestRunner::instance();
|
TestRunner *runner = TestRunner::instance();
|
||||||
runner->setSelectedTests( {configuration} );
|
runner->setSelectedTests( {configuration} );
|
||||||
runner->prepareToRunTests();
|
runner->prepareToRunTests(runMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "testrunner.h"
|
||||||
|
|
||||||
#include <coreplugin/inavigationwidgetfactory.h>
|
#include <coreplugin/inavigationwidgetfactory.h>
|
||||||
|
|
||||||
#include <utils/navigationtreeview.h>
|
#include <utils/navigationtreeview.h>
|
||||||
@@ -74,7 +76,7 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void initializeFilterMenu();
|
void initializeFilterMenu();
|
||||||
void onRunThisTestTriggered();
|
void onRunThisTestTriggered(TestRunner::Mode runMode);
|
||||||
|
|
||||||
TestTreeModel *m_model;
|
TestTreeModel *m_model;
|
||||||
TestTreeSortFilterModel *m_sortFilterModel;
|
TestTreeSortFilterModel *m_sortFilterModel;
|
||||||
|
@@ -397,14 +397,14 @@ void TestResultsPane::onRunAllTriggered()
|
|||||||
{
|
{
|
||||||
TestRunner *runner = TestRunner::instance();
|
TestRunner *runner = TestRunner::instance();
|
||||||
runner->setSelectedTests(TestTreeModel::instance()->getAllTestCases());
|
runner->setSelectedTests(TestTreeModel::instance()->getAllTestCases());
|
||||||
runner->prepareToRunTests();
|
runner->prepareToRunTests(TestRunner::Run);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestResultsPane::onRunSelectedTriggered()
|
void TestResultsPane::onRunSelectedTriggered()
|
||||||
{
|
{
|
||||||
TestRunner *runner = TestRunner::instance();
|
TestRunner *runner = TestRunner::instance();
|
||||||
runner->setSelectedTests(TestTreeModel::instance()->getSelectedTests());
|
runner->setSelectedTests(TestTreeModel::instance()->getSelectedTests());
|
||||||
runner->prepareToRunTests();
|
runner->prepareToRunTests(TestRunner::Run);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestResultsPane::initializeFilterMenu()
|
void TestResultsPane::initializeFilterMenu()
|
||||||
|
48
src/plugins/autotest/testrunconfiguration.h
Normal file
48
src/plugins/autotest/testrunconfiguration.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
|
||||||
|
namespace Autotest {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class TestRunConfiguration : public ProjectExplorer::RunConfiguration
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TestRunConfiguration(ProjectExplorer::Target *parent)
|
||||||
|
: ProjectExplorer::RunConfiguration(parent, "AutoTest.TestRunConfig")
|
||||||
|
{
|
||||||
|
setDefaultDisplayName(tr("AutoTest Debug"));
|
||||||
|
addExtraAspects();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWidget *createConfigurationWidget() { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Autotest
|
@@ -28,6 +28,7 @@
|
|||||||
#include "autotestconstants.h"
|
#include "autotestconstants.h"
|
||||||
#include "autotestplugin.h"
|
#include "autotestplugin.h"
|
||||||
#include "testresultspane.h"
|
#include "testresultspane.h"
|
||||||
|
#include "testrunconfiguration.h"
|
||||||
#include "testsettings.h"
|
#include "testsettings.h"
|
||||||
#include "testoutputreader.h"
|
#include "testoutputreader.h"
|
||||||
|
|
||||||
@@ -38,6 +39,7 @@
|
|||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/projectexplorer.h>
|
#include <projectexplorer/projectexplorer.h>
|
||||||
#include <projectexplorer/projectexplorersettings.h>
|
#include <projectexplorer/projectexplorersettings.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
#include <utils/runextensions.h>
|
#include <utils/runextensions.h>
|
||||||
|
|
||||||
@@ -45,6 +47,9 @@
|
|||||||
#include <QFutureInterface>
|
#include <QFutureInterface>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
|
||||||
|
#include <debugger/debuggerruncontrol.h>
|
||||||
|
#include <debugger/debuggerstartparameters.h>
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -125,7 +130,7 @@ static void performTestRun(QFutureInterface<TestResultPtr> &futureInterface,
|
|||||||
QEventLoop eventLoop;
|
QEventLoop eventLoop;
|
||||||
int testCaseCount = 0;
|
int testCaseCount = 0;
|
||||||
foreach (TestConfiguration *config, selectedTests) {
|
foreach (TestConfiguration *config, selectedTests) {
|
||||||
config->completeTestInformation();
|
config->completeTestInformation(TestRunner::Run);
|
||||||
if (config->project()) {
|
if (config->project()) {
|
||||||
testCaseCount += config->testCaseCount();
|
testCaseCount += config->testCaseCount();
|
||||||
} else {
|
} else {
|
||||||
@@ -208,8 +213,9 @@ static void performTestRun(QFutureInterface<TestResultPtr> &futureInterface,
|
|||||||
futureInterface.setProgressValue(testCaseCount);
|
futureInterface.setProgressValue(testCaseCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestRunner::prepareToRunTests()
|
void TestRunner::prepareToRunTests(Mode mode)
|
||||||
{
|
{
|
||||||
|
m_runMode = mode;
|
||||||
ProjectExplorer::Internal::ProjectExplorerSettings projectExplorerSettings =
|
ProjectExplorer::Internal::ProjectExplorerSettings projectExplorerSettings =
|
||||||
ProjectExplorer::ProjectExplorerPlugin::projectExplorerSettings();
|
ProjectExplorer::ProjectExplorerPlugin::projectExplorerSettings();
|
||||||
if (projectExplorerSettings.buildBeforeDeploy && !projectExplorerSettings.saveBeforeBuild) {
|
if (projectExplorerSettings.buildBeforeDeploy && !projectExplorerSettings.saveBeforeBuild) {
|
||||||
@@ -251,7 +257,7 @@ void TestRunner::prepareToRunTests()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!projectExplorerSettings.buildBeforeDeploy) {
|
if (!projectExplorerSettings.buildBeforeDeploy) {
|
||||||
runTests();
|
runOrDebugTests();
|
||||||
} else {
|
} else {
|
||||||
if (project->hasActiveBuildSettings()) {
|
if (project->hasActiveBuildSettings()) {
|
||||||
buildProject(project);
|
buildProject(project);
|
||||||
@@ -272,6 +278,70 @@ void TestRunner::runTests()
|
|||||||
Core::ProgressManager::addTask(future, tr("Running Tests"), Autotest::Constants::TASK_INDEX);
|
Core::ProgressManager::addTask(future, tr("Running Tests"), Autotest::Constants::TASK_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestRunner::debugTests()
|
||||||
|
{
|
||||||
|
// TODO improve to support more than one test configuration
|
||||||
|
QTC_ASSERT(m_selectedTests.size() == 1, onFinished();return);
|
||||||
|
|
||||||
|
TestConfiguration *config = m_selectedTests.first();
|
||||||
|
config->completeTestInformation(Debug);
|
||||||
|
if (!config->runConfiguration()) {
|
||||||
|
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
|
||||||
|
TestRunner::tr("Failed to get run configuration."))));
|
||||||
|
onFinished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &commandFilePath = executableFilePath(config->targetFile(),
|
||||||
|
config->environment().toProcessEnvironment());
|
||||||
|
if (commandFilePath.isEmpty()) {
|
||||||
|
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
|
||||||
|
TestRunner::tr("Could not find command \"%1\". (%2)")
|
||||||
|
.arg(config->targetFile())
|
||||||
|
.arg(config->displayName()))));
|
||||||
|
onFinished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debugger::DebuggerStartParameters sp;
|
||||||
|
sp.inferior.executable = commandFilePath;
|
||||||
|
sp.inferior.commandLineArguments = config->argumentsForTestRunner(
|
||||||
|
*AutotestPlugin::instance()->settings()).join(' ');
|
||||||
|
sp.inferior.environment = config->environment();
|
||||||
|
sp.inferior.workingDirectory = config->workingDirectory();
|
||||||
|
sp.displayName = config->displayName();
|
||||||
|
|
||||||
|
QString errorMessage;
|
||||||
|
Debugger::DebuggerRunControl *runControl = Debugger::createDebuggerRunControl(
|
||||||
|
sp, config->runConfiguration(), &errorMessage);
|
||||||
|
|
||||||
|
if (!runControl) {
|
||||||
|
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
|
||||||
|
TestRunner::tr("Failed to create run configuration.\n%1").arg(errorMessage))));
|
||||||
|
onFinished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(runControl, &Debugger::DebuggerRunControl::finished, this, &TestRunner::onFinished);
|
||||||
|
ProjectExplorer::ProjectExplorerPlugin::startRunControl(
|
||||||
|
runControl, ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestRunner::runOrDebugTests()
|
||||||
|
{
|
||||||
|
switch (m_runMode) {
|
||||||
|
case Run:
|
||||||
|
runTests();
|
||||||
|
break;
|
||||||
|
case Debug:
|
||||||
|
debugTests();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
QTC_ASSERT(false, return); // unexpected run mode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TestRunner::buildProject(ProjectExplorer::Project *project)
|
void TestRunner::buildProject(ProjectExplorer::Project *project)
|
||||||
{
|
{
|
||||||
ProjectExplorer::BuildManager *buildManager = ProjectExplorer::BuildManager::instance();
|
ProjectExplorer::BuildManager *buildManager = ProjectExplorer::BuildManager::instance();
|
||||||
@@ -290,7 +360,7 @@ void TestRunner::buildFinished(bool success)
|
|||||||
this, &TestRunner::buildFinished);
|
this, &TestRunner::buildFinished);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
runTests();
|
runOrDebugTests();
|
||||||
} else {
|
} else {
|
||||||
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
|
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
|
||||||
tr("Build failed. Canceling test run."))));
|
tr("Build failed. Canceling test run."))));
|
||||||
|
@@ -44,6 +44,12 @@ class TestRunner : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum Mode
|
||||||
|
{
|
||||||
|
Run,
|
||||||
|
Debug
|
||||||
|
};
|
||||||
|
|
||||||
static TestRunner* instance();
|
static TestRunner* instance();
|
||||||
~TestRunner();
|
~TestRunner();
|
||||||
|
|
||||||
@@ -57,7 +63,7 @@ signals:
|
|||||||
void testResultReady(const TestResultPtr &result);
|
void testResultReady(const TestResultPtr &result);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void prepareToRunTests();
|
void prepareToRunTests(Mode mode);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void buildProject(ProjectExplorer::Project *project);
|
void buildProject(ProjectExplorer::Project *project);
|
||||||
@@ -66,11 +72,14 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void runTests();
|
void runTests();
|
||||||
|
void debugTests();
|
||||||
|
void runOrDebugTests();
|
||||||
explicit TestRunner(QObject *parent = 0);
|
explicit TestRunner(QObject *parent = 0);
|
||||||
|
|
||||||
QFutureWatcher<TestResultPtr> m_futureWatcher;
|
QFutureWatcher<TestResultPtr> m_futureWatcher;
|
||||||
QList<TestConfiguration *> m_selectedTests;
|
QList<TestConfiguration *> m_selectedTests;
|
||||||
bool m_executingTests;
|
bool m_executingTests;
|
||||||
|
Mode m_runMode = Run;
|
||||||
|
|
||||||
// temporarily used if building before running is necessary
|
// temporarily used if building before running is necessary
|
||||||
QMetaObject::Connection m_buildConnect;
|
QMetaObject::Connection m_buildConnect;
|
||||||
|
@@ -102,7 +102,9 @@ public:
|
|||||||
TestTreeItem *findChildByNameAndFile(const QString &name, const QString &filePath);
|
TestTreeItem *findChildByNameAndFile(const QString &name, const QString &filePath);
|
||||||
|
|
||||||
virtual bool canProvideTestConfiguration() const { return false; }
|
virtual bool canProvideTestConfiguration() const { return false; }
|
||||||
|
virtual bool canProvideDebugConfiguration() const { return false; }
|
||||||
virtual TestConfiguration *testConfiguration() const { return 0; }
|
virtual TestConfiguration *testConfiguration() const { return 0; }
|
||||||
|
virtual TestConfiguration *debugConfiguration() const { return 0; }
|
||||||
virtual QList<TestConfiguration *> getAllTestConfigurations() const;
|
virtual QList<TestConfiguration *> getAllTestConfigurations() const;
|
||||||
virtual QList<TestConfiguration *> getSelectedTestConfigurations() const;
|
virtual QList<TestConfiguration *> getSelectedTestConfigurations() const;
|
||||||
virtual bool lessThan(const TestTreeItem *other, SortMode mode) const;
|
virtual bool lessThan(const TestTreeItem *other, SortMode mode) const;
|
||||||
|
Reference in New Issue
Block a user