Alex Ruiz likes to read anything with Java
Data related to development, testing, object-oriented programming, Aspect-Oriented Programming, and concurrency. Programming is his favorite. Alex is the creator of fest and fest is an innovative Java
Library, mainly used to simplify swing and javafx testing and comprehensive testing. He works as a software engineer at Oracle development tools. Go to Oracle
Previously, Alex was a consultant for thoughtworks. View Alex's blog
.
Introduction:
When you need to use or maintain other Java
Debugging and testing help you understand how your code works. However, for visual code, these powerful practical methods are more difficult to use unless you have the right tools. Two open-source tools introduced in this article-
Swing explorer and Fest-swing-make the swing UI debugging and testing simple and reliable. Alex Ruiz
Demonstrate how to use these two tools to understand the UI structure, test its functions, and troubleshoot.
Swing is a powerful GUI toolkit that is scalable, configurable, and cross-platform. However, swing's flexibility is both its main advantage and its major weakness. Swing
You can build the same UI in different ways. For example, you can use a plug-in, a blank border, or padding to place an interval between GUI components. Considering that there are too many swing options, you can understand the existing GUI.
It is as daunting as writing a new GUI, and it is not easy to map its visual appearance to the underlying code. (Try to read severalGridBagLayout
In the code line, imagine the GUI .)
Whether you are maintaining a swing GUI that has never been written or integrating a third-party Gui
A reasonable way to understand the code of Components in your application is to compile the test. While writing and testing, you are also familiar with the internal structure of unknown code. This will produce another valuable result, that is, you
Eventually there will be a test suite that helps prevent regression introduction while maintaining code. For third-party GUI components, the test suite helps identify whether any behavior changes are introduced in the new library version.
At first, it is best to write a function test to understand how the GUI responds to user input. Writing a test for GUI is more complex than writing a test for non-visualized code, because:
- Theoretically, testing must be automated, but the GUI is intended for humans rather than computer programs.
- Traditional unit tests involve isolation tests and are not suitable for GUI components. In GUI terms, a "unit" involves multiple guis
Component collaboration, so it contains more than one class.
- The GUI responds to user-generated events. To test
Gui, you need a method that can simulate user input, wait until the generated events are distributed to all listeners, and then check the results, just as the GUI responds to users. Compile a simulated user and Gui
Interactive code is cumbersome and error-prone.
- Modifying the GUI layout should not affect strong functional tests.
Another problem is that you must be familiar with the structure and behavior of the GUI to be tested. Otherwise, you do not know which components should be used for automated testing and what needs to be verified. All in all, you need to write a GUI
Test, you must know:
- Components used for testing in Gui
- How to uniquely identify such a component in a test
- Expected States (or attributes) of components in a specific use case)
You can use visual design tools (such as netbeans Matisse) to understand the GUI structure. However, this tool only displays the GUI
Design time information, which is different from what you see at runtime. For example, some components may be displayed as visible or invisible based on user input.
Traditional debugging programs cannot help you understand the GUI status when executing specific use cases. When the debugging program stops the breakpoint set in the swing code, the GUI drawing is interrupted
The GUI looks like a blank box. Ideally,When
When you use a debug program for One-Step debugging, you want to see how the gui works.
Fortunately, two open-source tools-swing explorer and Fest-swing-can help you quickly understand the existing swing
Code. This article describes these tools to show you how to use them together to check the GUI structure of the application, test its functions, and identify potential problems.
Application to be explored
For most examples of this article, I will use a free functional HTML file named html#enteditor.
Editor, which serves as the application to be tested. If you want to complete the example, you can download
Application and sample test code. Figure 1 shows the running html#enteditor:
Figure 1. HTML editor
Before writing a GUI test, you need to understand the GUI composition method. The HTML editor is simple and contains a text area and several HTML files for opening, saving, and editing.
Document menu.
It is also important to be familiar with the specific types of each component. This helps you understand the actions or Attributes provided by GUI components for testing through APIS. For HTML
Editor, You need to determine whether the text area isJTextArea
,JTextPane
Or a common
Gui components. One way to determine the GUI component type is to check the source code.
Based on the GUI implementation method, this can be a simple task or a challenging task. Html#enteditor
The source code is readable and easy to understand. After checking the source code quickly, it is found that the text area isJTextPane
. However, during your technical career, you may encounter a lot of problems.
Poor GUI code, which is hard to understand. In this case, you can spend a lot of time deciphering the code, or find a tool that provides effective help.
About swing Explorer
Swing Explorer allows you to visually check the internal structure of swing guis. Its simple and intuitive UI makes it easier for us to discover all the components in the GUI, investigate the drawing method, and check the attributes of any time.
Swing Explorer can be used in eclipse and netbeans as independent applications and plug-ins at the same time. We recommend that you use ide
Plug-in. In this article, I will use the Eclipse plug-in.
After installing the plug-in, I started the main class of the HTML editor using swing explorer, as shown in Figure 2:
Figure 2. Editor application started in swing Explorer
Swing explorer provides multiple views to help you find out the internal structure of the swing Gui:
- Display a Tree View of the Component Hierarchy
- Check Gui
- A tab panel that displays the attributes of the selected component (name, size, etc.) and contains other useful and interesting tools
It is easy to use swing explorer to understand the GUI structure. For the purpose of this exercise, it is assumed that you cannot find
The type of components used as text areas in the editor. With swing explorer, you only need to select the text area on the component Tree View or click GUI
Component itself. In Figure 3 below, swing explorer confirms that the text area isJTextPane
:
Figure 3. Swing Explorer with the selected component attributes
Understand and test application Behavior
Once the GUI to be tested is determined
The next step is to understand the behavior of the application so that you can know the expected values to be verified. This can be done in different ways: Meet the current end user and read the application documentation (if there are
Or simply use the application itself.
At the beginning, I will select two test cases for testing:
- Open an HTML file
- Change the document font color
Now I am ready to start writing functional GUI tests.
Function GUI test to verify that the application runs as expected. It focuses on the behavior of applications, rather than the appearance of the GUI.
The following factors are essential for creating strong functional GUI tests:
- Ability to simulate user input (keyboard and mouse)
- Reliable mechanism for searching GUI Components
- Allows changes in component position or layout
Fantasy: Use it directlyRobot
To make sure that an automated test can truly simulate user input, you need to generate "native" events at the operating system level, just as if the user is using the keyboard and mouse.
JDK has passed Abstract Window Toolkit (AWT) Since version 1.3)Robot
Supports input simulation. HoweverRobot
Valid only for screen coordinates, but for Swing
The component reference is invalid, so using it directly can make the test very fragile, which means that any layout change will stop the test.
And AWTRobot
The level is too low; it only knows how to click the mouse button and button. You need to write code that can translate advanced actions, suchSelect this
The third element in the combo box
PutRobot
Action. Depending on the number of actions required for the test and the types of related components, this requires a lot of work.
In addition, AWTRobot
Not for component query (such as searchButton with "OK" Text
) Provides a reliable mechanism. You still need
Write your own code.
All in all, use AWT directlyRobot
It takes a lot of effort and time. When writing a function Gui
During testing, you need to focus on the behavior to be verified, rather than on the underlying pipeline that makes GUI testing possible.
Fest-swing Introduction
The fest (fixtures for easy Software Testing) Swing module allows you to easily create and maintain a robust functional GUI.
A library to be tested.
Its main features include:
Use Fest-swing to write functional GUI tests
At present, we have learned about the GUI structure of the editor application, collected the test cases to be tested, found a reliable test tool, and finally began to write functional GUI tests.
Use Case: open an HTML file
To open a file in the HTML editor, perform the following operations:
- Select File> open sub-menu
- Select the file to open from the displayed file Selector
- Make sure that the editor loads the File Content
Listing 3 shows the code for this case:
Listing 3. Test opening an HTML file
public class HTMLDocumentEditor_Test extends FestSwingJUnitTestCase {
private FrameFixture editor;
protected void onSetUp() { editor = new FrameFixture(robot(), createNewEditor()); editor.show(); }
@RunsInEDT private static HTMLDocumentEditor createNewEditor() { return execute(new GuiQuery<HTMLDocumentEditor>() { protected HTMLDocumentEditor executeInEDT() { return new HTMLDocumentEditor(); } }); }
@Test public void should_open_file() { editor.menuItemWithPath("File", "Open").click(); JFileChooserFixture fileChooser = findFileChooser().using(robot()); fileChooser.setCurrentDirectory(temporaryFolder()) .selectFile(new File("helloworld.html")) .approve(); assertThat(editor.textBox("document").text()).contains("Hello"); } }
|
The test in listing 3 is described as follows:
- The first line expands the fest-swing
FestSwingJUnitTestCase
. It provides
Fest-swingRobot
Is automatically created for the correct swing
Thread verification (detailed later), automatic cleaning of resources (Closing open windows, releasing the mouse and keyboard, etc ).
editor = new FrameFixture(robot(), createNewEditor());
Create a newFrameFixture
InFrame
Simulate user input, query its internal components (using multiple search criteria) and verify its status.
editor.show();
The HTML editor is displayed on the screen.
@RunsInEDT
Ensure that the log is executed in the event scheduling thread (EDT)createNewEditor()
Method.
return execute(new GuiQuery<HTMLDocumentEditor>()
Creating EDTHTMLDocumentEditor
.
- In
editor.menuItemWithPath("File", "Open").click();
In, Fest-swing simulates a user and click File> open sub-menu.
- In
JFileChooserFixture fileChooser =
findFileChooser().using(robot());
In, Fest-swing searches for
"Open file"JFileChooser
.
- In the next three lines, the fest-swing simulated user selects the helloworld.html file in the temporary system folder.
assertThat(editor.textBox("document").text()).contains("Hello");
Check whether the file containsHello
To verify whether the file is loaded into the editor.
Note that listing 3 is based on the name (editor
) QueryJTextPane
. This is the most
It ensures that component search never fails, even if the GUI layout changes in the future.
Use Case: Change the document font color
To verify that the HTML editor changes the document font color to yellow, you need:
- Select color> yellow sub-menu
- Enter content in the editor
- Verify that the color of the input text is yellow.
Listing 4 shows how to use Fest-swing to perform the preceding operations:
Listing 4. Testing to change the document font color
@Test public void should_change_document_color() { editor.menuItemWithPath("Color", "Yellow").click(); JTextComponentFixture textBox = editor.textBox(); textBox.enterText("Hello"); assertThat(textBox.text()).contains("<font color=/"#ffff00/">Hello</font>"); }
|
So far, I have demonstrated how to test simple GUI components, such as menus and text boxes. Next, I will introduce an intuitive test mode.
More complex tests
To demonstrate the visual and compact APIs of Fest-swing, I will use a highly complex component of swing-
JTable
.
I will useTableDialogEditoDemo
Application. This application usesJTable
:JComboBox
Es andJCheckBox
Es,
4:
Figure 4.TableDialogEditDemo
As an example, I will write a test to simulate the second element in the combo box where the user selects 0 rows. The action to perform the test is:
- Scroll up or down the table as needed to make the row visible.
- Click the cell in column 0th of row 2nd.
- Wait until the combo box appears.
- Find and click the combo box.
- Select the second element from the combo box.
This is just a rough description of the action I want to code. Writing real code is not trivial. Fortunately, the fest-swing API simplifies this task, as shown in listing 5:
Listing 5. Select the third element in the combo box where the row is 0
dialog.table.enterValue(row(0).column(2), "Knitting");
|
Fest-swing can simplify the compilation and reading of GUI tests and even complex tests.
Swing thread
Swing is a single-threaded UI toolkit. Because it is not thread-safe, all swing code must be executed in EDT. As described in the official documentation
Swing code may cause thread conflicts or memory consistency errors.
Swing thread policy status:
- The swing component must be created in EDT.
- Swing components must be accessed in EDT unless you call the document as a thread-safe method.
Although this seems simple, it is easy to break rules. Swing does not provide any runtime check for correct EDT usage, and most of the time it appears to be "performing well"
Swing UI actually destroys these rules.
Both swing explorer and Fest-swing support searching for violations of swing thread policies. Figure 5 shows the swing Explorer
EDT monitor. The EDT monitor can report EDT access violations when executing applications.
Figure 5. EDT Monitor of swing Explorer
Fest-swing providesFailOnThreadViolationRepaintManager
To check
EDT violations. If any violation is detected, it will force the test to terminate. The configuration is simple:@BeforeClass
Annotated
Put it in the set-up method, as shown in Listing 6:
Listing 6. InstallationFailOnThreadViolationRepaintManager
@BeforeClass public void setUpOnce() { FailOnThreadViolationRepaintManager.install(); }
|
In addition, you can use the fest-swingFestSwingTestngTestCase
OrFestSwingJunitTestCase
Sub-classes. These two classes have been installed.FailOnThreadViolationRepaintManager
.
Fest-swing also provides useful abstract classes to ensure that access to swing components is completed in EDT. For more information, see.
Gui test failure troubleshooting
Regardless of the library used for writing functional GUI tests, such tests are vulnerable to environment-related events. Fest-swing
Is no exception. For example, a pre-scheduled anti-virus scan may pop up a dialog box to block the GUI being tested. Fest-swingRobot
You will not be able to access the GUI and eventually force the test to terminate due to timeout. Test failure is not caused by program errors, but out of date.
One of the most useful features of Fest-swing is that it can ingest desktops when a test fails. When you perform a single test in the IDE, the test is automatically embedded in JUnit or
The testng report or saved in the directory. Figure 6 shows a JUnit HTML report after the GUI test fails. Note: When the test fails
Add the fest-Swing Link to the desktop.
Figure 6. JUnit HTML report linking from failure test to desktop
Another common cause of test failure is component query failure. The recommended query component is queried based on the unique component name. Sometimes you want to test the GUI
The component does not have a unique name, so you can only use the general search criteria. Two types of component query failed:
- The GUI component cannot be found.
For example, assume that the query name isfirstName
OfJTextField
But the original developer forgot to assign the name to the component. In this case, Fest-swingComponentLookupException
Contains available component hierarchies, making it easy to find the cause of failure. In this example, you can check the Component Hierarchy to viewJTextField
Is there a correct name or is it trueJTextField
Add to Gui. Listing 7 showsComponentLookupException
Component Hierarchy in:
Listing 7.ComponentLookupException
org.fest.swing.exception.ComponentLookupException: Unable to find component using matcher org.fest.swing.core.NameMatcher[name='ok', requireShowing=false].
Component hierarchy: myapp.MyFrame[name='testFrame', title='Test', enabled=true, showing=true] javax.swing.JRootPane[] javax.swing.JPanel[name='null.glassPane'] javax.swing.JLayeredPane[] javax.swing.JPanel[name='null.contentPane'] javax.swing.JTextField[name='name', text='Click Me', enabled=true]
|
The Component Hierarchy in listing 7 helps you infer that the original developer isJTextField
The error name is provided. The current name is notfirstName
,
But it should bename
.
- Find multiple GUI components.
This happens when multiple GUI components match a given search criteria. For example,firstName
May be accidentally provided to twoJTextField
. When the query name isfirstName
OfJTextField
The query fails (and the test is terminated) because the two components have the same name. To help you diagnose this problemComponentLookupException
Show all matching components found, as shown in listing 8:Listing 8.ComponentLookupException
Contains a list of components that match a search criterion.
org.fest.swing.exception.ComponentLookupException: Found more than one component using matcher org.fest.swing.core.NameMatcher[ name='firstName', type=javax.swing.JTextField, requireShowing=false].
Found: javax.swing.JTextField[name='firstName', text='', enabled=true] javax.swing.JTextField[name='firstName', text='', enabled=true]
|
SometimesComponentLookupException
It is difficult to check the Component Hierarchy, especially when you are dealing with a GUI containing a large number of components. Swing explorer provides great help again here.
As shown above, you only need to click a component to select and check the properties of any component in the component hierarchy. The big Component Hierarchy Is In The GUI of swing Explorer
ComparedComponentLookupException
The text-based representation provided is much easier to understand.
Conclusion
The power of swing is at the cost of its complexity. Understanding swing code is as challenging as writing it. To explore unknown guis
Writing and testing code is more complex than writing and testing non-visual code. Fortunately, swing explorer and Fest-swing
It can help you free yourself from this monotonous job. Swing Explorer allows you to explore the GUI structure when an application is running. Once you understand what you want to test
After the structure and behavior of the GUI, you can use the fest-swing compact and intuitive API to write functional GUI tests. Besides its coherent APIs
In addition, Fest-swing verifies the correct use of swing threads and features, which is in the case of a failed Gui
This helps you save time during testing. This article only describes some basic functions of these powerful tools.
A better solution similar to swing explorer and Fest-swing is a record/playback tool that records Java
User interaction in the code, just as it is manually created by the developer. The record/playback tool provides you with a test suite in the shortest time. You and the existing Gui
Interaction, and all events generated by the user are recorded in a script. Later, you can play back the script to recreate user interaction for a specific scenario. The main weakness of existing recording/playback tools is the maintenance of Test Generation.
Very expensive. Any changes to the application must record all test scenarios. In addition, when testing similar scenarios, record all test scenarios to create repeated test code. The recorded script is usually very long,
It is written in specialized languages and lacks the object-oriented language features. The modularization of repetitive actions requires a lot of work, which is easy to produce errors, and usually requires a new programming language.
By using a record/playback tool based on a popular and mature OO language-Java language-, developers can enjoy the rich functionality of the IDE
It brings many benefits. These ides can make tedious and error-prone tasks (such as code refactoring) fast and insignificant, so as to improve efficiency and reduce maintenance costs. This is exactly what Fest
The project team is currently focusing on the development of a playback/record tool that can use the fest-swing Java API to generate a completely object-based GUI.
Test. We hope to see this tool before March 13, second quarter of 2010.
Download
Description |
Name |
Size |
Download Method |
Sample GUI Test |
Jswingtest-code.zip |
1.28 MB |
HTTP |
References
Learning
- Swing Explorer
: Access
Swing explorer project site.
- Fest-swing
:
Find links to documents, articles, and software downloads.
- "Writing EDT-safe
Swing UI tests
"(Alex Ruiz's blog, July 2009): describes how to follow the swing thread policy to write test cases.
- "Pursuing code quality:
Use testng-Abbot for automated GUI Testing
"(Andrew Glover, developerworks, 2007 2
Month): Read the GUI test related to testng-Abbot. testng-Abbot is a test tool before Fest-swing.
- "WYSIWYG
HTML editor with jeditorpane and htmleditorkit
"(Artima.com, February 2, 2002
Month): Charles Bell released the html#enteditor source here.
- How
To use tables
: This is a swing tutorial on how to use tables.
Obtain products and technologies
- Swing
Explorer
: Download the swing explorer or swing Explorer plug-in.
- Fest
: Download
Fest-swing.