目前可能无法与 Windows 一起使用,因此除非您想帮助解决问题,否则请使用 Linux 或类似的操作系统。
Github 集成可用于在推送新代码时自动执行测试:https ://github.com/marketplace/actions/mineunit-runner
如何使用mineunit
安装 mineunit 并为测试创建 spec 目录:
$ luarocks install --server=https://luarocks.org/dev --local mineunit $ cd ~/.minetest/mods/my_minetest_mod $ mkdir spec
spec
通过在目录中创建测试文件来添加测试。*_spec.lua
例如,文件名应与模式匹配mymod_spec.lua
。- 有关可能的规范文件内容,请参见下面的示例。
安装演示规范,替代上述mkdir spec
您可以安装spec
包含简单测试并显示一些您可以做的事情的演示目录。
要将 demo spec cd 安装到您的 mod 目录,必须有init.lua
文件并且不能有现有spec
目录。
- 运行命令:
$ mineunit --demo
为测试定义世界
世界可以通过调用world.layout
包含节点的表来替换,这将重置之前创建的世界布局。您还可以添加更多节点,而无需通过调用world.add_layout
而不是重置先前添加的世界布局world.layout
。
world.layout({ {{x=0,y=0,z=0}, “default:cobble”}, {{x=0,y=1,z=0}, “default:cobble”}, {{x=0,y=2,z=0}, “default:cobble”}, {{x=0,y=3,z=0}, “default:cobble”}, })
可以使用以下命令添加和删除单个节点world.set_node
:
world.set_node({x=0,y=0,z=0}, {name=“default:stone”, param2=0})
从世界中删除节点只需将节点设置为nil
:
world.set_node({x=0,y=0,z=0}, nil)
从世界中删除一切:
world.clear()
使用 Minetest 类和方法
API 尚未完成,但问题正在得到解决,并添加了更多功能,如果您发现问题,请创建问题
- 要设置节点元数据,只需
minetest.get_meta(pos):set_string("hello", "world")
像在 mod 中那样调用即可。 - 要创建 ItemStack,只需
ItemStack("default:cobble 99")
像在 mod 中那样调用即可。 - 任何其他类似的方式,就像你在 Minetest mods 中做的一样。
示例 mymod/spec/mymod_spec.lua 文件
下面附带了很多无用的东西,只是为了展示如何使用一些 mineunit 功能
-- Load and configure mineunit
require("mineunit")
-- Load some mineunit modules
mineunit("core")
mineunit("player")
mineunit("protection")
mineunit("default/functions")
-- Load some fixtures from spec/fixtures/nodes.lua for tests
-- Skip this if your tests do not need fixtures
fixture("nodes")
-- Load some mymod source files, you wanted to test these right?
-- This will execute init.lua in current directory
sourcefile("init")
-- Maybe we need actual world for test?
-- If world is larger or reused by multiple test specs it might be good
-- idea to put this into spec/fixtures/world.lua and load using fixture("world")
world.layout({
{{x=0,y=1,z=0}, "mymod:special_dirt"},
{{x=0,y=0,z=0}, "mymod:special_dirt"},
{{x=1,y=0,z=0}, "mymod:special_dirt"},
{{x=0,y=0,z=1}, "mymod:special_dirt"},
{{x=1,y=0,z=1}, "mymod:special_dirt"},
})
-- Protect some nodes, this will affect outcome of minetest.is_protected calls
mineunit:protect({x=0,y=1,z=0}, "Sam")
-- Create few players
local player1 = Player("Sam", {interact=1})
local player2 = Player("SX", {interact=1})
-- Define tests for busted
describe("My test world", function()
it("contains special_dirt", function()
local node = minetest.get_node({x=0,y=0,z=0})
assert.not_nil(node)
assert.equals("mymod:special_dirt", node.name)
end)
it("allows Sam to dig dirt at y 1", function()
assert.equals(false, minetest.is_protected({x=0,y=1,z=0}, player1:get_player_name()))
end)
it("protects dirt at y 1 from SX", function()
assert.equals(true, minetest.is_protected({x=0,y=1,z=0}, player2:get_player_name()))
end)
end)
有用的 Minute API 函数
Mineunit 本身带有一些额外的功能来允许受控的测试执行:
功能 | 描述 |
---|---|
mineunit:set_modpath(name, path) |
为命名的 mod 设置 modpath,minetest.get_modpath(name) 然后将报告此路径。 |
mineunit:set_current_modname(name) |
暂时将当前模组名称切换到另一个以测试检查当前模组名称的代码。 |
mineunit:restore_current_modname() |
使用更改后恢复原始 modname mineunit:set_current_modname(name) 。 |
mineunit:execute_globalstep(dtime) |
执行 Minetest globalstep:将触发注册的 globalsteps、nodetimers、minetest.after 和类似的回调。 |
mineunit:mods_loaded() |
执行用 注册的函数minetest.register_on_mods_loaded(func) 。 |
mineunit:execute_shutdown() |
模拟服务器关闭事件。 |
mineunit:execute_on_joinplayer(player, lastlogin) |
模拟Player 加入游戏。 |
mineunit:execute_on_leaveplayer(player, timeout) |
模拟Player 离开游戏。 |
mineunit:execute_on_chat_message(sender, message) |
模拟Player 发送聊天消息。 |
mineunit:execute_modchannel_message(channel, sender, message) |
Modchannel 消息处理程序。 |
mineunit:execute_modchannel_signal(channel, signal) |
Modchannel 消息处理程序。 |
mineunit:protect(pos, name_or_player) |
将位置添加到保护列表以模拟保护而不加载保护模块。 |
mineunit:get_players() |
获取所有已注册玩家,使用鉴权模块时还会返回未加入游戏的玩家。 |
mineunit:has_module(name) |
判断 Mineunit 模块是否已加载。 |
mineunit:config(key) |
读取 Mineunit 配置值。 |
mineunit:debug(...) |
verbose 如果选项高于 3 ,则打印到控制台。 |
mineunit:info(...) |
verbose 如果选项高于 2 ,则打印到控制台。 |
mineunit:warning(...) |
verbose 如果选项高于 1 ,则打印到控制台。 |
mineunit:error(...) |
verbose 如果选项高于 0 ,则打印到控制台。 |
print(...) |
print 如果选项未禁用,则打印到控制台。 |
mineunit:destroy_nodetimer(pos) |
改用 Minetest 对应物 |
mineunit:get_modpath(name) |
改用 Minetest 对应物 |
mineunit:get_current_modname() |
改用 Minetest 对应物 |
mineunit:get_worldpath() |
改用 Minetest 对应物 |
mineunit:register_on_mods_loaded(func) |
改用 Minetest 对应物 |
mineunit.export_object(obj, def) |
内部使用 |
mineunit.deep_merge(data, target, defaults) |
内部使用 |
mineunit.registered_craft_recipe(output, method) |
内部使用 |
Mineunit 模块将添加一些功能,例如一些简单的玩家动作模拟等。
矿机模块
核心模块
mineunit("core")
将加载多个模块并为简单的测试设置基本环境,这些模块将与core
模块一起自动加载:
模块名称 | 描述 |
---|---|
世界 | 提供world 命名空间以允许在测试世界中进行节点操作。 |
设置 | 提供Settings 类。core 如果存在,模块还将从 fixtures 目录加载 minetest 配置文件。 |
元数据 | 为测试提供元数据和库存操作。 |
物品堆 | 提供ItemStack 类。 |
游戏/常数 | Minetest 引擎库。 |
游戏/物品 | Minetest 引擎库。 |
游戏/杂项 | Minetest 引擎库。 |
游戏/注册 | Minetest 引擎库。 |
游戏/特权 | Minetest 引擎库。 |
常见/misc_helpers | Minetest 引擎库。 |
普通/矢量 | Minetest 引擎库。 |
通用/序列化 | Minetest 引擎库。 |
普通/fs | Minetest 引擎库。 |
建议始终加载core
模块,而不是选择单个自动加载的模块。
附加模块
模块名称 | 描述 |
---|---|
http | 提供用于测试使用minetest.request_http_api() . |
节点定时器 | 提供节点定时器功能。 |
播放器 | 提供Player 类、特权函数和表单规范函数。metadata 作为依赖加载。 |
保护 | 提供简单的节点保护 API 来模拟minetest.is_protected(pos) 行为。 |
服务器 | 为 globalstep、player、modchannel 和 chat 提供功能。加载nodetimer ,common/chatcommands 和game/chat 作为依赖项。 |
体素 | 提供VoxelManip 类。 |
授权 | 提供认证API。 |
实体 | 提供 SAO 实体 API。 |
常用/聊天命令 | Minetest 引擎库。 |
游戏/聊天 | Minetest 引擎库。 |
断言 | 提供自定义断言,如assert.isPlayer(thing) 和assert.is_ItemStack(thing) 。 |
命令行参数
Usage:
mineunit [-c|--coverage] [-v|--verbose] [-q|--quiet] [-x|--exclude <pattern>]
[--engine-version <version>] [--fetch-core <version>] [--core-root <path>]
Options:
-h, --help Display this help message.
-c, --coverage Execute luacov test coverage analysis.
-r, --report Build report after successful coverage analysis.
Currently cannot be combined with --coverage
-x|--exclude <pattern>
Exclude source file patterns from test coverage analysis.
Can be repeated for multiple patterns.
--demo Install demo tests to current directory.
Good way to learn Mineunit or initialize tests for project.
--core-root <path>
Root directory for core libraries, defaults to install path.
--engine-version <tag>
Use core engine libraries from git tag version.
--fetch-core <tag>
Download core engine libraries for tag.
This is simple wrapper around `git clone`.
-v|--verbose Be verbose, prints more useless crap to console.
-q|--quiet Be quiet, most of time keeps your console fairly clean.
Configuration files (in order):
/etc/mineunit/mineunit.conf
$HOME/.mineunit.conf
$HOME/.mineunit/mineunit.conf
./spec/mineunit.conf
配置文件按顺序检查合并,最后一个配置条目生效。例如,项目配置中的 core_root 将覆盖用户配置中的 core_root。
命令行参数将覆盖所有配置文件条目,除了将被合并的 luacov excludes。表值(luacov 除外)仅在项目配置文件中受支持。
使用 mineunit 的已知项目
有关如何使用 mineunit 以及可以用它做什么的更多示例,请参阅以下项目
Technic Plus:简单、干净和直接的测试。
- 网络测试technic/technic/spec at master · mt-mods/technic · GitHub
- CNC 测试technic/technic_cnc/spec at master · mt-mods/technic · GitHub
- GitHub 工作流程technic/.github/workflows/mineunit.yml at master · mt-mods/technic · GitHub
Metatool:复杂的测试设置。Mineunit 的开发从这里开始。
- Metatool API 测试https://github.com/SSX/metatool/tree/master/metatool/spec
- Sharetool 测试https://github.com/SSX/metatool/tree/master/sharetool/spec
- Containertool 测试https://github.com/SSX/metatool/tree/master/containertool/spec
- Tubetool 测试https://github.com/SSX/metatool/tree/master/tubetool/spec
- GitHub 工作流程https://github.com/SSX/metatool/blob/master/.github/workflows/mineunit.yml