String Handling in Python 3 Test Scripts

String Handling in Python 3 Test Scripts

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 bytes.decode(encoding):

with open('input.txt') as f:
  message =
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, "QString")
# Comparing toolkit strings with Python strings works fine, "Hello")
# Explicit conversion to Python str is also possible, "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 bytes and str when necessary.

Stefan Gehn joined froglogic in 2010 after finishing his Master's degree in computer science. He's mostly leaping around everything that involves Qt and Linux and has been squashing bugs left and right in several other areas of Squish ever since.


Leave a reply

电子邮件地址不会被公开。 必填项已用*标注