Contents
The single hardest thing to do while writing autopilot tests is to understand the state of the application’s object tree. This is especially important for applications that change their object tree during the lifetime of the test. There are three techniques you can use to discover the state of the object tree:
Using Autopilot Vis
The Autopilot vis tool is a useful tool for exploring the entire structure of an application, and allows you to search for a particular node in the object tree. If you want to find out what parts of the application to select to gain access to certain information, the vis tool is probably the best way to do that.
Using print_tree
The print_tree method is available on every proxy class. This method will print every child of the proxy object recursively, either to stdout or a file on disk. This technique can be useful when:
The print_tree method often produces a lot of output. There are two ways this information overload can be handled:
Of course, these techniques can be used in combination.
Using get_properties
The get_properties method can be used on any proxy object, and will return a python dictionary containing all the properties of that proxy object. This is useful when you want to explore what information is provided by a single proxy object. The information returned by this method is exactly the same as is shown in the right-hand pane of autopilot vis.
Sometimes a tests fails because the application under tests has issues, but what happens when the failing test can’t be reproduced manually? It means the test itself has an issue.
Here is a troubleshooting guide you can use with some of the common problems that developers can overlook while writing tests.
Not waiting for an animation to finish before looking for an object. Did you add animations to your app recently?
problem:
self.main_view.select_single('Button', text='click_this')solution:
page.animationRunning.wait_for(False) self.main_view.select_single('Button', text='click_this')
Not waiting for an object to become visible before trying to select it. Is your app slower than it used to be for some reason? Does its properties have null values? Do you see errors in stdout/stderr while using your app, if you run it from the commandline?
Python code is executed in series which takes milliseconds, whereas the actions (clicking a button etc.) will take longer as well as the dbus query time. This is why wait_select_* is useful i.e. click a button and wait for that click to happen (including the dbus query times taken).
problem:
self.main_view.select_single('QPushButton', objectName='clickme')solution:
self.main_view.wait_select_single('QPushButton', objectName='clickme')
problem:
self.assertThat(dialogButton.visible, Eventually(Equals(False)))
problem:
self._get_activity_indicator().running.wait_for(False)
solution:
dialogButton.wait_for_destroyed()
solution:
self._get_activity_indicator().running.wait_for_destroyed()
problem:
def get_first_photo(self):
"""Returns first photo"""
return event.select_many(
'OrganicItemInteraction',
objectName='eventsViewPhoto'
)[0]
solution:
def _get_named_photo_element(self, photo_name):
"""Return the ShapeItem container object for the named photo
This object can be clicked to enable the photo to be selected.
"""
photo_element = self.grid_view().wait_select_single(
'QQuickImage',
source=photo_name
)
return photo_element.get_parent()
def select_named_photo(self, photo_name):
"""Select the named photo from the picker view."""
photo_element = self._get_named_photo_element(photo_name)
self.pointing_device.click_object(photo_element)