views:

680

answers:

6

I've been tasked with developing a system for automated GUI testing and I could use some advice. As luck would have it, we are in the midst of a major redesign of our GUI and the developers doing the work are open to making their code more friendly to automation. My problem is that I'm not sure what to ask them to add. Whatever hooks are added can't impact the functionality, appearance or security of the interface and shouldn't have a noticeable impact on performance. Other than that, the sky's the limit!

The application in question is a web-based Java app accessed via AJAX. Most of the existing features are coded using jsp, Javascript and a little bit of Flash 8. The next wave of features will be done using the YUI Javascript library. I'm pretty much settled on Selenium as a test tool because of its flexibility and price tag (free). Major point: I'm aiming for test-reusability and ease-of-maintenance. My preference is to write code that detects, validates and exercises the page elements rather than use a record-and-playback system for test development.

Can anyone provide some guidance as to what hooks could be placed in the code or some best practices to make test development easier and the tests themselves more robust?

+1  A: 

I'm pretty green to (proper) unit testing, but have ran across a few mentions that you should try and avoid testing your GUI. They usually omit specific reasons, so I can't really back them up.

The approach I take (and I think the approach adviced by Juval Lowy in "Programming .NET Components") is to try and abstract the actual code from the GUI via an interface, which lets me write unit tests for all the business logic triggered by the GUI without actually testing the GUI itself.

It works pretty well and has resulted in much cleaner code with great separation of business logic from GUI and also makes GUI modifications a great deal less stressful.

STW
+1  A: 

There is very little that the devs can add to the code to help.

The issue is that if you want to test the execution of code paths and the validity of those code paths, that should be done in Unit Tests, and those should be completely divorced from your GUI. But if you really want to test your GUI, then you've just got to simulate user input. The one thing that can help with this is to have your objects and controls properly tagged so that they can be properly detected by your test framework and be exercised. Other than that, there's just not a lot that can be done (although that can help quite a bit in itself).

McWafflestix
+2  A: 

As with most questions, it depends. Mostly on what your site looks like and what sort of controls are on the pages - are there a lot of repeated elements etc?

I've had a lot of success using Selenium RC and Selenium IDE. The main thing is getting used to using Selenium and its commands. It's also helpful to get used to locating objects on the page (XPaths and CSS selectors, as well as 'contains' function). What you don't want is a lot of elements that have the same select path. If the tables and divs below don't have a unique part to them, it can add extra complexity to your tests.

<html>
  <body>
    <table>
      <tr>
        <td>
          <div></div>
          <div></div>
          <div></div>
        </td>
      </tr>
    </table>
    <table>
      <tr>
        <td>
          <div></div>
          <div></div>
          <div></div>
        </td>
      </tr>
    </table>
  </body>
</html>

To test images, its nice to be able to check for their existence based on something other than the image file name, so you don't have to change your tests when the image is updated. If you need to test Flash objects, check out this site.

Beyond that, there isn't a whole lot that I have noticed that can be incorporated in the development side. Once you start setting up the tests and locating elements on the page, you'll probably see pretty quickly what the developers need to do to help you out.

s_hewitt
+1 ids for divs. A big help.
MatthieuF
+1  A: 

Adding to comments by McWafflestix and s_hewitt - gui elements need to be properly tagged, unique AND predictable for success with gui automation. If the element ids are not predictable, you will run into trouble. Predictable does not necessarily mean static. For static page elements like a username field or a login button, I would expect the name/id for these to be static from build to build and run to run. For checkboxes, radio buttons, dynamic content, I would expect these to be dynamic, yet predictable. For example, you might have a div with a class = "contentdetail" and an id = "12345". As long as you can craft your xpath to find the object you need to interact with reliably, you should be good.

EDIT: A great way for devs to support test automation is with test setup. Depending on your application, automated test setup and teardown can be problematic. For example, in a warehouse workflow application, the tests at the beginning of the workflow (accept items into the warehouse) are easy to set up, but the tests at the end of the workflow (ship an item from warehouse to customer) have so many dependencies (item must be in warehouse, with sufficient quantity, in correct inventory location, etc...) that most of your automation code may deal with just navigating and inputting your way through the app to get to the point where you can perform a test. In these cases, it may be beneficial to have some kind of external utility (outside the app, so the main gui is unaffected) to inject dependencies or reset the database to some known state. In my warehouse example, your utility could set up the scenario through the api level, so that the automated gui test can pick up at the relevant point.

Tom E
+2  A: 

One piece of advice: keep your test code in at least two layers of abstraction:

  1. upper layer: this should be some sort of a facade that is oriented towards your specific application terminology/actions etc. This layer does not directly use the Selenium RC library. In the background it uses the...
  2. ... lower layer: a library with some common testing patterns (example: "assert that the value X of the radio button control is chosen"), which uses the Selenium RC library.

This way your tests will be cleaner to maintain and more understandable in terms of what is being tested. We even tried a three-layered approach, the third (uppermost) layer being the tests specified using XML. This was in order for our non-programming testers to be able to specify acceptance tests without delving into the C# code.

Igor Brejc
+1  A: 

Basic guiding principle: if they want you to test something, testers need a way to get the application into that state, and once in that state, a way to validate that the state is correct.

So the first thing is to ensure they understand that automation is programming and the UI is your API.

  • Agreement to not arbitrarily change the UI -- if tester Bob see that the component changed from a button to a link, and it matches the spec, clicks and goes on. While a relatively easy code change in automation, it is a change that may have to be made in multiple locations. (your job as a tester is to understand that change happens and minimize the cost of maintenance; their job is to only make important changes and to understand the impact)

  • A way to determine which page you are on.... Bob can tell the difference between login and order entry, but how will automation know? If an enter field with the 'Username' label, the login page. If an entry field with Order number, the order field.

Not good -- better practice is a consistent UI element to identify the page -- page title, hidden component, etc.

  • A way to uniquely identify every element that you need to interact with (click, type in, verify, etc.) And not INPUT_42....

  • Ask the developers what information that testers can provide them to speed their debugging, and ask them to put it into a log file

  • Ability to dump state of the program

  • Consistent error handling & reporting (also just good UI design)

Klaus K