BillWake provides excellent guidance:
It doesn't address every issue with testing GUIs (by any means!) but I created a small example that gives the feel of testing and coding a Java GUI, at http://www.xp123.com/xplor/xp0001/index.shtml
Bill, this is fabulous! Please publish it somewhere soon. -- KentBeck
This is fabulous!! This will really help out our Java people with the problem of Java GUI testing. -- sg
The above is now Chapter 31 of ExtremeProgrammingInstalled
One Java-specific thing that I would add to that great article (if I could) or to this page in general, is the information formerly found at http://jfcunit.sourceforge.net/
under the paragraph, "Need for JFCUnit". (Page has now changed, paragraph is missing). I've moved that information to JavaGuiUnitTesting
, where I intend to start a discussion of such issues that are too specific to Java to exist here. -- JeffTulley
Just for a change, I'm going to disagree with Bill on this one. I think that the code for his GUI stinks - it's totally unrealistic. Why would the search button be a public attribute on its panel? This applies to most of the other elements too. If I were writing this GUI I'd use a local reference when I instantiate the button, add it to the form, and set its actionListener to be an instance of my controller (which I'd have passed in to the panel's constructor), then I'd let the local reference just drop out of scope. There is no further need to reference the button. At some point in the panel's constructor I'd also have passed a reference to the text field to the controller, and again I'd have then dropped my local reference to it, because it's no longer needed.
The JTable is an observer of its model. I'd have implemented a wrapper around my domain model to support the necessary interface for the JTable. Again, this would require me to expose no reference to the JTable.
Without exposed references GUIs are terribly difficult to test. Bill's tests drove the development of the interface, but the implementation has been generated to facilitate the tests, not to maintain common idioms or even good OO practices. It's good practice to encapsulate as much as possible, even in the GUI - Bill's implementation exposes too much, and it does so purely for the sake of testing.
SebastianPetzelberger asks (about the C3 project):
The tests run in 10 minutes. ... How can you end up in such a short time? And how about testing the GUI? Are you testing a window without opening it?
We do some testing of GUIs without opening them. Our system does not have many GUIs, so we do not have very much intelligent to say about testing them. Of course, if you have kept the model very separate from the GUI, most of the testing can be done on the model side.
I had one case where I had some logic in a GUI COM control which really should have been in a domain class. Unit testing a GUI COM control is pointless, so I ended up doing ArchitecturalSubstitution
. I duplicated the logic in a new class by writing UnitTest
s first, and I kept compiling the new class into the application also, calling the methods on the new object and the control in parallel and verifying that they did the same thing. When I saw, through interaction with the live app, that the new class was doing what I wanted, I dropped the calls to the control and deleted the methods, leaving the calls to the new class. I now had a new class with tests. At each point in the process, I asked myself: "What is the smallest step that I can take towards the goal that keeps everything working?" One could say that the legacy code was the spec for the new code. Of course, now that the tests exist, I can refactor the hell out of it fearlessly.
I think much of my answer is in what Mike said above but I don't understand it fully. My developers are writing unit tests for their classes and their COM components and that is fairly easy. They write an MFC test application that uses the COM control or component and just calls its methods and such. Now in my case, I am doing the GUI. The GUI COM app is a Java or MFC/C++ Windows Application. How do I write UnitTest
s for it? How do I drive the application? Essentially users would just point and click. They would select things off menus and so forth. I guess this a general question of how you write UnitTest
s for Windows GUI applications in ExtremeProgramming
. -- sg
In general, GuiTesting is difficult.
For several reasons, it is a good idea to design GUI applications
to communicate with a back-end via some command language.
- Doing so allows power users to easily automate tasks.
- The command language can be used to automate integration testing.
- The design of the command language creates a clear divide between the GUI code and the object model.
- If a bug is discovered, then the command stream can be recorded, greatly simplifying fault analysis.
There are tools that record keystrokes and mouse clicks and recognize common controls. These tools can be used for scripting GUI tests. SQA Robot is an example. -- CayteLindner
...And the story ends like this:
9) A year+ later it is noticed that the GUIs have no automated tests and are of increasingly low quality and have long manual test cycles. A new manager decides to do something about it and we proceed to step 1.
Extracted from GuiTesting
How can you generate useful UnitTest
s for user interface code? Much of our code is visual C++ MFC based code. I can easily write unit tests for my own classes, for each function and module, but have real difficulty seeing how to apply this to the large classes the visual c++ generates. I can't test all of the functionality because it would take literally weeks to write the test code even if you could isolate the individual user interface classes, and it's all so dependent on user interaction anyway.
Looking for any suggestions or comments. -- JohnBurton?
A while back, I tried to start a discussion on this topic over in GuiTesting. There's some useful stuff there, but I wish there were more. It seems to be a hard problem.
My thoughts are that you need to design your gui software with the thought that it needs to run automated tests. Make sure that the classes (functions, whatever) that handle the user interface have the minimum of code. Delegate all
of the work that actually runs the application to modules that are
testable. At least this minimizes the amount of code that can't be automatically unit tested and reduces the impact of any faults that exist in it. -- JohnBurton?
you'll be finding version 2.1 of DelphiUnit
. It also has a GUI driver, complete with a little scripting language. -- SergeBeaumont
code that presses the buttons, and inspects the resulting DOM.
If you want to test browser-based UIs, you should use JS Unit http://www.edwardh.com/jsunit/
instead of using the frameset approach. -- Espen Dalløkken
Here's something new, a GUI aware programming IDE to automate UnitTest
s -- ChrisGarrod
just found it, nothing to do with it's invention or propagation yet:
and the home site for Sikuli - see its blogs for newer examples
Freely available (MitLicense
) for Windows, Mac, Linux, and anything with Java (perhaps).
We need a SikuliPage?
, but I'm not very good at naming pages at WardsWiki