我有一个Qt Unit测试(子)项目,它生成一个类(主要由QTEST_APPLESS_MAIN
生成)。我可以从Qt Creator中作为控制台应用程序启动它。
问:如何将其他类作为测试用例添加到此特定项目中。
private Q_SLOTS
),则不调用方法,而只调用具有QTEST_APPLESS_MAIN
main(..)
,我不能在项目中使用QTEST_APPLESS_MAIN
多个类(这是正确的吗?)main
的一个类,但这非常繁琐。 那么在单元测试项目中对几个类运行单元测试的最佳方法是什么?
PS: 但是,在“Using QT Unit Tests in a project - conflicting main(...) functions”a Blog is mentioned中,我无法下载描述解决方案的zip。
答案 0 :(得分:21)
根据您链接的解决方案,在单个Qt单元测试项目中完成测试两个(或更多)类的方法是确保每个要测试的类都具有相应的测试类,并且您已创建一个执行每个测试类的自定义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
文件。
答案 1 :(得分:19)
基于已接受的答案,如果您使用的是C ++ 11,您可能会对使用lambdas的解决方案感兴趣。它避免了你每次都写相同的代码。虽然你可以用函数替换lambda,但我认为lambda更清晰。
#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();
};
答案 2 :(得分:4)
我在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;
}
答案 3 :(得分:2)
我正在使用以下代码收集所有测试结果:
let t = document.getElementsByClassName('annonce_titre');
for (elt of t ){
let titleLink = elt.getElementsByTagName('a');
console.log(titleLink[0].href);
setInterval(function(){console.log("Interval reached");}, 5000);
}
答案 4 :(得分:1)
我的方式:
我基本上对this post进行了轻微修改。
答案 5 :(得分:0)
使用CMake而不是QMake进行构建,并添加两个测试目标。
add_executable(firstTest tst_testfirst.cpp)
add_test(NAME firstTest COMMAND firstTest)
add_executable(secondTest tst_testsecond.cpp)
add_test(NAME secondTest COMMAND secondTest)
tst_testfirst.cpp和tst_testsecond.cpp都有自己的QTEST_MAIN行。
Qt Creator将同时运行两个测试类。如果从命令行运行它们,则可以使用“ ctest”运行测试。