Почему JPanelFixture.comboBox (). PressAndReleaseKeys () работает с FEST, но не с AssertJ?

При попытке смоделировать ввод с помощью 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);
    }
}

person Nashir    schedule 22.03.2019    source источник


Ответы (1)


Это не ответ на вопрос, а обходной путь, позволяющий добиться желаемого поведения. Эту проблему можно решить, вызвав robot () для comboBox ().

Вместо того

window.comboBox().pressAndReleaseKeys(KeyEvent.VK_S);

попробуй сделать

window.comboBox().robot().pressAndReleaseKeys(KeyEvent.VK_S);

person Nashir    schedule 25.03.2019