При попытке смоделировать ввод с помощью AssertJ pressAndReleaseKeys () для модульного тестирования JComboBox в программе Java Swing я не вижу ожидаемого поведения. Программа чаще всего зависает в строке pressAndReleaseKeys, а затем терпит неудачу или иногда удаляет весь текст, находящийся в данный момент в тестируемом JComboBox, что приводит к сбою последующих утверждений (например, requireSelection ()). Трассировка стека, которую я получаю для предоставленного примера программы (см. Ниже), когда она зависает, выглядит следующим образом:
Изменение фокуса на javax.swing.JComboBox [name = 'combob', selectedItem = 'Bean', contents = [Pork, Beans, Rice], editable = true, enabled = true, visible = true, visible = true] владелец фокуса не удалось : javax.swing.plaf.metal.MetalComboBoxEditor $ 1 (javax.swing.JTextField) [name = null, text = 'Bean', enabled = true, visible = true, visible = true]
org.assertj.swing.exception.ActionFailedException
в org.assertj.swing.exception.ActionFailedException.actionFailure (ActionFailedException.java:33)
в org.assertj.swing.core.BasicRobot.focus (BasicRobot .java: 301)
в org.assertj.swing.core.BasicRobot.focusAndWaitForFocusGain (BasicRobot.java:270)
в org.assertj.swing.driver.ComponentDriver.focusAndWaitForFocusGain (Component419. )
в org.assertj.swing.driver.ComponentDriver.pressAndReleaseKeys (ComponentDriver.java:315)
в org.assertj.swing.fixture.AbstractComponentFixture.pressAndReleaseKeys (AbstractComponentFixture.java /:293)
в javapractice.ComboBoxSampleTest.testMain (ComboBoxSampleTest.java:59)
Я использую FEST и надеюсь перенести свои тесты на AssertJ, поскольку он активно поддерживается, тогда как FEST не обновлялся годами. Я использовал руководство по переходу с Fest на AssertJ Джоэла Костильолы, но у меня возникли проблемы при имитации ввода с клавиатуры с помощью pressAndReleaseKeys (). Я могу имитировать ввод при использовании JTextComponentFixture, т.е.
window.textBox("textB").pressAndReleaseKeys(KeyEvent.VK_LEFT);
(где window - это FrameFixture, контейнер как в AssertJ, так и в FEST), но я не могу имитировать ввод при использовании JComboBoxFixture, т.е.
window.comboBox("comboB").pressAndReleaseKeys(KeyEvent.VK_LEFT);
Этого препятствия обычно можно избежать, поскольку большинство нажатий клавиш можно смоделировать с помощью enterText, т.е.
window.comboBox("comboB").enterText("\n"); //to press the enter key
window.comboBox("comboB").enterText("\b"); //to press the backspace key
но я хотел бы иметь возможность использовать клавиши со стрелками, клавишу управления и другие клавиши, где я не могу имитировать нажатие клавиши с помощью enterText (). Произошла ли эта ошибка из-за проблемы с моей средой *, из-за того, как я ее использую, или из-за неисправности самого API?
Я пробовал использовать pressKey (), а затем releaseKey () в качестве обходного пути, но это тоже не работает с JComboBox, и моя программа вместо этого зависает на pressKey (). При этом я не могу использовать pressKey () и releaseKey () для тестирования JComboBox с FEST.
* Сведения о среде:
Версия языка: версия java 1.8.0_131
Версия платформы (например, .NET 3.5; обратите внимание, что это не всегда подразумевается из языковой версии или наоборот)
Работа система: Red Hat Release 6.10 (Сантьяго)
IDE: Netbeans 8.0.2
Пример приложения с графическим интерфейсом пользователя:
package javapractice;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ComboBoxSample extends JFrame implements ItemListener{
JPanel jp;
JComboBox jcb;
JLabel result;
JLabel title;
JTextField jtc;
public static void main(String[] args) {
ComboBoxSample frame = new ComboBoxSample();
}
ComboBoxSample() {
super();
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
this.setTitle("Testing AssertJ");
this.setLayout(new FlowLayout());
jp = new JPanel();
jcb = new JComboBox(new String[] {"Pork", "Beans", "Rice"});
jcb.setEditable(true);
jcb.setName("combob");
jtc = new JTextField();
jtc.setEditable(true);
jtc.setPreferredSize(new Dimension(150, 25));
jtc.setName("textb");
title = new JLabel("Food: ");
result = new JLabel("No food");
jp.add(title);
jp.add(jcb);
jp.add(result);
jp.add(jtc);
this.add(jp);
this.setLocationRelativeTo(null);
jcb.addItemListener(this);
this.pack();
this.repaint();
}
@Override
public void itemStateChanged(ItemEvent e) {
if(e.getSource() == jcb) {
result.setText("I'm eating " + jcb.getSelectedItem());
}
this.pack();
}
public void cleanUp() {
jcb = null;
result = null;
jtc = null;
jp = null;
title = null;
}
}
Тестовый файл для Fest:
package javapractice;
import com.sun.glass.events.KeyEvent;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* Fest imports.
*/
import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
import org.fest.swing.edt.GuiActionRunner;
import org.fest.swing.edt.GuiQuery;
import org.fest.swing.fixture.FrameFixture;
public class ComboBoxSampleTest {
private FrameFixture window;
private ComboBoxSample frame;
@BeforeClass
public static void setUpClass() {
FailOnThreadViolationRepaintManager.install();
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
frame = GuiActionRunner.execute(new GuiQuery<ComboBoxSample>() {
@Override
protected ComboBoxSample executeInEDT() {
return new ComboBoxSample();
}
});
window = new FrameFixture(frame);
window.show();
}
@After
public void tearDown() {
window.cleanUp();
frame.cleanUp();
}
/**
* Test of main method, of class ComboBoxSample.
*/
@Test
public void testMain() {
//Delay so that we can see what's going on
try {
Thread.sleep(2000);
} catch (InterruptedException ie) {
}
window.textBox("textb").enterText("hi there");
window.textBox("textb").pressAndReleaseKeys(KeyEvent.VK_BACKSPACE);
window.comboBox().replaceText("Bean");
window.comboBox().pressAndReleaseKeys(KeyEvent.VK_S);
window.comboBox().pressAndReleaseKeys(KeyEvent.VK_DOWN);
window.comboBox().pressAndReleaseKeys(KeyEvent.VK_DOWN);
window.comboBox().pressAndReleaseKeys(KeyEvent.VK_DOWN);
window.comboBox().pressAndReleaseKeys(KeyEvent.VK_ENTER);
}
}
Тестовый файл для AssertJ:
package javapractice;
import com.sun.glass.events.KeyEvent;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* AssertJ imports.
*/
import org.assertj.swing.edt.FailOnThreadViolationRepaintManager;
import org.assertj.swing.edt.GuiActionRunner;
import org.assertj.swing.fixture.FrameFixture;
public class ComboBoxSampleTest {
private FrameFixture window;
private ComboBoxSample frame;
@BeforeClass
public static void setUpClass() {
FailOnThreadViolationRepaintManager.install();
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
frame = GuiActionRunner.execute(() -> new ComboBoxSample());
window = new FrameFixture(frame);
window.show();
}
@After
public void tearDown() {
window.cleanUp();
frame.cleanUp();
}
/**
* Test of main method, of class ComboBoxSample.
*/
@Test
public void testMain() {
//Delay so that we can see what's going on
try {
Thread.sleep(2000);
} catch (InterruptedException ie) {
}
window.textBox("textb").enterText("hi there");
window.textBox("textb").pressAndReleaseKeys(KeyEvent.VK_BACKSPACE);
window.comboBox().replaceText("Bean");
//the above line is the last one to execute
window.comboBox().pressAndReleaseKeys(KeyEvent.VK_S);
window.comboBox().pressAndReleaseKeys(KeyEvent.VK_DOWN);
window.comboBox().pressAndReleaseKeys(KeyEvent.VK_DOWN);
window.comboBox().pressAndReleaseKeys(KeyEvent.VK_DOWN);
window.comboBox().pressAndReleaseKeys(KeyEvent.VK_ENTER);
}
}