Writing Tests with Nt Test
How to write, build and run a test, and the macros Nt Test provides.
A test is a QObject with Q_OBJECT whose private slots are the test functions. ntmoc has to process the class: that is how Nt Test finds the slots. The usual form is a .cpp file that includes its own moc output:
#include <QSignalSpy>
#include <QTest>
class Counter : public QObject {
Q_OBJECT
public:
int value() const { return m_value; }
void setValue(int value) {
if (value == m_value)
return;
m_value = value;
emit valueChanged(value);
}
signals:
void valueChanged(int value);
private:
int m_value = 0;
};
class TestCounter : public QObject {
Q_OBJECT
private slots:
void init() { m_counter.setValue(0); }
void startsAtZero() { QCOMPARE(Counter().value(), 0); }
void emitsOnChange() {
QSignalSpy spy(&m_counter, &Counter::valueChanged);
m_counter.setValue(5);
m_counter.setValue(5);
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.takeFirst().at(0).toInt(), 5);
}
void toHex_data() {
QTest::addColumn<int>("value");
QTest::addColumn<QByteArray>("hex");
QTest::newRow("zero") << 0 << QByteArray("0");
QTest::newRow("byte") << 255 << QByteArray("ff");
}
void toHex() {
QFETCH(int, value);
QFETCH(QByteArray, hex);
QCOMPARE(QByteArray::number(value, 16), hex);
}
private:
Counter m_counter;
};
QTEST_MAIN(TestCounter)
#include "tst_counter.moc"
Link Nt::Test and enable moc for the target:
add_executable(tst_counter tst_counter.cpp)
target_link_libraries(tst_counter PRIVATE Nt::Test)
nt_enable_automoc(tst_counter)
add_test(NAME tst_counter COMMAND tst_counter)
The executable returns the number of failed test functions, or 127 if that is higher.
Test Functions
Every private slot that returns void and takes no arguments runs, in the order of declaration, except for these special ones:
Slots inherited from a base class that ntmoc has seen run first.
Data-Driven Tests
A _data function builds a table with QTest::addColumn() and QTest::newRow(), and the test function reads the current row with QFETCH(). See the toHex test in the example above.
Macros
The macros that report a failure return from the calling function, so they only work in a function that returns void. To check from a helper function, follow the call with QTest::currentTestFailed().
Fails unless the relation holds, and prints both values. |
Like |
The same, with the timeout in milliseconds as the last argument. |
Running a Test
Name test functions on the command line to run only those, and add a data tag to run one row: ./tst_counter toHex:zero. A row of global and local data is global:local. The options are: