Melakukan Pengujian Java Swing Dengan FEST
10 Januari 2013 Tinggalkan komentar
Pada aplikasi web, saya dapat melakukan pengujian view HTML dengan menggunakan Selenium. Bagaimana dengan aplikasi desktop? Apakah saya juga bisa melakukan pengujian user interface? Yup, bisa! Salah satu tool yang dapat saya pergunakan adalah FEST (Fixtures for Easy Software Testing).
Untuk memakai FEST, saya perlu men-download fest-swing-1.2.zip dari http://code.google.com/p/fest. Di dalam file tersebut, saya akan menemukan file fest-swing-1.2.jar yang harus disertakan dalam proyek yang akan diuji. Selain itu, saya juga perlu menyertakan jar yang ada di dalam folder lib seperti fest-util-1.1.2.jar dan fest-assert-1.2.jar. Btw, di saat sedang serius, saya lebih memilih memakai Maven untuk melakukan proses download secara otomatis dengan menyertakan dependency ke org.easytesting.fest-swing.
Saya akan membuat sebuah tampilan Swing yang akan diuji dengan menggunakan MigLayout seperti berikut ini:
package com.snake.view; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPasswordField; import javax.swing.JTextField; import net.miginfocom.swing.MigLayout; public class LoginView extends JFrame { private static final long serialVersionUID = -1977819063823609321L; private JTextField txtNama; private JPasswordField txtPassword; private JButton btnLogin; private JButton btnKeluar; public LoginView() { super("Login"); setLayout(new MigLayout("", "[right][grow,fill]", "[][][nogrid]")); add(new JLabel("Nama Pengguna:")); add(txtNama = new JTextField(20), "wrap"); add(new JLabel("Password:")); add(txtPassword = new JPasswordField(20), "wrap"); add(btnLogin = new JButton("Login"), "align center, gaptop 10"); add(btnKeluar = new JButton("Keluar")); txtNama.setName("txtNama"); txtPassword.setName("txtPassword"); btnLogin.setName("btnLogin"); btnKeluar.setName("btnKeluar"); btnLogin.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (txtNama.getText().equals("solid") && String.valueOf(txtPassword.getPassword()).equals("snake")) { JOptionPane.showMessageDialog(LoginView.this, "Ok, login sukses!"); } else { JOptionPane.showMessageDialog(LoginView.this, "Maaf, kamu bukan dia!"); } } }); setSize(500,500); pack(); } public static void main(String[] args) { LoginView loginView = new LoginView(); loginView.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); loginView.setVisible(true); } }
Lalu, untuk melakukan pengujian, saya membuat sebuah JUnit test seperti berikut ini:
package com.snake.view; import org.fest.swing.edt.FailOnThreadViolationRepaintManager; import org.fest.swing.edt.GuiActionRunner; import org.fest.swing.edt.GuiQuery; import org.fest.swing.fixture.FrameFixture; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class LoginViewTest { private FrameFixture window; @BeforeClass public static void beforeClass() { FailOnThreadViolationRepaintManager.install(); } @Before public void before() { LoginView loginView = GuiActionRunner.execute(new GuiQuery<LoginView>() { @Override protected LoginView executeInEDT() throws Throwable { return new LoginView(); } }); window = new FrameFixture(loginView); window.show(); } @After public void after() { window.cleanUp(); } @Test public void testTampilanAwal() { window.textBox("txtNama").requireEditable().requireEmpty(); window.textBox("txtPassword").requireEditable().requireEmpty(); window.button("btnLogin").requireVisible(); window.button("btnKeluar").requireVisible(); } @Test public void testLoginSukses() { window.textBox("txtNama").enterText("solid"); window.textBox("txtPassword").enterText("snake"); window.button("btnLogin").click(); // Menunggu JOptionPane muncul dengan timeout default 100ms window.optionPane().requireMessage("Ok, login sukses!"); } @Test public void testLoginGagal() { window.textBox("txtNama").enterText("user aneh"); window.textBox("txtPassword").enterText("password ajaib"); window.button("btnLogin").click(); // Menunggu JOptionPane muncul dengan timeout default 100ms window.optionPane().requireMessage("Maaf, kamu bukan dia!"); } }
Pada pengujian di atas, saya memberikan statement FailOnThreadViolationRepaintManager.install()
untuk mendeteksi apakah ada kode program yang mengakses Swing tetapi tidak berjalan di EDT. Saya membahas tentang EDT di tulisan Multithreading Dengan Mudah Di Griffon. Pada tulisan tersebut saya memakai bahasa Griffon, sementara disini saya memakai bahasa Java. Tapi keduanya sama-sama berjalan di platform Java sehingga prinsip dasar-nya tetap sama. Bila terdapat pelanggaran saat JUnit dijalankan, pada console akan terdapat output seperti org.fest.swing.exception.EdtViolationException: EDT violation detected.
Ini adalah contoh hasil yang saya peroleh saat menjalankan JUnit test case di atas:
Pada saat memakai JUnit dengan Selenium, browser akan muncul dan men-klik “sana-sini” secara otomatis. Begitu juga dengan sekarang. Saat memakai FEST, JFrame
yang diuji akan muncul, setiap JTextField
akan di-isi, kemudian JButton
akan di-click.
Anda harus log masuk untuk menerbitkan komentar.