Useing FRIEND_TEST for unit/functional gtests

Hello everyone :wave:,

I am trying to write functional tests for the vtol_att_control module. The basic setup is working and the tests are executed. Now I am trying to access a private member of the tiltrotor but (obviously) can not access it.

I tried to use the FRIEND_TEST which gtest offers, but somehow the include of gtest is not found in the class file. Here is a shortened example:

#include <gtest/gtest.h>
class Tiltrotor : public VtolType {
        FRIEND_TEST(VtolAttitudeControlTest, setupTest);
        float _private_member = 2.0f;

The include of gtest is found in the vtol_att_control_test.cpp file without any issues. The terminal just says no such file or directory. Does anyone know why and how to fix it?


I changed following line from the CMakeLists.txt from OFF to ON:

option(CMAKE_TESTING "Configure test targets" ON)

Now I have the googletest folders in my build/px4_sitl_default folder but it is still not linking to the tiltrotor.h file.

From my answer on Slack, I don’t usually solve problems with friend, but rather make a local class in the test file that extends and gives access to protected members - reserve private for things which will truly never be required from the outside.

The technical reason what you’re trying to do here doesn’t work is because GTest isn’t available on the embedded target, so the dependency can only point in the direction GTest --> code. The runtime code cannot include any of the GTest infrastructure, since it can’t be put onto the embedded systems.

1 Like

Thanks a lot for the in-depth explanation of the problem. I will give it a shot with writing a local class :slight_smile:

@jkflying I tried to write my own class to access the data which is stored in the VtolAttitudeControl class. Below you see a minimal compiling version:

This issue is now, that every time when I try to access data like _v_att from the VtolType class it results in a Seg. fault. I suspect that this data is not initialized yet due to the reason that I start my tiltrotor class with a nullptr. Could this be a reason? Or how do I get local pos and attitude (just an example)?

If you look in vtol_type.cpp you’ll see that the _local_pos is initialized from the attitude controller you pass in, which in your case is nullptr. You need to make an attitude controller that gets passed in to set these parameters.

I’m actually surprised it isn’t crashing earlier, when the _local_pos is set to the _attc->getLocal_pos(), given that _attc is nullptr.

@jkflying I understand what you are saying but I can still not figure out the correct way to initialize my VtolAttitudeControl class. I tried the forward declaration (as in many other px4 files) and the declaration with the #include like shown here.

Below you see the forward declaration. It compiles and runs but when trying to access _local_pos from the VtolAttitudeControl it ends in a seg. fault again. Valgrind says Use of uninitialised value of size 8, so it seems VtolAttitudeControl is still not initialized correctly.

When trying to use #include statement, it gives me following error message:

Any suggestions which of both ways to proceed? Or am I just missing a real obvious way to solve this?


You don’t need a forward declaration, that is only for places where you want a point to something as a class member but users of your public API don’t need access to it. Instead, you need to include the actual .h file.

Is there a branch with code I can look at somewhere? You might be hitting something new regarding tests for modules.

not yet, but I will make one :slight_smile:

@jkflying here is the branch:
The base branch is v1.11.0-beta1. If you run make tests TESTFILTER=functional the error should pop up quite quick.

Hey, sorry I didn’t see the edit :slight_smile:

You’re pretty close there, I got it to compile with just these tweaks:

diff --git a/src/modules/vtol_att_control/vtol_att_control_test.cpp b/src/modules/vtol_att_control/vtol_att_control_test.cpp
index 6fac62f79f..dfbc4bac0a 100644
--- a/src/modules/vtol_att_control/vtol_att_control_test.cpp
+++ b/src/modules/vtol_att_control/vtol_att_control_test.cpp
@@ -30,6 +30,7 @@
 #include <gtest/gtest.h>
 #include <vtol_att_control/tiltrotor.h>
@@ -68,7 +69,7 @@ public:
 TEST_F(VtolAttitudeControlTest, setupTest)
-       TestTiltrotor tiltrotor(_vtol_att_control);
+       TestTiltrotor tiltrotor(&_vtol_att_control);
        std::cout << "DEBUG ------------" << std::endl;

The test fails, but I’m sure that’s expected at this stage :+1:

1 Like

Oh, and if you add some tests against behavior which is upstream, it would be great to get them brought in :wink:

cool thanks :slight_smile: the solution looks way easier than expected :sweat_smile:

I will give it a shot and If some useful tests come out of it I will push it :+1:

1 Like

@jkflying I tried to write some tests today but I couldn’t access any functions of the Tiltrotor class (after accessing through a helper function). When running the generated test file I get following output:

ERROR [px4_work_queue] not running
ERROR [px4_work_queue] wq:rate_ctrl not available
ERROR [px4_work_queue] init failed

I guess their might still be something wrong with the instantiation of the Tiltrotor class. Do you have any thoughts on this?

Thanks :slight_smile:

These are due to other components not being initialized - they shouldn’t cause problems for you in unit tests. If you can’t access functions I’d expect to have compile time errors.