How I am learning to test The Internet with SeleniumBase

Goal: I have a simple, ambitious big hairy goal Learn how to “Automate all the (test) things, in Python”. This is Part 1 on my journey towards this goal.

For context I consider myself experienced as a tester, but a relative newbie as a developer. I have been involved in one successful automation project using Powershell, and one failed automation project using .NET Framework and Selenium.

Go learn Python! Somewhere else

What I won’t be touching on in any point during this series, is how to install or use the basics of Python. This is well covered ground, and the Python Docs are a great place to start if this is what your after. https://docs.python.org/3/

SeleniumBase

SeleniumBase is a test framework that wraps Selenium and extends Pytest, and also works with Nose test. I have selected SeleniumBase as my web test framework of choice, after a brief evaluation for a few reasons:

Low barrier to entry, it’s really easy to write and run your first test

The competition where mostly based in JavaScript (WebDriver.io and NightWatch.js), I found them flaky to get running out of the box

I wanted to avoid Java, for personal preference *The maintainer is VERY responsive via Twitter and Git issues, and has helped me and added functionality. I can’t emphasis enough how much confidence this gives me.

Finally and maybe most important, I was moments away from taking another direction, and got a recommendation from the kind folks at the Ministry of Testing Testers.Chat slack community to make use of Python and SeleniumBase to start my automation journey, 100 times thank you!

I found Getting up and running with SeleniumBase is easy, following their own instructions, so I am not going to cover this ground. http://seleniumbase.com/

The Internet

Sure I could, and have, tried creating some automation against client projects. But here is where I come across some problems in terms of developing my skills:

I cannot share details of this work with others, my nature it is confidential

I am limited to solving the challenges for the given project

Things change, so a lot of what I learned is about maintaining references to page elements

Easy, right?

On first glance, the list of individual pages of isolated examples looks like it should be super easy to automate with any Selenium based framework. Turns out, for me at least, each example I have tried to automate so far has thrown up some interesting mini challenge I have had to spend time thinking about and researching. This is great news! Because it validates it as a useful resource to hone my skills.

Basic Auth

The basic problem I had to solve for this example, is how to pass the username and password for basic auth. I understand, the method I have choosen is far from production ready. If i find myself in a situation where I am testing pre-production code that uses basic auth, happy days.

Again I am making use of the Page Object model pattern. Following the SeleniumBase examples, all I am doing is storing strings that are the selectors for the elements I will find in my tests. I am not returning objects here, but I am abstracting the locators so I have a “single source of truth” to update when the web app I am testing is updated, and my references break.

This was my first experiment using the get_attributes function. I adapted this method from an equivalent I found researching the challenge online. Getting naturalWidth of 0 appeared to be a widely accepted method to assert if an image is broken. Note, this is a failing test, and that is to be expected a two of the images ARE broken, and I am asserting that they should not be.

I can think of at least two things I have not done to make this example elegant:

*The check for a broken image could be abstracted into a helper method
*Instead of static references to three images, all images could be iterated

Feel free to send me a pull request if you find time to do either of these enhancements, or folk my examples and do this for yourself. Either way, let me know!

Nothing exciting here, just another basic object model. the only gotcha is that checkbox 2 is the 3rd child, not he 2nd. I believe this is because the 2nd child is the text label for checkbox 1. Answers on a postcard.

Unlike in the Broken Images example, here I have created a helper method. I am using .get_attribute(), this time I need to work around the fact the method throws an example if the attribute is not found. It turns out, the “checked” attribute is added and removed from the element when the check-box is checked and unchecked.

If you think if anything more interesting I can test with checkboxes, or again a way to more elegantly iterate them, let me know!