运行 从命令行进行单元测试时继承依赖关系
Inheriting dependencies when running unit tests from command line
我正在尝试从命令行 运行 Julia 单元测试,但单元测试失败 运行 因为它们找不到我在主项目中使用的依赖项。我怎样才能使这项工作?我尝试执行的实际命令是来自项目根目录的 julia test/test_blueprint.jl
。下面是更多详细信息。
有关设置的详细信息
我的项目位于路径/home/jonas/prog/julia/blueprint
。在该目录中,我有一个包含这些行的 Project.toml
文件:
name = "blueprint"
uuid = "c1615a0c-c255-402d-ae34-0b88819b43c6"
authors = [""]
version = "0.1.0"
[deps]
FunctionalCollections = "de31a74c-ac4f-5751-b3fd-e18cd04993ca"
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
连同 Manifest.toml
文件。
我在 test/
有一个子目录,其中包含我在 this guide 之后创建的单元测试,该目录包含另一个 Project.toml
文件,其中包含
[deps]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
有一个包含单元测试的文件 test/test_blueprint.jl
,该文件以
开头
using Test
include("../src/blueprint.jl") # Alternative 1
#using blueprint # Alternative 2
using FunctionalCollections
using LinearAlgebra
...
正在测试的实际代码在文件 src/blueprint.jl
.
中
问题详情
从项目根目录,我尝试 运行 使用命令 julia test/test_blueprint.jl
进行单元测试。当我 运行 该命令时,它会产生以下输出:
ERROR: LoadError: ArgumentError: Package Setfield not found in current path:
- Run `import Pkg; Pkg.add("Setfield")` to install the Setfield package.
Stacktrace:
[1] require(into::Module, mod::Symbol)
@ Base ./loading.jl:967
[2] include(fname::String)
@ Base.MainInclude ./client.jl:451
[3] top-level scope
@ ~/prog/julia/blueprint/test/test_blueprint.jl:8
in expression starting at /home/jonas/prog/julia/blueprint/src/blueprint.jl:1
in expression starting at /home/jonas/prog/julia/blueprint/test/test_blueprint.jl:8
提示找不到依赖项Setfield
。如果我从
稍微编辑文件的顶部 test/test_blueprint.jl
include("../src/blueprint.jl") # Alternative 1
#using blueprint # Alternative 2
至
#include("../src/blueprint.jl") # Alternative 1
using blueprint # Alternative 2
它仍然失败,但出现不同的错误:
ERROR: LoadError: ArgumentError: Package blueprint not found in current path:
- Run `import Pkg; Pkg.add("blueprint")` to install the blueprint package.
Stacktrace:
[1] require(into::Module, mod::Symbol)
@ Base ./loading.jl:967
in expression starting at /home/jonas/prog/julia/blueprint/test/test_blueprint.jl:9
问题:如何从命令行进行单元测试运行?
请注意,我 可以 运行 通过使用 C-c C-a
在 src/blueprint.jl
文件并在单元测试文件 test/test_blueprint.jl
中调用 C-c C-b
。我的 Julia 版本是 1.7.0 (2021-11-30)。不要犹豫,要求更多说明。
首先,一些可能不会(但可能会)导致此处问题的命名约定:
- 按照惯例,包名称以单个大写字母开头,因此我建议将名称更改为
Blueprint
无处不在
- 默认情况下,
] test
运行s 测试在 test/runtests.jl
中找到,所以我建议将您的顶级测试脚本命名为 runtests.jl
以避免混淆,即使尽管从此处的错误来看 test
确实以某种方式找到您的 test_blueprint.jl
文件。
现在,虽然我无法在没有您的软件包的完整代码的情况下进行测试,但我怀疑这里发生的情况如下:
- 通常,
test/Project.toml
中不需要您正在测试的包的依赖项(比方说 MyPackage
),因为它们在 MyPackage
中是隐式的。因此,在成功 using MyPackage
之后,虽然它们仍然无法用于在您的测试脚本 中编写的任何函数 (test/runtests.jl
),但 将 可用于 MyPackage
中编写的函数——就像您在 REPL 中键入 ]using MyPackage
然后 运行 您的测试代码一样。这是您通常不需要从 test/Project.toml
. 中的主要 Project.toml
复制所有部门的唯一原因
- 由于
using Blueprint
方法由于其他原因在这里失败,当您简单地 include
来自 src/blueprint.jl
的代码时,该文件中的 using
将依次失败,因为这些软件包不存在于 test/Project.toml
的活动环境中(即使它们存在于您的系统其他地方)。
- 因此,使用当前
include("../src/blueprint.jl")
方法快速解决问题的一种方法是将这些依赖项简单地添加到 test/Project.toml
但是,解决您在 using Blueprint
中遇到的问题会更令人满意。在没有看到你的包的完整结构的情况下,我没有足够的信息来调试它,但我建议作为一个开始
- 确保您的代码是 properly structured as a package
- 测试即使未注册,您也可以通过 git repo URL(即
] add https://some_website.com/you/Blueprint.jl
) 从 REPL ] add
您的包裹
编辑:
检查评论中链接的代码 (https://github.com/jonasseglare/Blueprint),发现其他一些问题:
- 虽然它们已经默认安装,但现在的标准库确实需要包含在 [deps] 中。在这种情况下,这意味着
LinearAlgebra
stdlib
- 您在测试脚本中明确
using
的任何包,除了您的包本身,do 需要添加到 test/Project.toml
。即,任何您在测试脚本中 直接 using
从 运行的包(而不是通过包的导出函数间接使用)都需要包含在 test/Project.toml
。
在你的情况下,后者似乎意味着 LinearAlgebra
和 FunctionalCollections
,但不是 Setfield
(那个只需要包含在常规 Project.toml
中,因为它不是直接用在runtests.jl
).
因此,通过一些 minor changes to your repo 我们可以简单地
] add https://github.com/brenhinkeller/Blueprint
] test Blueprint
或者,因为您更喜欢使用命令行
user$ julia -e "using Pkg; Pkg.add(url=\"https://github.com/brenhinkeller/Blueprint\")
user$ julia -e "using Pkg; Pkg.test(\"Blueprint\")"
Testing Blueprint
Status `/private/var/folders/qk/2qyrdb854mvd2tn4crc802lw0000gn/T/jl_fSypP7/Project.toml`
[c1615a0c] Blueprint v0.1.0 `https://github.com/brenhinkeller/Blueprint#master`
[de31a74c] FunctionalCollections v0.5.0
[37e2e46d] LinearAlgebra `@stdlib/LinearAlgebra`
[8dfed614] Test `@stdlib/Test`
Status `/private/var/folders/qk/2qyrdb854mvd2tn4crc802lw0000gn/T/jl_fSypP7/Manifest.toml`
[c1615a0c] Blueprint v0.1.0 `https://github.com/brenhinkeller/Blueprint#master`
[187b0558] ConstructionBase v1.3.0
[de31a74c] FunctionalCollections v0.5.0
[1914dd2f] MacroTools v0.5.9
[ae029012] Requires v1.3.0
[efcf1570] Setfield v0.8.1
[56f22d72] Artifacts `@stdlib/Artifacts`
[2a0f44e3] Base64 `@stdlib/Base64`
[9fa8497b] Future `@stdlib/Future`
[b77e0a4c] InteractiveUtils `@stdlib/InteractiveUtils`
[8f399da3] Libdl `@stdlib/Libdl`
[37e2e46d] LinearAlgebra `@stdlib/LinearAlgebra`
[56ddb016] Logging `@stdlib/Logging`
[d6f4376e] Markdown `@stdlib/Markdown`
[9a3f8284] Random `@stdlib/Random`
[ea8e919c] SHA `@stdlib/SHA`
[9e88b42a] Serialization `@stdlib/Serialization`
[8dfed614] Test `@stdlib/Test`
[cf7118a7] UUIDs `@stdlib/UUIDs`
[e66e0078] CompilerSupportLibraries_jll `@stdlib/CompilerSupportLibraries_jll`
[4536629a] OpenBLAS_jll `@stdlib/OpenBLAS_jll`
[8e850b90] libblastrampoline_jll `@stdlib/libblastrampoline_jll`
Testing Running tests...
Test Summary: | Pass Total
Plane tests | 7 7
Test Summary: | Pass Total
Plane intersection | 2 2
Test Summary: | Pass Total
Plane intersection 2 | 4 4
Test Summary: | Pass Total
Plane shadowing | 3 3
Test Summary: | Pass Total
Polyhedron tests | 3 3
Test Summary: | Pass Total
Polyhedron tests 2 | 5 5
Test Summary: | Pass Total
Beam tests | 2 2
Test Summary: | Pass Total
Half-space test | 2 2
Test Summary: | Pass Total
Ordered pair test | 2 2
Test Summary: | Pass Total
Test plane/line intersection | 2 2
Test Summary: | Pass Total
Update line bounds test | 21 21
Testing Blueprint tests passed
FWIW,您还应该能够混合和匹配那些命令行和 REPL 方法(即,在 repl 中安装,通过命令行测试,反之亦然)。
虽然我最初没有考虑过这种情况,但评论中讨论的另一种可能性是希望在没有或不依赖 git 远程的情况下测试包的本地状态;在这种情况下,@Rulle 报告激活包目录,即
julia -e "using Pkg; Pkg.activate(\".\"); Pkg.test(\"Blueprint\")"
或
julia --project=. -e "using Pkg; Pkg.test(\"Blueprint\")"
或 REPL 中的等价物
] activate .
] test Blueprint
假设包目录当前是本地目录.
我自己的问题的可能答案:
要使其正常运行,请在使用 --project
调用脚本时在命令行中指定主项目根目录。在这种情况下,我们会调用
julia --project=/home/jonas/prog/julia/blueprint test/test_blueprint.jl
不过好像有什么隐藏状态我不太明白,因为这个命令运行一次后,好像--project
这个选项可以省略了。另一方面,我也试图提供一个废话项目目录,例如/tmp
:
julia --project=/tmp test/test_blueprint.jl
有时它仍会 运行 单元测试 (!) 有时不会。但是当它运行单元测试失败时,只要我指定正确的路径,它就会再次成功,即/home/jonas/prog/julia/blueprint
。我也不明白这与我使用 using blueprint
还是 include('../src/blueprint.jl')
如何相互作用,但似乎当我使用 using
时,它只起作用 iff --project
路径设置正确。但是我还是不确定。
我正在尝试从命令行 运行 Julia 单元测试,但单元测试失败 运行 因为它们找不到我在主项目中使用的依赖项。我怎样才能使这项工作?我尝试执行的实际命令是来自项目根目录的 julia test/test_blueprint.jl
。下面是更多详细信息。
有关设置的详细信息
我的项目位于路径/home/jonas/prog/julia/blueprint
。在该目录中,我有一个包含这些行的 Project.toml
文件:
name = "blueprint"
uuid = "c1615a0c-c255-402d-ae34-0b88819b43c6"
authors = [""]
version = "0.1.0"
[deps]
FunctionalCollections = "de31a74c-ac4f-5751-b3fd-e18cd04993ca"
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
连同 Manifest.toml
文件。
我在 test/
有一个子目录,其中包含我在 this guide 之后创建的单元测试,该目录包含另一个 Project.toml
文件,其中包含
[deps]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
有一个包含单元测试的文件 test/test_blueprint.jl
,该文件以
using Test
include("../src/blueprint.jl") # Alternative 1
#using blueprint # Alternative 2
using FunctionalCollections
using LinearAlgebra
...
正在测试的实际代码在文件 src/blueprint.jl
.
问题详情
从项目根目录,我尝试 运行 使用命令 julia test/test_blueprint.jl
进行单元测试。当我 运行 该命令时,它会产生以下输出:
ERROR: LoadError: ArgumentError: Package Setfield not found in current path:
- Run `import Pkg; Pkg.add("Setfield")` to install the Setfield package.
Stacktrace:
[1] require(into::Module, mod::Symbol)
@ Base ./loading.jl:967
[2] include(fname::String)
@ Base.MainInclude ./client.jl:451
[3] top-level scope
@ ~/prog/julia/blueprint/test/test_blueprint.jl:8
in expression starting at /home/jonas/prog/julia/blueprint/src/blueprint.jl:1
in expression starting at /home/jonas/prog/julia/blueprint/test/test_blueprint.jl:8
提示找不到依赖项Setfield
。如果我从
test/test_blueprint.jl
include("../src/blueprint.jl") # Alternative 1
#using blueprint # Alternative 2
至
#include("../src/blueprint.jl") # Alternative 1
using blueprint # Alternative 2
它仍然失败,但出现不同的错误:
ERROR: LoadError: ArgumentError: Package blueprint not found in current path:
- Run `import Pkg; Pkg.add("blueprint")` to install the blueprint package.
Stacktrace:
[1] require(into::Module, mod::Symbol)
@ Base ./loading.jl:967
in expression starting at /home/jonas/prog/julia/blueprint/test/test_blueprint.jl:9
问题:如何从命令行进行单元测试运行?
请注意,我 可以 运行 通过使用 C-c C-a
在 src/blueprint.jl
文件并在单元测试文件 test/test_blueprint.jl
中调用 C-c C-b
。我的 Julia 版本是 1.7.0 (2021-11-30)。不要犹豫,要求更多说明。
首先,一些可能不会(但可能会)导致此处问题的命名约定:
- 按照惯例,包名称以单个大写字母开头,因此我建议将名称更改为
Blueprint
无处不在 - 默认情况下,
] test
运行s 测试在test/runtests.jl
中找到,所以我建议将您的顶级测试脚本命名为runtests.jl
以避免混淆,即使尽管从此处的错误来看test
确实以某种方式找到您的test_blueprint.jl
文件。
现在,虽然我无法在没有您的软件包的完整代码的情况下进行测试,但我怀疑这里发生的情况如下:
- 通常,
test/Project.toml
中不需要您正在测试的包的依赖项(比方说MyPackage
),因为它们在MyPackage
中是隐式的。因此,在成功using MyPackage
之后,虽然它们仍然无法用于在您的测试脚本 中编写的任何函数 (test/runtests.jl
),但 将 可用于MyPackage
中编写的函数——就像您在 REPL 中键入]using MyPackage
然后 运行 您的测试代码一样。这是您通常不需要从test/Project.toml
. 中的主要 - 由于
using Blueprint
方法由于其他原因在这里失败,当您简单地include
来自src/blueprint.jl
的代码时,该文件中的using
将依次失败,因为这些软件包不存在于test/Project.toml
的活动环境中(即使它们存在于您的系统其他地方)。 - 因此,使用当前
include("../src/blueprint.jl")
方法快速解决问题的一种方法是将这些依赖项简单地添加到test/Project.toml
Project.toml
复制所有部门的唯一原因
但是,解决您在 using Blueprint
中遇到的问题会更令人满意。在没有看到你的包的完整结构的情况下,我没有足够的信息来调试它,但我建议作为一个开始
- 确保您的代码是 properly structured as a package
- 测试即使未注册,您也可以通过 git repo URL(即
] add https://some_website.com/you/Blueprint.jl
) 从 REPL
] add
您的包裹
编辑: 检查评论中链接的代码 (https://github.com/jonasseglare/Blueprint),发现其他一些问题:
- 虽然它们已经默认安装,但现在的标准库确实需要包含在 [deps] 中。在这种情况下,这意味着
LinearAlgebra
stdlib - 您在测试脚本中明确
using
的任何包,除了您的包本身,do 需要添加到test/Project.toml
。即,任何您在测试脚本中 直接using
从 运行的包(而不是通过包的导出函数间接使用)都需要包含在test/Project.toml
。 在你的情况下,后者似乎意味着LinearAlgebra
和FunctionalCollections
,但不是Setfield
(那个只需要包含在常规Project.toml
中,因为它不是直接用在runtests.jl
).
因此,通过一些 minor changes to your repo 我们可以简单地
] add https://github.com/brenhinkeller/Blueprint
] test Blueprint
或者,因为您更喜欢使用命令行
user$ julia -e "using Pkg; Pkg.add(url=\"https://github.com/brenhinkeller/Blueprint\")
user$ julia -e "using Pkg; Pkg.test(\"Blueprint\")"
Testing Blueprint
Status `/private/var/folders/qk/2qyrdb854mvd2tn4crc802lw0000gn/T/jl_fSypP7/Project.toml`
[c1615a0c] Blueprint v0.1.0 `https://github.com/brenhinkeller/Blueprint#master`
[de31a74c] FunctionalCollections v0.5.0
[37e2e46d] LinearAlgebra `@stdlib/LinearAlgebra`
[8dfed614] Test `@stdlib/Test`
Status `/private/var/folders/qk/2qyrdb854mvd2tn4crc802lw0000gn/T/jl_fSypP7/Manifest.toml`
[c1615a0c] Blueprint v0.1.0 `https://github.com/brenhinkeller/Blueprint#master`
[187b0558] ConstructionBase v1.3.0
[de31a74c] FunctionalCollections v0.5.0
[1914dd2f] MacroTools v0.5.9
[ae029012] Requires v1.3.0
[efcf1570] Setfield v0.8.1
[56f22d72] Artifacts `@stdlib/Artifacts`
[2a0f44e3] Base64 `@stdlib/Base64`
[9fa8497b] Future `@stdlib/Future`
[b77e0a4c] InteractiveUtils `@stdlib/InteractiveUtils`
[8f399da3] Libdl `@stdlib/Libdl`
[37e2e46d] LinearAlgebra `@stdlib/LinearAlgebra`
[56ddb016] Logging `@stdlib/Logging`
[d6f4376e] Markdown `@stdlib/Markdown`
[9a3f8284] Random `@stdlib/Random`
[ea8e919c] SHA `@stdlib/SHA`
[9e88b42a] Serialization `@stdlib/Serialization`
[8dfed614] Test `@stdlib/Test`
[cf7118a7] UUIDs `@stdlib/UUIDs`
[e66e0078] CompilerSupportLibraries_jll `@stdlib/CompilerSupportLibraries_jll`
[4536629a] OpenBLAS_jll `@stdlib/OpenBLAS_jll`
[8e850b90] libblastrampoline_jll `@stdlib/libblastrampoline_jll`
Testing Running tests...
Test Summary: | Pass Total
Plane tests | 7 7
Test Summary: | Pass Total
Plane intersection | 2 2
Test Summary: | Pass Total
Plane intersection 2 | 4 4
Test Summary: | Pass Total
Plane shadowing | 3 3
Test Summary: | Pass Total
Polyhedron tests | 3 3
Test Summary: | Pass Total
Polyhedron tests 2 | 5 5
Test Summary: | Pass Total
Beam tests | 2 2
Test Summary: | Pass Total
Half-space test | 2 2
Test Summary: | Pass Total
Ordered pair test | 2 2
Test Summary: | Pass Total
Test plane/line intersection | 2 2
Test Summary: | Pass Total
Update line bounds test | 21 21
Testing Blueprint tests passed
FWIW,您还应该能够混合和匹配那些命令行和 REPL 方法(即,在 repl 中安装,通过命令行测试,反之亦然)。
虽然我最初没有考虑过这种情况,但评论中讨论的另一种可能性是希望在没有或不依赖 git 远程的情况下测试包的本地状态;在这种情况下,@Rulle 报告激活包目录,即
julia -e "using Pkg; Pkg.activate(\".\"); Pkg.test(\"Blueprint\")"
或
julia --project=. -e "using Pkg; Pkg.test(\"Blueprint\")"
或 REPL 中的等价物
] activate .
] test Blueprint
假设包目录当前是本地目录.
我自己的问题的可能答案:
要使其正常运行,请在使用 --project
调用脚本时在命令行中指定主项目根目录。在这种情况下,我们会调用
julia --project=/home/jonas/prog/julia/blueprint test/test_blueprint.jl
不过好像有什么隐藏状态我不太明白,因为这个命令运行一次后,好像--project
这个选项可以省略了。另一方面,我也试图提供一个废话项目目录,例如/tmp
:
julia --project=/tmp test/test_blueprint.jl
有时它仍会 运行 单元测试 (!) 有时不会。但是当它运行单元测试失败时,只要我指定正确的路径,它就会再次成功,即/home/jonas/prog/julia/blueprint
。我也不明白这与我使用 using blueprint
还是 include('../src/blueprint.jl')
如何相互作用,但似乎当我使用 using
时,它只起作用 iff --project
路径设置正确。但是我还是不确定。