Tests in Qt for Android Automotive

Qt IF Android Vehicle Properties is a Qt for Android Automotive (QtAA) submodule that provides a C++ and QML wrapper for the Android Automotive Vehicle Properties. The Qt Interface Framework (QtIF) is used to generate the code and avoid maintaining duplicate code per each vehicle property.

Like in other Qt solutions, Qt for Android Automotive contains tests. QtAA implements some of those tests standardly, using the Qt Test framework. On the other hand, the Qt IF Android Vehicle Properties tests depend on QtIF. We want to share how you can leverage QtIF to quickly create and maintain your tests.

QtIF "test" TEMPLATE

QtIF delivers its test Template. The generated tests are an excellent point to start. Just use qt_ifcodegen_generate CMake function for QtIF generator like below:

qt_ifcodegen_generate(
IDL_FILES [PATH_TO]/FILENAME.qface
TEMPLATE test
)

QtIF will generate two files per each interface defined in the qface file: header (tst_[INTERFACENAME].h) and cpp (tst_[INTERFACENAME].cpp). Those files contain declarations and definitions of tests that check: connections to (fake) backends, changing values from the (fake) backend/frontend, signals, and methods. That is something that can be easily and quickly integrated and used in your project.

 Module tests

Module tests are the second type of test for Qt IF Android Vehicle Properties in QtAA. They are used for testing the full feature (using the actual frontend and backend). The QtIF generator also generates backends, frontend, and test scenarios are also generated with :

qtaa_tests_if_generator

There are more than ten interfaces, each of them with multiple vehicle properties. Creating and maintaining tests per each property and backend combination would be too much manual work. The QtIF generator helps avoid copied code and gives you an easy way to iterate for each interface and property. It also offers a possibility to receive getter/setter function names or default properties value. Let's look at the following code:

{ % for interface in module.interfaces %}
{ %for property in interface.properties %}
toSet =
;
QSignalSpy Spy(m_,
SIGNAL(Changed()));
QVERIFY(Spy.isValid());
QCOMPARE(Spy.count(), 0);

m_->(toSet);
QVERIFY(Spy.wait());
QCOMPARE(Spy.count(), 1);
QCOMPARE(m_->(), toSet);
{ % endfor %}
{ % endfor %}

Code will be generated for each property in each interface in the QFace file. Let's look at the generated code for the fanSpeed property in the QIFHvac interface:

int toSetFanSpeed = 111;
QSignalSpy fanSpeedSpy(m_qifhvac_test, SIGNAL(fanSpeedChanged(int)));
QVERIFY(fanSpeedSpy.isValid());
QCOMPARE(fanSpeedSpy.count(), 0);

m_qifhvac_test->setFanSpeed(toSetFanSpeed);
QVERIFY(fanSpeedSpy.wait());
QCOMPARE(fanSpeedSpy.count(), 1);
QCOMPARE(m_qifhvac_test->fanSpeed(), toSetFanSpeed);
QtIfAndroidVehicleProperties::VehicleHvacFanDirections toSetFanDirection =
QtIfAndroidVehicleProperties::VEHICLE_HVAC_FAN_DIRECTION_DEFROST_AND_FLOOR;
QSignalSpy fanDirectionSpy(m_qifhvac_test,
SIGNAL(fanDirectionChanged(QtIfAndroidVehicleProperties::VehicleHvacFanDirections)));
QVERIFY(fanDirectionSpy.isValid());
QCOMPARE(fanDirectionSpy.count(), 0);

As you can see, using QtIF to generate test scenarios can be helpful. Just imagine you are manually writing this code for each property. The test will adjust during configuration when you add, rename, or remove a property from your qface file.

 


Blog Topics:

Comments