With Python 2 not seeing any further development or bug fixes after January 1st 2020, requests for custom Squish packages containing Python 3 support have gained a lot more traction. Since the next major Squish release will ship with Python 3, we’ll have a short look at Python 3-specific behavior in the context of Squish GUI tests. The most obvious change in behavior is how Python handles strings and how individual characters are represented inside a string.
Strings in Python
In Python 2, handling of strings was rather simple. Script writers usually did not have to take care about where these strings came from (network, files from other machines, etc.) or how their internal representation (also known as “encoding”) would look like. Most of the time, everything would just work, except for cases where it wouldn’t.
In Python 3, the authors of the language acknowledged that strings can come from different kinds of sources. Also, the Python 2 behavior of “working most of the time, but not always” may cause problems that are hard to track down.
The result is that in Python 3, strings now care about this internal representation, details of which would far exceed this article. Thankfully, the Python 3 documentation explains everything in its Unicode HOWTO.
Strings in Squish API
Traditionally, Squish always expected test scripts to be UTF-8 encoded. In fact, the Squish IDE by default creates all text files — and even the recently added Script-based Object Map — in this encoding. For literal strings in single- or double-quotes, this likely means that they are already in a format that is safely read and understood by Python 3. The following will just work fine:
someObject.title = '?' # Set a string property to a grinning face emoji
For data from any other source, like network connections or files read inside the test script, one extra step will be needed in Python 3. Most Python functions will provide such data as
bytes instead of
str. This means they will first have to be converted to
str before passing them on to anything in the Squish API that expects a string.
This can be achieved by calling
with open('input.txt') as f: message = f.read() type(someObject, message) # does not work in Python 3 anymore type(someObject, message.decode('utf-8')) # works in Python 2 and 3
Strings in GUI Toolkits
In addition to string types in Python, Squish also deals with string types from the GUI toolkit of the AUT. Typical types can be
QString for Qt-based AUTs or
java.lang.String in the case of Java-based AUTs. Conversion between these string types is usually done automatically inside test scripts. In some cases, however, an explicit conversion from the toolkit string type into the script language string type is needed or is at least helpful:
# Look up a QLineEdit inside a Qt AUT lineEdit = waitForObject(names.surname_LineEdit) # QLineEdit.text is a QString test.compare(className(lineEdit.text), "QString") # Comparing toolkit strings with Python strings works fine test.compare(lineEdit.text, "Hello") # Explicit conversion to Python str is also possible test.compare(str(lineEdit.text), "Hello")
String handling of Python inside Squish test scripts does not change a lot between Python 2 and 3. In most cases, the transition between Python versions should be transparent as long as all test script files are properly encoded as UTF-8. For the remaining cases, Python 3 offers functions to convert between
str when necessary.