Most professional software comes with translations for user-visible texts such that users can continue using a familiar language. This poses an additional challenge for automated UI tests since user-visible texts can no longer be used to identify objects in case the test suite is to be executed with different translations for the user interfaces.
In practice, it’s not uncommon to see a huge increase of size of an object map when dealing with translated user interfaces. For instance, here’s a small snippet taken from the object map used for testing the ‘Qt’ addressbook example shipped with
Squish for Qt
(we’re using the Python scripting language here):
This defines a name for a dialog used for adding new entries to the Addressbook.
If the test suite is now extended with new tests automating the same dialog, but in a different language (say: German), it’s not unlikely to end up with an object map like this:
Note how the object map doubled in size. Furthermore, it not only became larger but also introduced a significant amount of duplication; changing the structure of the dialog used for adding entries (e.g. by replacing QLabel controls with different kinds of controls) will require updating multiple object names.
In some cases, this issue can be addressed by reconfiguring Squish to not use properties which hold user-visible text when generating object names (see the chapter
Object Name Generation
in the Squish manual for more information). Instead, internal properties like id or the like might be available which can be used instead. However, this has a number of downsides:
not all objects tend to have such stable internal identifiers so it’s not uncommon that testers have to wait for engineers to add IDs for any relevant control
even if IDs are available, determining the ID for a given control on the screen can be tricky
the IDs tend to be a bit cryptic which negatively impacts readability of the test scripts; it’s harder to figure out which controls a given test script interacts with by reading the test code
In case internal identifiers are not available, a better approach might be to factor out user-visible texts into a separate module (a ‘dictionary’) in which each English text is mapped to a translation. This translation can be performed by a function which we will call tr (short of translate) here.
The first step is to augment the original object map such that the tr function is defined and used for all user visible texts:
Notice how the tr function takes one argument and merely returns it: it has no effect whatsoever. It’s used to mark all user-visible texts though. We can now move this function to a separate file (say english.py) and import it from there:
The benefit is that we can now provide alternative definitions of the tr function for other languages. For instance, the German translation might be:
By simply using from german import tr in our object map, all object names will then use the tr function suitable for translating English texts to German and thus the tests can be used when using the addressbook example program with German translations.