Qt поставляется с QTest
и есть несколько документов: например, официальный учебник.
Тем не мение, QTest
предлагает вам организовать модульные тесты в виде отдельных исполняемых файлов. Для этого есть специальный макрос, который генерирует main()
: QTEST_MAIN()
Если честно, мне очень не нравится этот подход: в общем случае гораздо полезнее запускать все тесты одновременно, чтобы убедиться, что последние изменения ничего не сломали. Иногда, полезно замаскировать какой-либо тест или выполнить отдельный тест, но это исключение, а не правило.
Итак, я хочу запустить все тесты одновременно. Хорошо, я могу написать свой собственный main()
который выполняет все тесты, которые я хочу, скажем, так:
int main(int argc, char **argv)
{
int status = 0;
//-- run all tests
{
TestHTCodecISO14230 tc;
status |= QTest::qExec(&tc, argc, argv);
}
{
TestHTDataMsg tc;
status |= QTest::qExec(&tc, argc, argv);
}
return status;
}
И он запускает все тесты, но проблема в том, что у меня нет удобной сводки всех тестов. Скажем, для двух тестов, приведенных выше, у меня есть два отдельных резюме:
********* Start testing of TestHTCodecISO14230 *********
Config: Using QtTest library 5.4.1, Qt 5.4.1 (i386-little_endian-ilp32 shared (dynamic) release build; by GCC 4.6.1)
PASS : TestHTCodecISO14230::initTestCase()
PASS : TestHTCodecISO14230::decode_summary()
PASS : TestHTCodecISO14230::encode()
PASS : TestHTCodecISO14230::decode_encoded()
PASS : TestHTCodecISO14230::cleanupTestCase()
Totals: 5 passed, 0 failed, 0 skipped, 0 blacklisted
********* Finished testing of TestHTCodecISO14230 *********
********* Start testing of TestHTDataMsg *********
Config: Using QtTest library 5.4.1, Qt 5.4.1 (i386-little_endian-ilp32 shared (dynamic) release build; by GCC 4.6.1)
PASS : TestHTDataMsg::initTestCase()
PASS : TestHTDataMsg::test1()
PASS : TestHTDataMsg::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted
********* Finished testing of TestHTDataMsg *********
Тот факт, что вернулся status
будет ненулевым в случае ошибки, безусловно, полезно, но было бы гораздо более полезным, если у меня есть резюме:
Totals: 8 passed, 0 failed, 0 skipped, 0 blacklisted
Из того, что я вижу, это невозможно: я не могу найти способ программно получить количество пройденных, неудачных, пропущенных и занесенных в черный список тестов: qExec()
это просто функция в QTest
пространство имен, поэтому невозможно собрать дополнительную информацию после его выполнения.
Ну, можно проанализировать выходную строку, но, тьфу …
Для меня это выглядит как плохой дизайн. Было бы, вероятно, гораздо лучше сделать QTest
как класс, затем создайте его экземпляр и передайте ему несколько тестовых классов. Затем некоторая дополнительная информация может быть получена из экземпляра.
Или, может быть, я что-то пропустил.
Итак, вопрос: это возможно с QTest
иметь итоговый вывод всех классов юнит-тестов?
Как я писал в своем комментарии, я построил бы свои тестовые классы следующим образом:
class MyTests: public QObject
{
Q_OBJECT
public:
MyTests() : m_executed(0), m_failed(0)
private slots:
[..]
// This function will be called after each test
void cleanup()
{
m_executed++;
if (currentTestFailed()) {
m_failed++;
}
}
// Output the summary of the test execution.
void report() const
{
qDebug() << "Totals:"<< m_executed - m_failed << "passed,"<< m_failed << "failed";
}
private:
int m_executed;
int m_failed;
};
Если у вас есть несколько экземпляров MyTests
Класс, вы можете расширить его API и суммировать результаты выполнения, генерируя глобальный отчет о выполнении теста. Просто используйте всю силу классов C ++.