使用 libgdx 的类的单元测试

12

我正在使用libgdx编写游戏,使用junit框架简化我的代码的单元测试。现在有部分代码(一个地图生成器,一个将我的自定义地图格式转换成TiledMap的类...)需要进行彻底的测试,但它使用了libgdx的代码:从文件处理到资源加载。我不打算以这种方式测试实际的图形输出或游戏本身,但我想测试单个组件(计算、资源访问...)以避免明显的错误。

我已经在“setUpBeforeClass”方法中尝试过这样做:

    LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
    cfg.useGL20 = true;
    cfg.width = 480;
    cfg.height = 320;
    cfg.resizable = true;
    LwjglApplication app = new LwjglApplication( new TestApplicationListener(), cfg);

在 tearDownAfterClass() 中调用:

    Gfx.app.exit()

但它创建了一个我不需要的窗口,当我只需要初始化文件处理时似乎过于复杂。有没有更好的方法可以在不创建整个应用程序对象的情况下初始化libGDX组件?谢谢。

编辑

回顾一下(感谢评论中的Sam),我意识到需要GL访问(加载资源需要它),但这种方法似乎行不通:图形库似乎没有被初始化。 GDX文档并没有提供帮助。有什么线索吗?


使用您概述的方法,我能够使用文件处理,但无法使用任何图形模块 - 可能是因为它都在单独的渲染线程中运行。我意识到您并不打算测试图形,但您是否遇到过在单元测试中调用图形模块的方法?非常感谢您的帮助! - Cabbage soup
是的,上述方法可行,但实际上会创建一个空的主窗口。 我认为你可以执行整个游戏操作,既然这样:我将添加一个屏幕测试并检查它。 - Calimar41
为什么不使用模拟对象呢?你可以选择:mockito + powermock、jmockit、easy mock等。这样你就可以轻松地模拟libgdx在测试用例中所需的行为,以验证你的组件的行为如何。 - Morfic
我的问题部分源于libgdx javadoc 不够完整; 我不确定我是否在使用正确的方法(例如:我试图通过getTextures()从TextureAtlas提取区域,这破坏了我的代码)。 Mock对象 - 我几乎没有经验 - 似乎假定我知道实际方法应该返回什么; 如果是这种情况,我将根据未经验证的假设来测试我的代码。如果有必要请纠正我。 - Calimar41
我正在使用EasyMock,但是我发现模拟Gdx.gl行为非常困难。 - Cabbage soup
显示剩余2条评论
2个回答

14

这个问题还没有得到回答,我感到惊讶没有人指出无头后端,这对于这种情况非常理想。将其与你喜欢的Mocking库结合使用,你就可以顺利进行了。

public class HeadlessLauncher {
    public static void main(final String[] args) {
        final HeadlessApplicationConfiguration config = new HeadlessApplicationConfiguration();
        config.renderInterval = Globals.TICK_RATE; // Likely want 1f/60 for 60 fps
        new HeadlessApplication(new MyApplication(), config);
    }
}

该死。正是我需要的!!谢谢。 - Calimar41
1
要将此与JUnit测试结合使用,您可以使用来自https://github.com/TomGrill/gdx-testing的`GdxTestRunner`。 - Thomas

3

如上所示,有一个HeadlessApplication后端,它为您提供了一个初始化的libGDX,但没有OpenGL上下文。要使用OpenGL,确实需要LwjglApplication后端来创建一个OpenGL窗口。

如果您在编写依赖于OpenGL上下文的测试时遇到问题,请记住OpenGL仅附加到LwjglApplication的线程上,而不是测试的线程。您的测试必须调用Gdx.app.postRunnable(Runnable r)以访问具有OpenGl上下文的线程。

您可能希望使用synchronizedCountDownLatch来暂停测试,同时等待应用程序执行命令。


我正在尝试做这件事情,但无法与junit通信(我对java还不太熟悉)。似乎CountDownLatch是保持Gdx.app和junit线程同步的一种方法 - 是否有任何方法可以检测Runnable代码中的通过/失败?也就是说,在Gdx.app线程中的junit assert不会影响junit线程,因此junit线程需要检测在Runnable代码中发生了什么。您知道如何做到这一点吗? - SheerSt
我想告诉你,这应该算作一个新问题而不是评论,但后来我看到你已经提问并得到了帮助 :-) 如果有人遇到这个评论,请参见:http://stackoverflow.com/questions/32492526/libgdx-junit-testing-how-do-i-communicate-with-the-application-thread - Sebastian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接