web-dev-qa-db-fra.com

Tests JUnit pour l'interface graphique en Java

Je voudrais écrire des cas de test pour une interface graphique. Je veux savoir comment simuler un clic de JButton ou extraire les éléments d'une JTable.

Pour ce faire, j'ai construit une interface graphique simple qui augmente le nombre de 1 si le bouton est cliqué et que le JTextfield est vide, mais le nombre est remplacé par l'entier du JTextfield si un nombre est fourni. Bien sûr, j'aimerais utiliser Regex pour m'assurer que le texte saisi dans le JTextfield est en fait un entier, mais supposons que les utilisateurs ne vont pas perdre leur temps et entrer un non-entier. De plus, JLabel met à jour le nombre actuel pendant que JTable ajoute une nouvelle ligne. 

Voici le 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();
            }
        });
    }
}

Supposons que je souhaite simuler l'ouverture de l'interface graphique, puis cliquez une fois sur le bouton sans saisir de texte, puis entrez 1234, cliquez sur le bouton, puis cliquez sur le bouton sans saisir de texte. La JTable doit comporter 3 colonnes: {{1,0 }, {1234, 1}, {1235, 1234}}. Comment puis-je écrire le test pour cela? Merci!

19
newtothissite

Java SE est livré avec un outil standard pour cela, la classe Robot . Je ne l'ai jamais utilisé que pour écrire des bots pour des jeux et pour contrôler à distance un ordinateur séparé via une paire serveur de connexion/client, mais il était en fait destiné à automatiser les tests et devrait donc fonctionner pour vous. Le format de base est 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);

Bien sûr, vous pouvez simuler des événements de clavier de manière similaire en utilisant les méthodes keyPress/keyRelease appropriées. J'ai parfois trouvé utile d'utiliser également la méthode screenCapture de la classe robot pour rechercher des images à l'écran et déterminer où cliquer. 

Remarque: cela n'exige pas que les fenêtres que vous testez soient construites sur awt/swing, cependant, cela nécessite que l'implémentation Java que vous utilisez utilise awt.

16
S E

AssertJ est un fork de FEST qui fonctionne très bien pour moi et supporte Swing . Le développement est actif (au moment de la rédaction), supporte Java 8, a des assertions pour quelques bibliothèques populaires telles que Guava et Joda Time et est très bien documenté. C'est aussi gratuit et ouvert.

4
Jwest08

Il y a quelques années, j'avais un projet dans lequel nous devions automatiser des tests.

Nous avons fini par aller avec:

jfcunit

Nous avons aussi essayé

fest - était bon, mais au moment de la rédaction de cet article, il n’y avait qu’un seul fil.

swingunit - aussi ok, mais nous avons eu quelques problèmes subtils, nous avons donc dû l'abandonner

2
Oliver Watkins

normalement, vous devez garder à l'esprit ce que vous souhaitez tester dans votre application. Les commandes indiquent que vous souhaitez tester les composants de l'application afin de vérifier si des modifications ultérieures affectant le format actuel ont eu lieu. la logique ou la méthode fournie dans l'application swing, c'est-à-dire si tout changement dans le flux affectera les instructions de retour. 

je vais placer un morceau de code de test

laisse envisager cette méthode de mise en œuvre

  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();
}

donc le cas de test suivant peut être (en utilisant 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);
    }

plus loin si vous voulez stimuler le clic de bouton, vous pouvez utiliser la méthode doClick de cette instance d'objet

    btn.run();
    b.doClick();

    String str=tf1.getText().toString();
    assertEquals("Welcome to junit.",str);
0
Akhil Vijayan

Généralement, une bonne pratique consiste à concevoir votre couche de vue aussi fine que possible afin de ne pas avoir à la tester et à vous concentrer sur une logique métier. Pour que les gens utilisent des modèles de conception tels que Model View Presenter ou Presentation Model.

Mais si vous devez tester l'interface graphique, vous pouvez essayer windowlicker: - https://code.google.com/p/windowlicker/

0
Luke