通过HeadlessApplication调用ShaderProgram(例如Stage)的单元测试Libgdx类

Tim*_* F. 5 unit-testing libgdx kotlin

我正在尝试对corelibgdx应用程序的程序包进行单元测试。

模拟ShaderProgram根类的最佳方法是什么?

考虑到Libgdx测试运行程序的以下初始化,

init {
    val conf = HeadlessApplicationConfiguration()

    HeadlessApplication(this, conf)
    Gdx.gl = mock(GL20::class.java) 
    Gdx.gl20 = mock(GL20::class.java)
    Gdx.gl30 = mock(GL30::class.java)
    Gdx.graphics = mock(Graphics::class.java)
    `when`(Gdx.graphics.height).thenReturn(dimensions)
    `when`(Gdx.graphics.width).thenReturn(dimensions)
}
Run Code Online (Sandbox Code Playgroud)

以及正在测试的函数(位于的子级的类中Application Listener),

override fun create() {
    ...
    stage = Stage(ScreenViewport())
    ...
}
Run Code Online (Sandbox Code Playgroud)

尝试编译着色器时,Stage内部发生错误。

即,SpriteBatch.java来自com.badlogic.gdx.graphics.g2d

ShaderProgram shader = new ShaderProgram(vertexShader, fragmentShader);
if (shader.isCompiled() == false) throw new IllegalArgumentException("Error compiling shader: " + shader.getLog());
Run Code Online (Sandbox Code Playgroud)

shader.isCompiled()似乎总是为false返回false HeadlessApplication

Cri*_*ges 2

由于到目前为止还没有答案,我想分享我目前的知识/观点:

首先,我们需要问一个问题:我们是否可以为一般的 GUI 编写单元测试?如果您想要深入的答案,请看一下这个问题。总结一下:您可以通过计算帧缓冲区的哈希值来对 GUI 进行单元测试,但一般建议是将尽可能多的逻辑从 GUI 中移出,并且根本不要对 GUI 进行单元测试。除此之外,我和大多数运行代码的服务器都没有对 OpenGL 的硬件支持。假设我们不想为软件渲染烦恼,那么对 GUI 本身进行单元测试是没有选择的。

根据这些信息,我认为我的逻辑与 GUI 的分离不够好。但是,当进一步研究 scene2d 和围绕它的大量教程时,很明显,scene2d 希望您在设计上结合代码的逻辑和 GUI 部分,请参阅此问题以供参考。

假设您同意 scene2d 很难将逻辑和 GUI 分开,我们现在面临操作员的问题,而常见的解决方案不适用。

在我看来,libGDX 的所有元素都应该与 HeadlessBackend 完全兼容,但事实并非如此,这是 libGDX 的设计缺陷。到目前为止,我想出的唯一解决方法是根据需要模拟 SpriteBatch 并将其传递到舞台:

val stage = Stage(myViewport, if (isHeadless) mock(SpriteBatch::class.java) else SpriteBatch())
Run Code Online (Sandbox Code Playgroud)

虽然这允许您正常使用舞台,但我不认为它是真正的解决方案,因为您需要编写测试感知的代码。