User interface (UI) tests or automated functional testing, have not a very good reputation. They are said to be hard to maintain and not powerful enough to find bugs. Though, very often the reasons for this is not the problem in the test frameworks or in the test tools. It turned out to be connected with a too bad particular tests design.
We gathered for you seven tips in functional test design, which certainly can make UI tests more easy in use and more powerful.
7 tips for functional testing:
1. Exploit discrete locators instead of indexes
Usually it is desirable to make a test you have to do somewhat like this ” click the seventh element in the list.” For such elements it is worth the intention to find or make unique identifiers, in place of manipulating aspects according to index.
The test will continues an unpredictable path, if the order of the list varies or the order of the links modify. Maintaining of such unexpected tests is pretty hard.
2. Check aftermath, don’t make just stupid clicking
In many automated test tools there are feature that allows to record automatically and then play back a set of actions. Such features are handy when creating tests, but the results of these record/playback tactic will result in a low quality. To make it clear let’s underline, that such kind of tests do not examine the application’s state after handling elements in the application.
Such functions as selecting, clicking, typing and other, anyway the state of the application will be changed. Proper results will be checked in good tests after manipulating elements in the application. Have the test verify that the resulting page is right, if the automated test follows a link. Have the test verify that the content of the report is right, if the test produce a report.
3. Don’t make pauses, better wait
Some period of time may be needed by application before results are obtainable for the test to examine. Such situation is common especially with AJAX calls. Sometimes it seems nice to pause the test or sleep for a few seconds until checking a result, but this is a kind of definitely bad practice. Keep in mind, that test will generate a mistaken failure if the application takes a huge period of time to return. And the test stands idle while it could be moving on, if the application returns pretty fast.
It is better to have the test wait for a particular aspect of the application to appear. This makes the test less prone to mistaken failures and more powerful, since the test is actually awaiting for and verifying the state of the application upon producing the aspect that test expects for.
4. Avoid using conditionals
Sometimes the behavior of the environments in software testing services can be unpredictable. It seems wise to use a conditional in a test for such cases. But there are a huge number of problems with this method. One problem is the same as the problem which appears after using indexes in place of specific locators: so if the application, which is tested, exposed to changes, the automated test may occur completely unexpected and unbeknown paths, causing mistaken failures (or worse, lying successes) and making maintenance very hard. The test would never display that a bug had been entered if you meet another problem. It is the problem when one branch of the conditional statement could (erroneously) vanish altogether.
5. Sort order must be examined with regular expressions
The correct order of application’s appearing aspects is often significant to the user. Usually it is significant that automated tests check for the correct order of things: whether it is text on the page itself, columns in tables or elements in a list.
Suppose there is a kit of things. These things should come in sight in order called “first,” “second” and “third.” Tests can use some sort of permanent expressions to check the order. Here is an example ot exploiting a simplistic kind of permanent expression. Its name is a “glob”. Such expression is available in automated test tools, and in particular in Selenium:
| getText | glob: first * second *three |
| click | sort_thing |
| getText | glob:three*two* first |
This it what the test’s first step examines, that the text ” first ” is running before the text “two” and the text “two” is followed by the text ” third.” The “*” character points that the test will permit any characters at all between ” first ” and ” second ” and ” third.” The test’s second step clicks somewhat that sort ” first ” ” second ” and ” third ” in reverse order, after this the test’s third step examines that the sorting was definitely proper.
And the last tip. Below there is a concrete example of a brilliant practice for specific kinds of test data particularly using Fitnesse and Selenium. As you can see, the test needs to enter a Taxpayer Identificational Number that is unique, then verify that TIN has in fact been entered into the application:
| $TIN= | getValue | tin |
| click | link=Save |
| type; | search | $TIN |
| GET SEARCH RESULTS CONTAINING THE TIN |
7. Stop repeating yourself
As it was already mentioned, that looking forward when an element in the application will appear is a useful habit. Fairly often there are the case that once the element appears, the test will want to work with that element. It is a pretty good habit to abstract widely spread actions into their own approaches or modules, then to call those actions from the tests as required. Next an example of abstracting the wait-for-and-click action is mentioned. The used syntax is Fitnesse and Selenium:
!| scenario | Wait for and click | elementLocator |
| waitForElementPresent | @elementLocator |
| click | @elementLocator |
We need only put down from a test itself:
| open | www.foo.com |
| Wait for and click | link=Hello from Foo! |
Only one line of typing is saved in this example. Pay attention to the fact, that if ‘Wait for and click’ is performed dozens or hundreds of times in a test suite, so this is a significant enhancement in readability and maintenance. Here are some other examples of actions to be abstracted to their own modules: might be selecting all the elements of a list, logging in, etc.
Quality testing needs a quality design
These are just some examples to give you a hand in making your automated tests both maintainable and powerful. Certainly there are a lot of other examples that are widely used by the testers from different software testing companies.
The automated functional tests are hard to maintain, are not powerful, they don’t search for bugs effectively – these are the biggest complaints about it. But well-designed are totally different. They are not difficult to maintain; they are strong in that they verify the state of the application being tested for aspects of function significant to the user and to the application itself, and well-designed automated tests definitely find bugs.