Qtユニットテスト(サブ)プロジェクトがあり、1つのクラスが生成されます(メインは_QTEST_APPLESS_MAIN
_によって生成されます)。これは、QtCreator内からコンソールアプリとして開始できます。
Q:この特定のプロジェクトにテストケースとしてクラスを追加するにはどうすればよいですか。
private Q_SLOTS
_)しかない場合、メソッドは呼び出されず、_QTEST_APPLESS_MAIN
_を持つクラスのメソッドのみが呼び出されます。main(..)
は1つしか存在できないため、プロジェクト内の複数のクラスで_QTEST_APPLESS_MAIN
_を使用することはできません(正しいですか?)main
を含む1つのクラスに手動で「配線」することはできますが、これは非常に面倒です。では、単体テストプロジェクトで複数のクラスに対して単体テストを実行するための最良の方法は何ですか?
PS: " プロジェクトでのQTユニットテストの使用-競合するmain(...)関数 " a ブログが言及されています ただし、ソリューションを説明するZipをダウンロードできません。
リンクしたソリューションによると、単一のQtユニットテストプロジェクト内で2つ(またはそれ以上)のクラスのテストを実行する方法は、テストする各クラスに対応するテストクラスがあり、カスタムint main
を作成したことを確認することです。各テストクラスを実行します。
例えば:
class TestClassA : public QObject
{
Q_OBJECT
public:
TestClassA();
...
private Q_SLOTS:
void testCase1();
...
};
class TestClassB : public QObject
{
Q_OBJECT
public:
TestClassB();
...
private Q_SLOTS:
void testCase2();
...
};
void TestClassA::testCase1()
{
// Define test here.
}
void TestClassB::testCase2()
{
// Define test here.
}
// Additional tests defined here.
// Note: This is equivalent to QTEST_APPLESS_MAIN for multiple test classes.
int main(int argc, char** argv)
{
int status = 0;
{
TestClassA tc;
status |= QTest::qExec(&tc, argc, argv);
}
{
TestClassB tc;
status |= QTest::qExec(&tc, argc, argv);
}
return status;
}
明らかに、さまざまなテストクラスを複数の翻訳ユニットに分散させてから、int main
とともに翻訳ユニットに含めることができます。適切な.moc
ファイルを含めることを忘れないでください。
受け入れられた回答に基づいており、C++ 11を使用している場合は、ラムダを使用したソリューションに興味がある可能性があります。毎回同じコードを書く必要がなくなります。ラムダを関数に置き換えることはできますが、ラムダの方がクリーンだと思います。
#include <QtTest>
#include "test1.h"
#include "test2.h"
int main(int argc, char** argv)
{
int status = 0;
auto ASSERT_TEST = [&status, argc, argv](QObject* obj) {
status |= QTest::qExec(obj, argc, argv);
delete obj;
};
ASSERT_TEST(new Test1());
ASSERT_TEST(new Test2());
return status;
}
#ifndef TEST1_H
#define TEST1_H
サンプルテスト
#include <QtTest>
class Test1 : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testCase1();
};
これと同じ答えを検索して、 http://qtcreator.blogspot.de/2009/10/running-multiple-unit-tests.html から非常に良い解決策を見つけました。彼は、(DECLARE_TESTマクロを介して)作成されたすべてのテストを登録するコンテナーを使用して名前空間を作成し、それを使用してリスト上のすべてのテストを実行します。コードに合わせて書き直し、バージョンをここに投稿します(Qt Creatorバージョン:4.1.0):
/* BASED ON
* http://qtcreator.blogspot.de/2009/10/running-multiple-unit-tests.html
*/
#ifndef TESTCOLLECTOR_H
#define TESTCOLLECTOR_H
#include <QtTest>
#include <memory>
#include <map>
#include <string>
namespace TestCollector{
typedef std::map<std::string, std::shared_ptr<QObject> > TestList;
inline TestList& GetTestList()
{
static TestList list;
return list;
}
inline int RunAllTests(int argc, char **argv) {
int result = 0;
for (const auto&i:GetTestList()) {
result += QTest::qExec(i.second.get(), argc, argv);
}
return result;
}
template <class T>
class UnitTestClass {
public:
UnitTestClass(const std::string& pTestName) {
auto& testList = TestCollector::GetTestList();
if (0==testList.count(pTestName)) {
testList.insert(std::make_pair(pTestName, std::make_shared<T>()));
}
}
};
}
#define ADD_TEST(className) static TestCollector::UnitTestClass<className> \
test(#className);
#endif // TESTCOLLECTOR_H
次に、次のようにテストヘッダーにADD_TEST(class)行を追加します。
#ifndef TESTRANDOMENGINES_H
#define TESTRANDOMENGINES_H
#include <QtTest>
#include "TestCollector.h"
class TestRandomEngines : public QObject
{
Q_OBJECT
private Q_SLOTS:
void test1();
};
ADD_TEST(TestRandomEngines)
#endif // TESTRANDOMENGINES_H
そして、すべてのテストを実行するには、次のようにします。
#include "TestCollector.h"
#include <iostream>
int main(int argc, char *argv[]) {
auto nFailedTests = TestCollector::RunAllTests(argc, argv);
std::cout << "Total number of failed tests: "
<< nFailedTests << std::endl;
return nFailedTests;
}
私のやり方:
私は基本的に この投稿 のわずかなバリエーションを作りました。