测试插件或 Mod

備註

你的 PR 中包括的变更决定了你是否需要提供测试插件或测试 Mod。其中,SpongeAPI 的变动需要一个测试插件,而 SpongeAPI 具体实现的变动则需要一个测试 Mod。为方便起见,本文将统一以“测试插件”指代这两者。

测试是任何软件开发项目中不可或缺的一部分。提供测试插件主要是为了:

  1. 测试

    测试插件说明你已经测试过了你提交的代码没有问题,别人也可以使用一样的测试插件自行检查你当前及未来的变更。

  2. 文件檔

    有完整文档的测试插件是对 PR 所要求的文档的一个很好的补充。除此之外,对 PR 的评论(comment)在 PR 合并后就会失去意义,但对程序的注释(comment)则会和对应的代码一直在一起。测试插件并不是文档的全部,而是对文档的支撑。

小訣竅

建立插件的充分了解是编写测试插件的坚实基础。普通插件的要求(例如插件識別碼記錄與除錯)一样适用于测试插件

如果你打算贡献一个新的或修改过的 API 特性或对应的实现,你应当提供一测试插件。这个插件只需一个位于 org.spongepowered.test 包下的类,对应的目录是 SpongeCommon/testplugins/src/main/java/org/spongepowered/test/。这个插件应当作为你的 PR 的一部分出现。

测试插件的基本原则之一是不在必须的时候不能改变游戏原本的行为。插件的功能应当可以通过某个命令来开关。注意这和将测试插件排除出构建过程不是一回事。在 SpongeCommon/gradle/implementation.gradle 中有一个选项可以将测试插件排除出构建出的 jar 文件。然而,不论最终构建出来的东西包不包含测试插件,这个测试插件都应有一个开关其功能的命令。

備註

@Plugin 注解允许你自动向 Sponge 注册你的插件,但如此做就不能手动禁用此插件了。

下列代码展示了如何注册测试插件,并使其功能可以开关:

private boolean registered = false;

@Listener
public void onInit(GameInitializationEvent event) {
    Sponge.getCommandManager().register(this,
        CommandSpec.builder().executor((source, context) -> {
            if (this.registered) {
                this.registered = false;
                Sponge.getEventManager().unregisterListeners(this.listener);
            } else {
                this.registered = true;
                Sponge.getEventManager().registerListeners(this, this.listener);
            }
            return CommandResult.success();
        }).build(), "flowerPotTest");
}

備註

JUnit 的使用相对有限,主要是用于内部实现相关的测试。一般来说,在不需要玩家对象的情况下,JUnit 会有它的用武之地。无论如何,推荐的做法的是在使用 JUnit 之前,先征得 Sponge 团队成员的同意。