Scripts, Snippets and Functions: Less Brittle Test Code with More Productivity

Sep 2, 2021 | Best Practices, Test Automation Insights

Scripts, snippets and functions

Login, search, create a profile: these are common things you have to do everywhere as a tester. eCommerce sites have “add to cart”, “view cart”, and checkout, while content-creation sites have tag, post, upload image, and edit a page. We can get enough understanding about these terms, easily enough, without even bothering to define the term pattern. So how do we test them? How do we test them automatically, that is, in an easily reproducible way that saves time and reduces the expertise our tests require?

Let’s start with Login.

Reusable Login Methods

The first thing you need to do in many applications is login. It is a blocking condition. The way most testers solve this is by having two different tests. First, they test all the combinations of login, including the interesting failures, as one artifact. Then they have a simple, reusable login script that appears at the top of every screen. This method combines four commands – type into username, type into password, click submit, wait for confirmation text that you are logged in, typically “hello, [full name as described in profile].” The screen might also verify some standard logged-in elements, or do an image comparison. The simplest strategy is to cut and paste this into every test.

Then one day, something happens. The developers add a new field, “company id”, to login, in order to enhance security, like the below example. This is a real screen capture from a regional bank in the United States, which added the ‘commercial’ login flow, which has an additional text field.

All of a sudden, every single method fails. If the code is stored in plain text, a clever programmer can write a search-and-replace algorithm to fix it.

Then again, a clever programmer would have used a code snippet in the first place.

The Code Snippet

Most tools have a way of creating a snippet of reusable logic. The visual tools often create this as a sort of encapsulation. That is, create these four or five visual commands, then collapse them into a virtual command that can be cut and pasted around..

That has the same problem as general cut and paste.

What you want to do is create a method, or function, that can be stored in an external library. That library should be under version control, which we’ll discuss later. When the user interface changes to add a new field, the code only needs to change in one place, that code library. Make the change once and all the tests that failed suddenly pass. Problem solved.

In the case of login, we have some ‘pre-canned’ information. Username, password, and possibly, what to expect on the other side. If we change these to variables, then we can pass in a non-username or an invalid password, and expect an error message. This means our test software needs the capability to pass in variables.

We also want the ability to create variables on the fly. For example, we may want to create users in entirely different billing structures and make sure they cannot find each other with search. Or we may want to run multiple tests at the same time, and make sure those users have different names. My favorite way to do this is to use a date-time-stamp and stick it in a variable. For example “acount20180509130010010101” and “[email protected].” A code snippet can generate these. If you need to actually check those emails for received mail, consider using emails with a domain.

Once the pattern for snippets exists for login, you’ll find yourself making all kinds of snippets. Search is particularly easy – search for (term) expect (result text). Starting with a canned, known database of records, or at least one where you can calculate the result, search for terms and show how the search works. The result text could be “Showing 1-20 of 200”, along with the specific results – and these could be in order. Regular expressions are a great way to check order. For example:

/Test Results[\w\W]*Test Planning[\w\W]*Test Execution/

This code matches the three test terms in specific order, separated by any number (*) of word (\w) or non-word (\W). characters … which is anything. Here’s a similar code to match a div with the same text in Ranorex Studio:

div[@text~’Test Results[\w\W]*Test Planning[\w\W]*Test Execution’]

Snippets have different nicknames – in some tools they are called methods, functions, modules, or “user code”. Once you can add variables and regular expressions to your snippets, the opportunity to use them seems to pop up all over the place. The page object pattern is an attempt to define test automation itself in terms of reusable business functions (like login and search) then compose tests out of those functions. To the extent your tooling consists of code (as opposed to visual representations) it is a fantastic, if often misunderstood, place to start.

Use snippets enough and you see everything as a potential snippet. Note that snippets of this sort are useful throughout testing, not just in fully-automated tests. A login snippet, for example, is great for interactive exploratory testing: the tester finishes login with a single keystroke, and is better able to concentrate on real exploration. In cases such as this, snippets help concentrate testing efforts where they’ll pay off, rather than dissipate them repeating tedious formulae whose results are already certain.

Except sometimes you don’t want to go through the UI, and want to work at a lower level.

Command-Line Problems Vs Through the UI

Creation of a profile, in many ways, feels like login. Enter values into fields, upload an image, confirm the results. If you leave a required field blank, see the appropriate error. All scriptable, all reusable.
Sometimes, though, you want to create a bunch of accounts. Perhaps you need three – two in the same account, to see each other when they search, and a third in a separate account.

In that case, calling the functions through the user interface will create delay. What we are doing is not really testing profile creation. Instead, profile creation is just a blocking condition for what we actually want to test. If I can, I prefer to offload the code from these to somewhere else — somewhere faster. We might store them in a test environment that we restore from disk. More likely, we’ll have a microservice or command-line function we can call to create profiles quickly.

This brings us to the final aspect of code snippets expertise: Version Control. Apply version control to test code just as is done for implementation code. When the code snippets (and tooling artifacts) are not versioned directly along with the production code, inevitably tests will run against code that diverges from what the tests expect. The result will be false error reports, which requires the test-code to be “fixed.”
For today, it’s enough to say that all your testing code, including code snippets, should be safely stored under version control, ideally in the same repository and branch as the production code.

One of Ranorex Studio’s benefits is easy creation of small, reusable code modules that can be called from test cases. Ranorex also provides built-in methods called “Automation Helpers” that you can simply drop in to your test automation project. Ranorex Studio gracefully integrates with version control including Git, Subversion, GitHub, Team Foundation, and GitLab.

All-in-one Test Automation

Cross-Technology | Cross-Device | Cross-Platform

Related Posts:

Secure Your Code, Harden Your App, Automate Its Testing

Secure Your Code, Harden Your App, Automate Its Testing

With DevOps practices more popular than ever in software engineering, there has been a push to integrate security, optimization, and frequent testing into the development process. However, as the baseline for what's considered good software evolves, so does the need...

A Guide to Test Driven Development (TDD)

A Guide to Test Driven Development (TDD)

For developers who work on many agile projects, test-driven development (TDD) may be something you wish to incorporate into your software development life cycle (SDLC). It’s a way to implement software programming while integrating unit testing, programming, and...