We can also test the signals and slots in our program by using the QSignalSpy class. QSignalSpy is a class provided by Qt to enable connecting to the signal of any object and recording its emission. QSignalSpy will then append the signal's arguments into a QVariant list for unit testing.
Let's continue our previous code and add a new slot function called test_signalslot:
private slots:
void initTestCase();
void cleanupTestCase();
void test_case1();
void test_case2();
void test_signalslot();
Next, in the constructor of the Testing class, we create a new QObject and connect its objectNameChanged signal to the test_signalslot slot function. We also connected the objectNameChanged signal to a QSignalSpy object so that it can record the emission. After that, we trigger the signal by changing the name of the object, as follows:
Testing::Testing()
{
QObject* object = new QObject(this);
connect(object, &QObject::objectNameChanged, this,
&Testing::test_signalslot);
spy = new QSignalSpy(object, &QObject::objectNameChanged);
object->setObjectName("New Name");
}
Then, we implement the test_signalslot function. First, we check whether the signal has been emitted. We also considered all the arguments recorded by QSignalSpy and check whether the first argument is "New Name", so that we can verify that the signal is the one we emitted just now:
void Testing::test_signalslot()
{
QCOMPARE(spy->count(), 1);
QList<QVariant> arguments = spy->takeFirst();
QVERIFY(arguments.at(0).toString() == "New Name");
}
Build and run the program now and you should see something like this:
********* Start testing of Testing *********
Config: Using QtTest library 5.13.0, Qt 5.13.0 (x86_64-little_endian-llp64 shared (dynamic) debug build; by GCC 7.3.0)
PASS : Testing::initTestCase()
PASS : Testing::test_case1()
PASS : Testing::test_case2()
PASS : Testing::test_signalslot()
PASS : Testing::cleanupTestCase()
Totals: 5 passed, 0 failed, 0 skipped, 0 blacklisted, 1ms
********* Finished testing of Testing *********
You can change the value in QCOMPARE and QVERIFY to see what will happen if the unit test failed. If you are testing the signal of a timer that doesn't emit immediately, you can use the wait function to ask Qt to wait for a few milliseconds before verifying it:
QVERIFY(spy->wait(1000));
That's it. We have learned how we can make use of Qt and Qt Quick tests to automatically check our code and ensure that quality is maintained properly. We also learned how we can unit test the signals and slots within our Qt application through QSignalSpy.
Next, we will move on to third-party auto test suites and make our test integration even more diverse and better.