【问题标题】:AssertJ-Swing and Junit 5 supportAssertJ-Swing 和 Junit 5 支持
【发布时间】:2022-01-08 10:52:22
【问题描述】:

我目前正在使用 JUnit Jupiter 测试一个 Java 应用程序。我开始在 GUI 上工作,我想知道是否可以将 AssertJ-Swing 与 JUnit 5 一起使用。 事实上,我在 AssertJ-Swing GitHub 页面上找到了一个开放的issue

他们给出的建议是像这样定义一个 GUITestExtension:

import org.assertj.swing.junit.runner.ImageFolderCreator;
import org.junit.jupiter.api.extension.Extension;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.InvocationInterceptor;
import org.junit.jupiter.api.extension.ReflectiveInvocationContext;

import java.lang.reflect.Method;

import static org.assertj.swing.annotation.GUITestFinder.isGUITest;
import static org.assertj.swing.junit.runner.Formatter.testNameFrom;

/**
 * Understands a JUnit 5 extension that takes a screenshot of a failed GUI test.
 * The Junit 4 runner is available in {@link org.assertj.swing.junit.runner.GUITestRunner}.
 *
 * @see <a href="https://github.com/assertj/assertj-swing/issues/259">assertj-swing #259</a>
 * @author William Bakker
 */
public class GUITestExtension implements Extension, InvocationInterceptor {
    private final FailureScreenshotTaker screenshotTaker;

    public GUITestExtension() {
        screenshotTaker = new FailureScreenshotTaker(new ImageFolderCreator().createImageFolder());
    }

    @Override
    public void interceptTestMethod(
            Invocation<Void> invocation,
            ReflectiveInvocationContext<Method> invocationContext,
            ExtensionContext extensionContext) 
            throws Throwable {
        try {
            invocation.proceed();
        } catch (Throwable t) {
            takeScreenshot(invocationContext.getExecutable());
            throw t;
        }
    }

    private void takeScreenshot(Method method) {
        final Class<?> testClass = method.getDeclaringClass();
        if (!(isGUITest(testClass, method)))
            return;
        screenshotTaker.saveScreenshot(testNameFrom(testClass, method));
    }
}

我对可以与 JUnit 4 一起使用的 GUITestRunner 有点熟悉,但我不知道如何用它来替换它。

注意: 通常 GUITestRunner 与 JUnit 4 一样使用:

import org.assertj.swing.junit.runner.GUITestRunner; 
import org.assertj.swing.junit.testcase.AssertJSwingJUnitTestCase;
import org.junit.runner.RunWith;
import org.assertj.swing.edt.GuiActionRunner; 
import org.assertj.swing.fixture.FrameFixture;

@RunWith(GUITestRunner.class) 
public class WelcomeSwingViewTest extends AssertJSwingJUnitTestCase{
    private FrameFixture window;
    private WelcomeSwingView welcomeSwingView;
    @Override
    protected void onSetUp() { 
        GuiActionRunner.execute(() -> {
         welcomeSwingView = new WelcomeSwingView();
         return welcomeSwingView; 
        });
        window = new FrameFixture(robot(), welcomeSwingView);
        window.show(); 
    }
}

感谢任何帮助。

【问题讨论】:

  • 显示的实现在哪些方面不能满足您的要求?您对 AssertJ-Swing 集成有什么要求?你能链接到 GUITestRunner 的实现吗?简而言之:它有助于为像我一样熟悉 JUnit5 方面但不了解 AssertJ-Swing 的人提供更多信息和上下文。
  • @johanneslink 我在 JUnit 4 中添加了 GUITestRunner 的常用用法
  • @claudia 我建议您将问题的第二部分放入答案中并接受它,因为它包含解决原始问题的所有细节。

标签: java swing junit5 assertj


【解决方案1】:

假设问题中提到的GUITestExtension是在你的代码库中定义的,可以通过以下方式注册:

@Test
@ExtendWith(GUITestExtension.class)
void test() {
    ...
}

更多信息可以在 JUnit 5 文档的 extension model 部分找到。

理想情况下,扩展应该直接来自 AssertJ Swing,但不幸的是,项目负责人已经没有时间了,因此我们正在寻找提交者。

如果有人感兴趣,请随时在 GitHub 上get in touch

【讨论】:

  • 感谢您的回答。我用当前测试类的代码更新了我的问题。你能告诉我那个代码是否可以吗?
【解决方案2】:

我根据 Stefano 的 answer 更改了我的测试类,现在一切正常。如果有人需要它,我的测试类代码是这样的:

import org.assertj.swing.core.matcher.JLabelMatcher;
import org.assertj.swing.edt.GuiActionRunner;
import org.assertj.swing.fixture.FrameFixture;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.assertj.swing.annotation.GUITest;

@ExtendWith(GUITestExtension.class)
class WelcomeSwingViewTest  {

    private FrameFixture window;
    private WelcomeSwingView welcomeSwingView;
    
    @BeforeAll
    static void setUpOnce() {
        FailOnThreadViolationRepaintManager.install();
    }

    @BeforeEach
    void setup() {

        GuiActionRunner.execute(() -> {
            welcomeSwingView = new WelcomeSwingView();
            return welcomeSwingView;
        });
        window = new FrameFixture(welcomeSwingView);
        window.show();
    }

    @AfterEach
    void clean() {
        window.cleanUp();
    }

    @Test @GUITest
    void testControlsInitialStates() {
        window.label(JLabelMatcher.withText("label"));
    }
}

当然,您还必须将GUITestExtension(在我的问题中定义)导入您的测试类。测试也是成功的,因为在我看来我有一个带有文本“标签”的label

【讨论】:

    猜你喜欢
    • 2016-11-19
    • 2019-03-04
    • 1970-01-01
    • 1970-01-01
    • 2018-03-22
    • 1970-01-01
    • 2012-08-24
    • 2020-07-29
    相关资源
    最近更新 更多