使用Junit4基于libgdx/ECS进行游戏测试。如果一起执行测试会失败

问题描述 投票:0回答:1

长话短说:我正在使用 libgdx/ECS(实体组件系统)开发一个小游戏,现在多次遇到我更改代码的问题,之后一些其他行为无法按预期工作(例如,单位无法不再移动到目标位置)。

为了避免将来出现此类问题,我的想法是使用 junit4 创建简单的游戏测试。设置完所有内容后,我现在遇到一个奇怪的问题:如果我单独执行测试用例,它们就会通过。当我尝试将它们一起运行时,它们就失败了。

在 @BeforeClass 方法中,我创建 libgdx“世界”,加载引擎并添加测试所需的所有系统。每个 @Test 类都会添加测试所需的所有实体(包括 libgdx 主体),并运行引擎一段特定的时间。在 @After 方法中,我确保删除测试添加的所有实体/主体。

@BeforeClass // executed once before all tests are performed 
public static void setupWorld() {

    world = new World(new Vector2(0, 0), true);
    //create a pooled engine
    engine = new PooledEngine();
    
    testUtility = new TestUtility(engine, world);

    // init factories
    bodyFactory = BodyFactory.getInstance(world);
    unitFactory = UnitFactory.getInstance(bodyFactory, engine);
    battleMap = new BattleMap(sceneryFactory, engine, 123, 0); // create a battle map without any terrain or scenery

    // add all the relevant systems our engine should run
    engine.addSystem(new FormationSystem());
    engine.addSystem(new PhysicsSystem(world));
    engine.addSystem(new FollowPathSystem(battleMap));
    engine.addSystem(new FollowFlowFieldSystem()); // this system works only for units!
    engine.addSystem(new ArriveSystem());
    engine.addSystem(new TurnTowardsSystem(engine));
    engine.addSystem(new FightSystem(engine, world));}

@After
public void cleanUp() throws Exception {
    // destroy all bodies in the world
    testUtility.destroyObsoleteStaticBodies();
    testUtility.destroyObsoleteDynamicBodies();
    // remove all steerable entities
    engine.removeAllEntities(Family.all(SteerableComponent.class).get());
    // remove all entities that contain the static body components
    engine.removeAllEntities(Family.all(BodyComponent.class).get());
    engine.clearPools();
    // check if world is reset correctly
    assertEquals("Number of bodies in the world should be zero.", 0, world.getBodyCount());
    assertEquals("Number of fixtures in the world should be zero.", 0, world.getFixtureCount());
}

这是一个测试示例(只是为了了解它的样子)

@Test
public void checkIfUnitTurnTowardsAttackingEnemy() {
    placeUnits(new Vector2(5,5), new Vector2(5,6));
    testUtility.runEngine(5, false);
    // get the steerable of the enemy unit to check if it has turned around
    SteerableComponent steerComp = engine.getEntitiesFor(Family.all(Enemy_Tag.class).get()).get(0).getComponent(SteerableComponent.class);
    float orientationAngle = MathHelper.simplifyAngle((float)Math.toDegrees(steerComp.body.getAngle()));
    assertTrue("Enemy unit that got attacked should have turned around. Offset in degrees: " + (orientationAngle-180), orientationAngle <= 180 + SteerableComponent.ANGLE_REACHED_THRESHOLD 
                                                                               && orientationAngle >= 180 - SteerableComponent.ANGLE_REACHED_THRESHOLD);
    assertTrue("Enemy should have angular velocity of zero.", steerComp.body.getAngularVelocity() <= SteerableComponent.ZERO_ANGULAR_SPEED_THRESHOLD);
}

我还缺少什么?顺便说一句,我正在使用 @RunWith(GdxTestRunner.class)。这是在测试期间能够访问行为树文件所必需的。

我什至尝试从 @BeforeClass 方法中删除所有代码并将所有内容放入 @Before 方法中,但这会导致同样的问题。

也许一般不建议使用 junit 测试基于 ECS 的 libgdx 游戏。如有任何帮助,我们将不胜感激。

java testing libgdx junit4 entity-component-system
1个回答
0
投票

我在我的设置中发现了问题。实际上,我有两个问题在相继执行多次测试时对行为产生了影响。

  1. 我尝试在测试后基于“SteerableComponent”删除实体(出于清理原因),但当实体在测试期间死亡时该组件已被删除。

  2. 更新引擎时,避免使用以下代码非常重要,因为两个测试用例之间的增量时间大于通常的增量时间,这可能会导致问题。

    engine.update(Gdx.graphics.getDeltaTime());

© www.soinside.com 2019 - 2024. All rights reserved.