JUnit testuje GUI w Javie
Chciałbym napisać przypadki testowe dla GUI. Chcę wiedzieć, jak symulować kliknięcie JButton, lub jak wyodrębnić elementy JTable.
W tym celu zbudowałem prosty GUI, który zwiększa liczbę o 1, Jeśli przycisk jest kliknięty, a pole JTextfield jest puste, ale liczba jest zastępowana liczbą całkowitą w polu JTextfield, jeśli podano liczbę. Oczywiście chciałbym użyć Regex, aby upewnić się, że tekst wprowadzony do JTextfield jest rzeczywiście liczbą całkowitą, ale Załóżmy, że użytkownicy nie zadzierają i nie wprowadzają liczby całkowitej. Ponadto Etykieta JLabel aktualizuje bieżącą liczbę, podczas gdy tabela JTable dodaje nowy wiersz.
Oto kod:
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();
}
});
}
}
Powiedzmy, że chciałbym symulować otwieranie GUI, a następnie kliknąć przycisk raz bez wpisywania tekstu, a następnie wpisać 1234 i kliknąć przycisk, a następnie kliknąć przycisk bez wpisywania tekstu, JTable powinien mieć 3 kolumny: {{1,0}, {1234, 1}, {1235, 1234}}. Jak mogę napisać do tego test? Dzięki!
5 answers
Java SE jest dostarczana ze standardowym narzędziem do tego celu, klasą Robot. Używałem go tylko do pisania botów do gier i zdalnego sterowania oddzielnym komputerem za pomocą pary Serwer/Klient gniazda, ale w rzeczywistości był przeznaczony do automatyzacji testów, więc powinien działać dla Ciebie. Podstawowy format jest prosty:
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);
Oczywiście można symulować zdarzenia klawiatury w podobny sposób, jak również za pomocą odpowiednich metod keyPress/keyRelease. Czasami uważam, że jest to przydatne w użyciu metoda screenCapture klasy robota, a także seach dla obrazów na ekranie i określić, gdzie kliknąć.
Uwaga: nie wymaga to, aby testowane okna były zbudowane na awt/swing, jednak wymaga, aby implementacja Javy, której używasz, wspierała awt.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-07 12:17:16
AssertJ to widelec FEST, który działa bardzo dobrze dla mnie i ma wsparcie dla Swing . Rozwój jest aktywny (w momencie pisania), obsługuje Javę 8, posiada asercje dla kilku popularnych bibliotek, takich jak Guava i Joda Time, I jest bardzo dobrze udokumentowany. Jest również bezpłatny i otwarty.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-24 21:28:57
Kilka lat temu miałem projekt, w którym musieliśmy zautomatyzować testy.
Skończyło się na:
Jfcunit
Wypróbowaliśmy również
Fest - był dobry, ale w momencie pisania był tylko jeden gwint.
Swingunit - również ok, ale mieliśmy kilka subtelnych problemów, więc musieliśmy go porzucić
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-17 15:58:04
Ogólnie dobrą praktyką jest zaprojektowanie warstwy widoku tak cienkiej, jak to możliwe, aby nie trzeba było jej testować i skupić się na logice biznesowej. Aby upewnić się, że ludzie używają wzorców projektowych, takich jak Model View Presenter lub Model prezentacji.
Ale jeśli musisz przetestować GUI to możesz spróbować windowlicker: - https://code.google.com/p/windowlicker/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-17 14:16:35
Zwykle musisz pamiętać o tym, co chcesz przetestować w swojej aplikacji.powiedzmy, że chcesz przetestować komponenty w aplikacji, aby sprawdzić, czy w przyszłości miały miejsce jakiekolwiek zmiany, które wpływają na bieżący format.a po drugie, aby sprawdzić logikę lub metodę dostarczoną w aplikacji swing tj., czy jakakolwiek zmiana w przepływie spowoduje wystąpienie instrukcji return.
Umieszczę fragment kodu testowego
Rozważmy tę implementację metoda
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();
}
Więc poniższy przypadek testowy może być (za pomocą 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);
}
Dalej jeśli chcesz stymulować kliknięcie przycisku, możesz użyć metody doClick tej instancji obiektu
btn.run();
b.doClick();
String str=tf1.getText().toString();
assertEquals("Welcome to junit.",str);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-24 10:02:43