Migrating our automation framework from Python 2 to Python 3

Qxf2’s Selenium, Appium and API test automation framework using the Page Object pattern was built with Python 2. We started receiving a lot of requests for Python 3 support. With Python 2 set to retire by the end of 2020, we migrated our existing Qxf2 automation framework code from Python 2 to Python 3. In this post, we will have a look at the changes done when migrating from Python 2 to Python 3.


Why this post?

We know making changes to a framework to support a different version of Python takes a lot of time and effort. We spent quite some time to check on what changes has to be made and what tools to use to make the changes smoother and faster. Sharing this experience would be quite useful for people planning to make similar changes. We have consolidated the list of changes in this post hoping it helps someone in the future.


Setting up Python3 environment

This step is just to show how we went about setting up Python 3 environment since we already had Python 2 in our system. We used virtualenv. You can follow the below steps to setup Python 3.x using virtualenv.

1. First Install virtualenv using pip
2. Download Python 3.x
3. Create a new dir – mkdir -p ~/projects/Python3-venv
4. Run – virtualenv Python3-env –python=”path-to-python-3.x”
5. Now run – source Python3-env/Scripts/activate
6. Then check Python version – Python –version
7. To pip install Python packages use – pip install
8. To come out of the virtualenv use – deactivate


Changes we made to migrate our POM testing framework from Python 2 to Python 3

1. Auto Converting Python 2 to Python 3 Code.
2. Change in Import Statements.
3. Change in Print Statement.
4. Change in urllib library.
5. Change in Encoding/Decoding the strings.
6. Change in Exception Statement.
7. Change in Mechanize module for handling API.

Let’s see the changes one by one.

1. Auto Converting Python 2 to Python 3 Code.

There are a lot of tools which help you port your code automatically from Python 2 to Python 3. We have chosen futurize Tool. It does its best to make Python 3 idioms and practices exist in Python 2, e.g. backporting the bytes type from Python 3 so that you have semantic parity between the major versions of Python. Unfortunately, the tools can’t automate everything to make your code work under Python 3 and so there are a handful of other things you will need to update manually to get full Python 3 support.

How to use futurize tool.

a. Install future into the virtualenv using:

pip install future

b. Run futurize

futurize --stage1 -w *.py subdir1/*.py subdir2/*.py.

Note that with recursive globbing in bash, you can apply stage 1 to all Python source files recursively with:

futurize --stage1 -w **/*.py

That was simple. The tool helped us to make most of the changes including print, the way we handle exception statements etc. We had to manually clean up some imports which futurize used to update our code.

2. Change in Import Statements.

Unlike Python2, in Python 3, implicit relative imports within packages are no longer available. Python 3 supports only absolute imports and explicit relative imports are supported. In addition, star imports (e.g. from x import *) are only permitted in module level code.

For example:

from Cars_API_Endpoints import Cars_API_Endpoints

changed to

from .Cars_API_Endpoints import Cars_API_Endpoints

3. Change in Print Statement.

The print statement has been replaced with a print() function, with keyword arguments to replace most of the special syntax of the old print statement. The futurize tool helped us update it automatically in all our libraries.

For Example:

print "Python says:%s"%str(e)

changed to

print("Python says:%s"%str(e))

4. Change in urllib library.

The urllib and urllib2 modules from Python 2.x have been combined into the urllib module in Python 3. Module urllib is further divided into modules urllib.request, urllib.error and urllib.parse.

For Example:

import urllib2

changed to

import urllib.request, urllib.error

5. Change in Encoding/Decoding the strings.

In Python2 Strings are handled ASCII way but in Python3 strings are handled as Bytes.

b64login = b64encode('%s:%s' % (user, password))

changed to

b64login = b64encode(bytes('%s:%s' %(user, password),"utf-8"))

6. Change in Exception Statement.

The syntax of Exception Handling is changed in Python3. The futurize tool helped us update it automatically in all our libraries.

For Example:

except Exception,e

changed to

except Exception as e

7. Change in Mechanize module for handling API.

Python3 does not support Mechanize module. So to support Python3, we had to replace our API testing endpoints to use Requests module. We will be writing a separate post on it shortly and link it here.


Now our Pythonic GUI and API test automation framework is fully compatible for Python 3. You can use this test automation framework to write:

a. Selenium and Python automation scripts to test web applications

b. Appium and Python scripts for mobile automation (Android and iOS)

c. API automation scripts to test endpoints of your web/mobile applications

Happy Testing…


References

1. A useful 11-minute video

2. Python 3 changes over Python 2


Leave a Reply

Your email address will not be published. Required fields are marked *