#集成测试 #修改 #辅助 #cargo #cargo-test #归档 #路径

bin+lib xtest-data

在测试已发布货物时获取辅助测试数据

8 个版本

1.0.0-beta.52024年3月12日
1.0.0-beta.42022年10月27日
1.0.0-beta.22022年3月17日
1.0.0-beta2021年9月26日
0.0.4 2021年9月26日

开发工具 中排名第 258

MIT OR Apache-2.0 OR Zlib

88KB
1.5K SLoC

在测试已发布货物时获取辅助测试数据。

本库的作用

本库解决了集成测试套件和文档测试不能仅从发布的 .crate 归档单独运行的问题,如果它们依赖于不应发送给下游包和最终用户的辅助数据文件。

为此,它在 Cargo.toml 中增加了额外的字段,描述了如何从与创建时的确切版本关联的 VCS 文件组成的归档文件。然后,在从 .crate 归档执行测试时引用打包的数据和确切版本。一个小型运行时组件解压数据并将文件路径重写到替代文件树中。

如何测试货物

此存储库包含了解释辅助元数据的参考实现。测试依赖此库的货物非常简单

# test for developers
cargo run --bin xtask --features bin-xtask -- test <path-to-repo>
# test for packager
cargo run --bin xtask --features bin-xtask -- crate-test <crate>
# prepare a test but delay its execution
eval `cargo run --bin xtask --features bin-xtask -- fetch-artifacts <crate>`

对于离线使用,其中归档由您自己处理

# Prepare .crate and .xtest-data archives:
cargo run --bin xtask --features bin-xtask -- package
# on stdout, e.g.: ./target/xtest-data/xtest-data-1.0.0-beta.3.xtest-data

# < -- Any method to upload/download/exchange archives -- >

# After downloading both files again:
eval `cargo run --bin xtask --features bin-xtask -- \
  fetch-artifacts xtest-data-1.0.0-beta.3.crate \
  --pack-artifact xtest-data-1.0.0-beta.3.xtest-data`
# Now proceed with regular testing

如何应用

将此软件包作为测试的 dev-dependency 集成到您的测试中。

let mut path = PathBuf::from("tests/data.zip");
xtest_data::setup!()
    .rewrite([&mut path])
    .build();
// 'Magically' changed.
assert!(path.exists(), "{}", path.display());

注意上述调用被类型化为不可失败,但它们不是完整的——当某些内容缺失时它们会引发恐慌,因为这表示数据缺失。这种推理是因为这表明了设置有误,而不是测试应该处理的事情。库的预期是您通过库而不是直接路径来访问所有数据。

动机

作为一个库的开发者,你将编写一些集成,目的是确保你的代码的正确功能。通常,这些将在发布前在 CI 管道中执行。然而,如果其他人——例如开源操作系统发行版——想要重新包装你的代码呢?在某些情况下,他们可能需要进行简单的、小的修改:重写依赖项、应用编译选项如加固标志等。在那些修改之后,最终产品是否仍然符合其自身的期望并不清楚。因此,你想再次运行集成测试套件。这就是库的用武之地。它应该确保

  • 它在作为依赖项包含时不需要修改代码,因此不会引起注意。
  • 测试应该可以从打包的.crate中进行重复,作者可以在本地和预发布检查期间验证此属性。
  • 测试所需的辅助数据文件被明确引用。
  • 它不对测试数据来源做出不可修改的假设。

如何使用离线模式

首先,导出包含你的测试运行的自包含对象包集合。

CARGO_XTEST_DATA_PACK_OBJECTS="$(pwd)/target/xtest-data" cargo test
zip xtest-data.zip -r target/xtest-data

这允许利用库组件为测试数据作为单独存档的分布式包提供引人入胜的体验。当然,你可以将target/xtest-data打包成任何你喜欢的形状或形式。在测试crate存档时,反转这些步骤

unzip xtest-data.zip
CARGO_XTEST_DATA_PACK_OBJECTS="$(pwd)/target/xtest-data" cargo test

详细信息

为crate作者的使用方法

对于基本用法,请参阅上述部分如何应用。对于更高级的API使用,请参阅文档。完整接口并不比上述简单版本复杂多少。

如果你想要检查你的crate是否成功通过了crate分布的测试,还有一个额外的细节。为此,你可以将此crate的xtask作为二进制文件重用

cd path/to/xtest-data
cargo run --bin xtask --features bin-xtask -- \
  --path to/your/crate test

提示:如果你将xtest-data的源仓库作为子模块添加,并将你的工作区修改为包含xtask文件夹,那么你始终可以从自己的crate中执行xtask

xtask将

  1. 运行cargo package来创建.crate存档和相关的打包目录。请注意,这要求选定的crate源代码未被修改。
  2. 如果未选择test,则停止。否则,解压缩并将此存档解包到临时目录中。
  3. 使用xtest-data的覆盖为本地开发编译包。特别是:CARGO_XTEST_DATA_PACK_OBJECTS将指向打包输出目录;CARGO_XTEST_DATA_TMPDIR将设置为在target目录中创建的临时目录;CARGO_TARGET_DIR也将指向目标目录。

这将在其他方面模拟新鲜的分发编译,同时保留rustc缓存数据。

打包者的定制点

在所有设置中,xtest_data将检查以下内容

  • 位于CARGO_MANIFEST_DIR中的Cargo.toml文件将被读取、解码,并且至少包含键package.namepackage.versionpackage.repository

在非源设置中(即从下载的crate运行时),xtest_data包将读取以下环境变量

  • CARGO_XTEST_DATA_TMPDIR(后备:TMPDIR)在测试中的任何测试都不是集成测试时必须设置。简单地说,设置创建了一些辅助数据文件,但它不能保证清理它们。这使显式努力与环境沟通这一点。如果你认为你的用例更适合使用隐式、泄漏的临时目录,请随时对此推理提出质疑。
  • CARGO_XTEST_DATA_PACK_OBJECTS:一个用于git打包对象的目录(参见man git pack-objects)。在从源代码运行测试时,将打包文件写入此目录,在从.crate存档运行测试时,从这个目录读取。这些是执行浅克隆和稀疏克隆时从源代码库中获取的相同对象。
  • CARGO_XTEST_VCS_INFO:包含版本控制信息的json文件的路径,结构类似于cargo生成的VCS信息。这将强制xtest进入VCS模式,其中资源被替换为打包对象(s)中的数据。可用于强制crates提供内部VCS信息或补充此类信息。例如,使用cargo package --allow-dirty生成的包将不包括此类文件,可以使用强制选择来覆盖。

工作原理

cargo打包.crate时,它将包含一个名为.cargo_vcs_info.json的文件,该文件包含基本版本信息,即作为存档创建基础的提交ID。当此crate的方法运行时,它们检测该文件的存在或不存在,以确定是否可以获取数据(我们还会从Cargo.toml中检测仓库信息)。

如果我们似乎是在开发仓库外部运行,则默认情况下我们不会做任何事情,只是验证信息,调试打印我们计划获取的内容——然后立即崩溃。然而,如果环境变量CARGO_XTEST_DATA_FETCH设置为yestrue1,则我们将尝试下载并签出请求的文件到相对位置。

目标实现

  • 该包是一个纯开发依赖项,重点是引入少量依赖。欢迎任何进一步减少此数量的补丁。(我们可能会添加一个切换,以禁用锁及其依赖项,如果非并行测试执行足够好?)
  • 提供了一种完整的离线模式,具有最少的辅助源存档。在构建crate而不执行测试时不需要任何测试数据。
  • 可以使用xtask工具进行本地开发和CI(例如,我们在自己的管道中使用它)。它不是与实现紧密耦合的,而是与公共接口相关,因此可以将其替换为您自己的逻辑。
  • 辅助文件通过分发crate的提交对象ID进行引用,这意味着从特定的树(tree-ish)中检索它们。这相当于遍历Merkle树,这有利于高效的签名等。
  • 只要提供了兼容git的服务器,就可以覆盖源仓库。例如,您可能会预先克隆源提交,并通过本地file://仓库提供数据。

已知问题

在获取数据时,Git可能会反复请求凭据,并且速度相当慢。当git支持sparse-checkout时,这个问题不应该发生。这是因为我们正在调用Git并使用git checkout,这是我们所利用的,用以非常选择性地在确切路径规范中撤销浅拷贝,不会保持连接活跃——即使你通过--pathspecs-from-file=-同时给出多个路径规范。然而,使用sparse-checkout时,我们只调用一次,这降低了连接尝试的次数。一种解决方案是设置本地代理并在之后清除它,或者创建一个短暂的生命周期令牌。

未来工作想法

作为一个cargo xtask。然而,xtask的理念是确切的设置不会随主包上传,而只是一个本地开发工具。尽管如此,我们仍然可以帮助测试设置。

将其添加为git子模块(或子树)。这应该允许你配置一个对单独存储库中数据文件的依赖,而该文件不由git本身跟踪。此包不介意你将其添加到何处,只要你将其配置为在你的工作区中。然后为这个包设置命令别名。

依赖关系

~2–10MB
~120K SLoC