Lessons Learned Switching Manual Tests to Pytest


If you want to start automating your test cases, László Szegedi makes an argument for using the popular Python and Selenium combination. Here, he gives a test script you can use after every release to find any serious regression bugs in the system, to be executed automatically. Integrate it with your existing development pipeline and you get a pretty useful tool for continuous improvement.

I’ve been testing for more than ten years now, and I still love it. I have tons of experience in manual testing, but due to industry changes and the needs at my current workplace, I had to start working outside my comfort zone and automating my test cases.

I was lucky enough to choose my own technology and framework, so I began looking around and evaluating the current mainstream automation technologies. After some comparison, I decided to choose the popular Python and Selenium combination for several reasons:

  • Python is easy to learn
  • It can be used on a large variety of projects and various testing types and levels
  • It has tons of online documentation
  • You can easily simulate user flows with Selenium

After going through a few tutorial videos, I quickly found the package developed specifically for testing: Pytest. It also has vast documentation, and combining it with the also popular Selenium framework to implement web-based tests proved to be relatively easy. Let’s see how these tests work through an example.

The simple code snippet I’ve created opens a Chrome browser, hits the popular music streaming application Spotify, and searches for my favorite Hungarian alternative rock band, Hiperkarma. The expected result shall be the band’s name found as the first result on the page. For the sake of readability and demonstrability, I will be using some not-so-elegant coding conventions.

All the test data is stored separately in a config file, as it’s worth keeping every URL, the login information, and any other test data in a separate file so that you can easily modify any of them if needed without browsing the code itself. The structure of the config file is rather self-explanatory, as is the use of the configparser package to process it.

As you can see in the code here, there are steps that have to be executed before every standalone test: opening a browser, hitting the given URL, opening the parser, reading the test data from the config file, and so on. To make your tests shorter and more readable, you can use the fixture feature, which is executed before all the tests—just like any other “before all” features in other frameworks.

In the current example, we spare seven lines. (Note that they are not spared during the actual test run, as they will be executed anyway.) The fixture creates an object (dr) that can be used in the particular tests; here, I’m passing a WebDriver object set up the way the test needs it to be.

After the test receives its prepared WebDriver, it searches on the user interface for the search field and types the test data in band. Finding these elements on the UI would be best by their IDs—if Spotify designers would add them. But this is not the case, just as with every mainstream web application. They are not interested in having scripts or bots running on their UI, so this example will probably run until a UI change only. This issue also is an example of the work needed to continuously maintain your Selenium scripts.

We find the UI elements mentioned above by their XPath. For the sake of demonstration, I didn’t shorten or resolve any of them, just copied how I reached them with a browser add-on. Would the developers added simple IDs, we would have found these elements with much shorter expressions.

You have to make sure you verify your expected result at the end of your test. This is what the assert function of pytest is for: it will pass the test if its expression is true, and fail if the result is false. This is why the script reads the first result into the result variable and compares it with the given expected result, the band itself. As we’ve found it, the assert function passes the test, printing a simple “.” to the standard output. If the publisher removes Hiperkarma’s albums from Spotify, like Taylor Swift did a few years ago, we would get an ugly red “F” in the output.

Instead of simply hitting the Run button in your IDE, you have to start the Pytest script with the following command: pytest spotify_sample.py. This command will identify and run all your tests (functions starting with the test_ prefix). Just make sure you give this command in the folder you have your test script in, log off at the end so as not to overload the system to be tested, and quit the driver at the end of the tests.

You can see how this test runs here.

Here you have a test script you can use after every release to find any serious regression bugs in the system, to be executed automatically. Integrate it with your existing development pipeline and you get a pretty useful tool for continuous improvement, especially if you feed the output to a processing tool and set up your own alerts. You can also adjust your test reports with other packages like pytest-html according to your needs. Just make sure you select the test cases to be automated consciously, keeping the test pyramid in mind.

About the author

StickyMinds is a TechWell community.

Through conferences, training, consulting, and online resources, TechWell helps you develop and deliver great software every day.