I was asked by a good friend on how to approach testing of a complex web application. How complex? Over 100 menu items, over 50 different screens, unknown amount of flows. He would be the only tester working in a small development team (10 developers). When he mentioned the lack of formal requirements, and explained why brainstorm sessions are not a real option I recognized how desperate situation he was in. He would be re-testing constantly! Like trying to shoot a moving target!
He’s one hard-working guy who wants to deliver quality testing work. Being the only tester in the team without relevant domain knowledge and no other means to build up a solid test basis. “Impossible to test and get decent test coverage with a single tester?” Sure, but unfortunately consultants find themselves in such situations quite often. “What would you recommend?” First of all, report to the customer and discuss options to get more resources… “They have no budget for an additional tester”. So we end up asking the same question again “How should a single tester handle this situation?”
I suggested: “You have to focus on testing new functionality, spend as little as possible time testing regression”. How to do that? Automate! Yes, automate testing functionality that isn’t clearly defined. Is that a crazy idea? Sure but desperate circumstances call for desperate measures. Think about it, how could you turn the situation into your advantage? We know that the lack of formal requirements and product owner will be cause of constant change. In order to cover as much as possible with a single tester he should automate the most valuable user scenarios. By doing this we can reduce the time generating valid test data for continued manual testing and at the same time test the most important flows automatically. “First step would be asking a domain expert to explain the most valuable flows, make a prioritized list out of these flows.” This list will become your test automation backlog.
“If we want to run tests in semi-automatic manner,
When developing complex applications,
Those test will need to be highly adaptable”
“How to start?” We build a lightweight test automation framework. Record and play style Selenium IDE would be a hell to rework after even the slightest change. Scripting offers the advantage of directly interacting with web elements while being platform independent, in other words, if you code it nicely and separate your ID’s and action code, write some reusable procedures and functions. You could adapt your scripts to changes much easier. And, your script could run on any platform / any browser. 🙂
For installation instructions for Selenium/Python refer to https://pypi.python.org/pypi/selenium
“So where to start?” I said “You have enough programming experience by coding excel VBA, Python is easier than that. Give it a try by automating the most valuable business flow. If you know you can manage that you can move ahead and automate other flows as you go.” 🙂
Initialising your TestBot
Let’s setup your first automated Selenium Test. I’m by no means an expert, but this is how I did it. Once again, this is only the basic start, we will build on this and no I’m not a programmer, this code isn’t optimised.
What it does? It opens up your favorite browser, loads Google, takes a screen shot and stores it in the appropriate test evidence folder, finally is closes the browser window.
# BasicPythonSeleniumTest 0.1 By Davy Benoot from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.chrome.options import Options import os, datetime import time import locale import types from time import sleep """ Start Browser Test """ def StartBrowserTest(URL, Browser): # Start browser for URL global TestRunPath # Subfolder of where the script is being run to store test results global TestID # Generated test ID (TestRun [Date] [Time]) global StartTime global wait # Defines the timeout for a page to load global browser # Selenium reference to browser InvalidBrowserSetting=False # We assume the browser is set correctly locale.setlocale(locale.LC_ALL, '') # Local number formats used (system setting) if Browser=="InternetExplorer": browsersetting = "InternetExplorer" browser = webdriver.Ie() # Start Internet explorer elif Browser=="Firefox": browsersetting = "Firefox" browser = webdriver.Firefox() # Start Firefox elif Browser=="Chrome": browsersetting = "Chrome" chrome_options = Options() chrome_options.add_argument("test-type") browser = webdriver.Chrome(chrome_options=chrome_options) # Start Chrome else: InvalidBrowserSetting=True # In case the requested browser setting isn't known if not InvalidBrowserSetting: # When the browser is set correctly we run the test browser.implicitly_wait(10) # Wait upto 10 seconds for the page to load wait = WebDriverWait(browser, 10) StartTime = datetime.datetime.now() # Get the current time/date so we can log when the test was executed print(StartTime) # print when the test started to the terminal # Make a new folder to contain the test output TestRunPath = "TestRun " + StartTime.strftime("%Y-%m-%d %Hu%M") + " " + browsersetting TestID = "TestRun " + StartTime.strftime("%Y-%m-%d %Hu%M") if not os.path.exists(TestRunPath): os.makedirs(TestRunPath) print (TestRunPath + " is created") browser.maximize_window() # Maximize the browser browser.get(URL) # GO to the URL MakeScreenShot("GoogleScreenshot") browser.close() def MakeScreenShot(ScreenShotName): # Make screenshot in the output folder browser.get_screenshot_as_file(TestRunPath + '//' + ScreenShotName + ".png") print ("Screenshot saved!") """ Start the actual test """ # This will start the function StartBrowserTest for selected URL and browser StartBrowserTest("http://www.google.com", "Firefox")