The main difficulty in testing visual Delphi components is simulating mouse and keyboard events and testing the appearance of the components.
This article described a method to automate the mouse and keyboard and to compare screen-captures of the components with previous versions that are believed to be correct.
Automated "GUI" TestingThe code provided helps automate testing user interaction, in the following ways:
- Simulate Mouse and Keyboard Events
- Get Screen Captures of the Controls
- Compare the New Screen Captures to Old Ones
Borlands private "Zombie" program does something similar. Take a look at Steve Trefethen's blog on Zombie - the internal GUI automation framework
The most important unit in this demonstration of a method for testing visual components is "GuiTesterUnit.pas". It is used in a DUnit project to test two descendants of TStringGrid. The components themselves are not of particularly great interest. However, the code used to test the components is interesting.
Note: DUnit testing is included in BDS (Delphi) 2005 and 2006.
To run the test, you must first install the components. They are in RbwDataGrid4.pas. Then compile and run UnitTest1.exe in the DUnit subdirectory. The tests will display, interact with and capture bitmaps of the components in action. Screen captures of the bitmaps will be compared with those in UnitTest1.bmpcollection. Unless your computer is configured exactly the same as the one on which UnitTest1.bmpcollection was created, the bitmap comparisons will probably fail. However, if you select the "scripted" option when starting UnitTest1.exe, you will have an opportunity to compare the new and original bitmaps. You will also be given a description of what the control should look like. Click Yes or No depending on whether the control looks like what it should look like. When you click "Yes", the new bitmap will replace the old one in the collection (which will be saved when the application closes). If you run the tests again. All the bitmap comparisons for which you clicked "Yes" should now pass the test.
Do not move the mouse or press a key on the keyboard during the tests unless prompted to do so.
If you are interested in what the components can do, stop and restart UnitTest1.exe only this time select the "Manual" option. Follow the on-screen instructions for each test.
If you select the "fully automatic" option when starting UnitTest1.exe, it will run without interruption even if the bitmap comparisons fail. If a bitmap comparison fails, the test will fail. (With the "scripted option, if a bitmap comparison fails, you have to decide whether or not the test failed based on the on-screen instructions.
Here's an example of a test method:
procedure DragMouse(Start, Stop: TPoint) ; Const TenthSecond = 100; // 100 milliseconds - 1/10 second. This value works for me. begin MoveMouseToPosition(Start) ; MouseGoesDown; try MoveMouseToPosition(Stop) ; // To generate a mouse move event, enough time must elapse. // Empirically 1/20'th of a second is enough. Sleep(TenthSecond) ; Application.ProcessMessages; finally MouseGoesUp; Application.ProcessMessages; end; end;