I would like to write test cases for a GUI. I want to know how do you simulate a click of JButton, or how do you extract the elements of a JTable.
For the purpose of this, I have built a simple GUI that increase the count by 1 if the button is clicked and the JTextfield is empty, but the count is replaced by the integer in the JTextfield if a number is provided. Of course I would like to use Regex to make sure the text entered into the JTextfield is actually an integer, but let's assume users won't mess around and enter a non-integer. In addition, the JLabel updates the current count while the JTable adds a new row.
Here's the code:
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.GroupLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.table.DefaultTableModel; public class sampleGUI extends JFrame implements ActionListener { private Integer previous_count; private Integer current_count; private JButton Button; private JTable table; private JTextField text; private DefaultTableModel model; private JScrollPane scroll; private JLabel label; public sampleGUI() { previous_count = null; current_count = 0; JFrame frame = new JFrame("Sample"); JPanel panel = new JPanel(); GroupLayout layout = new GroupLayout(panel); panel.setLayout(layout); label = new JLabel("Current Count: " + Integer.toString(current_count)); text = new JTextField(15); Button = new JButton("Change the Count!"); model = new DefaultTableModel(); model.addColumn("Previous Count"); model.addColumn("Current Count"); table = new JTable(model); scroll = new JScrollPane(table); layout.setHorizontalGroup(layout .createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup( layout.createSequentialGroup().addComponent(label) .addComponent(text).addComponent(Button)) .addComponent(scroll)); layout.setVerticalGroup(layout .createSequentialGroup() .addGroup( layout.createParallelGroup( GroupLayout.Alignment.BASELINE) .addComponent(label).addComponent(text) .addComponent(Button)).addComponent(scroll)); Button.addActionListener(this); frame.add(panel); frame.pack(); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == Button) { if (text.getText().equals("")) { previous_count = current_count; current_count++; label.setText("Current Count: " + Integer.toString(current_count)); model.addRow(new Object[] { current_count, previous_count }); } else { previous_count = current_count; current_count = Integer.parseInt(text.getText()); label.setText("Current Count: " + Integer.toString(current_count)); text.setText(""); model.addRow(new Object[] { current_count, previous_count }); } table.changeSelection(table.getRowCount() - 1, 0, false, false); } } public static void main(final String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { sampleGUI gui = new sampleGUI(); } }); } }
Let's say I would like to simulate opening the GUI, then click the button once without entering any text, then enter 1234 and click the button, then click the button without entering any text, the JTable should have 3 columns: {{1,0}, {1234, 1}, {1235, 1234}}. How can I write the test for that? Thanks!
The central class of JUnit is TestCase, which represents a fixture that provides the framework to run unit tests and store the results.
Besides manual testing, JUnit is preferred equally for automation testing. It can also be used along with the Selenium WebDriver to automate tests for web applications. It provides a unique way to write structured, short, and better test cases.
JUnit can be used as a test runner for any kind of test: e.g. system and integration tests; tests which are interacting with a deployed application.
JUnit is an open source unit testing tool that helps to test units of code. It is mainly used for unit testing Java project, however, it can be used with Selenium Webdriver to automate testing of Web applications. So you can even perform automation testing of a web application with JUnit.
Java SE comes with a standard tool for doing just this, the Robot class. I've only ever used it to write bots for games and to remotely control a separate computer via a socket server/client pair, but it was actually intended to automate testing, and so it should work for you. The basic format is simple:
Robot bot = new Robot(); bot.mouseMove(10,10); bot.mousePress(InputEvent.BUTTON1_MASK); //add time between press and release or the input event system may //not think it is a click try{Thread.sleep(250);}catch(InterruptedException e){} bot.mouseRelease(InputEvent.BUTTON1_MASK);
Of course you can simulate keyboard events in a similiar way as well using the appropriate keyPress/keyRelease methods. I've sometimes found it useful to use the screenCapture method of the robot class as well to seach for images on the screen and determine where to click.
Note: this does not require that the windows you are testing are built on awt/swing, however it does require that the java implementaton you are using supports awt.
AssertJ is a fork of FEST that is working very well for me, and has support for Swing. Development is active (at time of writing), supports Java 8, has assertions for a few popular libraries such as Guava and Joda Time, and is very well documented. It is also free and open.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With