Skip navigation.

How Do You TDD UI?

How Do You TDD UI?

Something I've been experimenting with recently is Test-Driven Design (TDD) for user interfaces (UI). In brief (see Wikipedia for further details), with TDD you write a test, run it to be sure it fails, and then write just enough code to make it pass. The power here is that you are forced to specify what should happen before you write the code to make it happen, so you typically write simpler code and less of it.

You can imagine what this would look like using typical UI automation methods: a mess of intricate code that searches for and pokes specific bits of UI. The TDD ideal of tiny tests would be impossible to achieve. Similarly, any refactoring you later want to do (maybe you decide a check box works better than a drop-down list box, say) would be very difficult because you would have to wade through all of your tests looking for the ones that hit the refactored UI, and then figure out how to change them once you find them. This is not exactly agile development!

If you have a Physical Object Model, though, much of this messiness goes away. With a POM in hand you can focus on the UI itself rather than the details of interacting with it. Much of the refactoring you might want to do can be done transparently to your tests. (To continue the example, you just set a value regardless of whether you have a check box or a drop-down list box.) TDD can actually be useful.

If you take things one step further and build a Logical Functional Model you can really take advantage of TDD. The whole point of the LFM is to specify what should happen from your customer's point of view - which is exactly what makes TDD so helpful. Writing your TDD tests against an LFM gives you complete freedom to muck about with your UI while being confident that you aren't breaking the intent of your tests.

So TDD for UI can work, but is it useful in practice? I haven't made up my mind on that yet. But if you give it a try I would love to hear your thoughts!

 

*** Want a fun job on a great team? I need a tester! Interested? Let's talk: Michael dot J dot Hunter at microsoft dot com. Great coding skills required.

my experiences tdd-ing the GUI, web and desktop

Hi,

TDD on domains where automated tests are not that easy was always a concern of mine. In this order of
ideas, I and the my colleagues have explored automated tests on the GUI, both for desktop and web apps
in .NET as well as database data related automated tests. I said that my conclusions will be put in
several articles, however that's when I will have the time.

TDD on the GUI

I. The process

There are 3 fundamental steps in TDD on the GUI:

1. build the UI (a Windows.Form's Form for instance) , add the controls, name them right, but do not
add any functionality yet.
2.build the test - that means that on the form, you define the test code that tests how the form
should work. Run the test to make sure that it fails now, befote the UI has any functionality. This is
a guarantee that you don't build a wrong test that always succeds.
3. build the code for the UI until the code runs. Usually this means that VS.NET is put to start NUnit
(fit) when you click F5 and you code a little, then run, until the tests pass.

II. The tools

I am now only talking about .NET:
Web:
Selenium - http://selenium.thoughtworks.com - fit based, excellent tool
NUnitASP - http://nunitasp.sf.net - .net based

Windows.Forms
NUnitForms - http://nunitforms.sf.net - .net based
SharpRobo - http://gforge.public.thoughtworks.org/projects/sharprobo/ - fit based, written in .net as
an extention of fit

As it can be seen there are two kinds of tools that help the programmer work with the UI, and simulate
user interaction with the UI. One is based on code, and each control has a wrapper class that helps
interact with the control, called a Tester (NUnitForms and NUnitASP).Ex: for a login form with 2
textboxes and a button we test like:

//show form
Loginform = new LoginForm();
form.Show();

//initialise testers
txtUsernameTester = new TextBoxTester("admin");
txtPasswordTester = new TextBoxTester("adminpwd");
btnLoginTester = new ButtonTester("btnLogin");

//action
btnLoginTester.Click();

//asserts

For the other fit based tools, tests are written as HTML tables like (Selenium):

open | ./tests/html/test_type_page1.html
verifyElementPresent | username
type | username | TestUser
verifyValue | username | TestUser
verifyElementPresent | password
type | password | testUserPassword
verifyValue | password | testUserPassword
clickAndWait | submitButton
verifyTextPresent | Welcome, TestUser!


III. The architectural risks

The big problem when testing the UI is maintenability. The UI changes a lot and that makes the testing
code to be very easily maintenable. I have found two very important techniques:

1. Functional decomposition of tests - separate the tests into reusable and simpler units that can be
assembled together to make a test case.
2. Data separation - separate the data for the test from the test code
3. Test code generation
4. Simulating the UI test - using Model View Controller - MVC one can simulate the test of the UI, by
unit testing only the Controller and the Model. This is much more maintanable but is not very accurate.

These are only a few things I am trying to share from my experience testing the UI-s.

Thank you,

Dan Bunea
http://danbunea.blogspot.com

Comment viewing options

Select your preferred way to display the comments and click 'Save settings' to activate your changes.