JUnit Тесты для GUI в Java
Я хотел бы написать тестовые примеры для графического интерфейса. Я хочу знать, как вы имитируете щелчок JButton, или как вы извлекаете элементы JTable.
Для этого я построил простой графический интерфейс, который увеличивает число на 1, если кнопка нажата, а поле JText пусто, но число заменяется целым числом в поле JText, если предоставляется число. Конечно, я хотел бы использовать Regex, чтобы убедиться, что текст, введенный в поле JTextfield, на самом деле является целым числом, но пусть предполагают, что пользователи не будут возиться и ввести нецелое число. Кроме того, JLabel обновляет текущий счет, а JTable добавляет новую строку.
Здесь код:
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();
}
});
}
}
Скажем, я хотел бы симулировать открытие GUI, затем один раз щелкнуть по кнопке без ввода какого-либо текста, затем ввести 1234 и нажать кнопку, затем нажать кнопку без ввода какого-либо текста, JTable должен иметь 3 столбца: {{ 1,0}, {1234, 1}, {1235, 1234}}. Как я могу написать тест для этого? Спасибо!
Ответы
Ответ 1
Java SE поставляется со стандартным инструментом для этого, Robot. Я только когда-либо использовал его для написания ботов для игр и дистанционного управления отдельным компьютером через пару сокетов/клиента, но он был фактически предназначен для автоматизации тестирования, и поэтому он должен работать на вас. Основной формат прост:
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);
Конечно, вы можете имитировать события клавиатуры аналогичным образом, используя соответствующие методы keyPress/keyRelease. Иногда мне было полезно использовать метод screenCapture для класса робота, а также для поиска изображений на экране и определения того, где щелкнуть.
Примечание. Это не требует, чтобы проверенные вами окна были построены на awt/swing, однако для этого требуется, чтобы исполняемый файл java поддерживал awt.
Ответ 2
У меня был проект несколько лет назад, где нам нужно было автоматизировать тесты.
Мы закончили с:
jfcunit
Мы также опробовали
fest - был хорош, но на момент написания был только однострочный.
swingunit - тоже хорошо, но у нас было несколько тонких проблем, поэтому нам нужно было остановить его
Ответ 3
AssertJ - это fork FEST, который работает очень хорошо для меня и поддерживает Swing. Разработка активно (на момент написания), поддерживает Java 8, имеет утверждения для нескольких популярных библиотек, таких как Guava и Joda Time, и очень хорошо документирована. Он также свободен и открыт.
Ответ 4
Как правило, хорошей практикой является создание слоя вашего представления как можно более тонким, поэтому вам не нужно его тестировать, и вы фокусируетесь на бизнес-логике. Чтобы добиться того, что люди используют шаблоны проектирования, такие как Model View Presenter или Presentation Model.
Но если вам нужно протестировать GUI, вы можете попробовать windowlicker:
- https://code.google.com/p/windowlicker/
Ответ 5
обычно вам нужно помнить о том, что вы хотите протестировать в своем приложении. Скажем, вы хотите протестировать компоненты в приложении, чтобы проверить, произошли ли какие-либо изменения в будущем, которые влияют на текущий формат. второй, чтобы проверить логику или метод, предоставляемые в приложении swing, то есть, будет ли какое-либо изменение потока воздействовать на операторы return.
я поместит кусок тестового кода
рассмотрим этот метод реализации
public void activate()
{
f=new JPanel();
tf=new JTextField();
tf.setBounds(50,50, 150,20);
tf.setName("b1");
b=new JButton("Click Here");
b.setName("Click Here");
b.setBounds(50,100,95,30);
f.add(b);
f.add(tf);
f.setSize(400,400);
f.setLayout(null);
f.setVisible(true);
//b.doClick();
}
, поэтому следующий тестовый пример может быть (с использованием junit)
@Test
public void testActivate()
{
btn=new Button();
assertNotNull(btn);
JPanel jf=btn.f;
btn.activate();
int height=b.getHeight();
int width=b.getWidth();
assertEquals(30,height);
assertEquals(95,width);
int x=b.getX();
int y=b.getY();
assertEquals(50,x);
assertEquals(100,y);
int x1=tf.getX();
int y1=tf.getY();
assertEquals(50,x1);
assertEquals(50,y1);
}
далее, если вы хотите стимулировать нажатие кнопки, вы можете использовать метод doClick этого экземпляра объекта
btn.run();
b.doClick();
String str=tf1.getText().toString();
assertEquals("Welcome to junit.",str);