Подтвердить что ты не робот

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}}. Как я могу написать тест для этого? Спасибо!

4b9b3361

Ответ 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);