A py.test插件,提供配置以简化inmanta模块测试。
项目描述
pytest-inmanta
用于测试inmanta模块的pytest插件
安装
pip install pytest-inmanta
如果您想使用pytest-inmanta
测试v2模块,请确保安装该模块
inmanta module install -e .
用法
此插件提供了一个测试夹具,可以编译、导出和部署代码,而无需运行实际的inmanta服务器。
def test_compile(project):
"""
Test compiling a simple model that uses std
"""
project.compile("""
host = std::Host(name="server", os=std::linux)
file = std::ConfigFile(host=host, path="/tmp/test", content="1234")
""")
夹具还提供了对模型内部结构的访问
assert len(project.get_instances("std::Host")) == 1
assert project.get_instances("std::Host")[0].name == "server"
对导出资源的访问
f = project.get_resource("std::ConfigFile")
assert f.permissions == 644
对编译输出和模拟文件系统的访问
def test_template(project):
"""
Test the evaluation of a template
"""
project.add_mock_file("templates", "test.tmpl", "{{ value }}")
project.compile("""import unittest
value = "1234"
std::print(std::template("unittest/test.tmpl"))
""")
assert project.get_stdout() == "1234\n"
并允许部署特定资源
# perform deploy
result = project.deploy_resource_v2("std::ConfigFile", expected_status=inmanta.const.ResourceState.deployed)
# assert the deploy performed no changes
result.assert_no_changes()
# assert the deploy produced specific log lines
result.assert_has_logline("Calling read_resource")
和干运行
result = project.dryrun_resource_v2("testmodule::Resource")
assert result.changes == {"value": {'current': 'read', 'desired': 'write'}}
# Or dryrun all resources at once
result = project.dryrun_all()
也可以一次性部署所有资源
results = project.deploy_all()
assert results.get_context_for("std::ConfigFile", path="/tmp/test").status == ResourceState.deployed
dryrun_all
和deploy_all
函数返回一个包含一些有用的辅助函数以进行一些基本检查的Result
对象。
我们可以检查结果中每个资源是否具有正确的状态
results = project.dryrun_all()
results.assert_all(ResourceState.dry)
可以确定每个资源在其更改中是否都有purged
属性。这有助于断言资源是否将被创建(purged
设置为True)或删除(purged
设置为False)
results = project.dryrun_all()
results.assert_resources_have_purged()
相同的情况也适用于deploy_all
results = project.deploy_all()
results.assert_all(ResourceState.deployed)
要检查部署是否成功并且我们达到了期望的状态,可以在部署后进行干运行并检查是否有更改
results = project.deploy_all()
results.assert_all(ResourceState.deployed)
results = project.dryrun_all()
results.assert_has_no_changes()
为了方便,也可以一次性进行干运行和部署所有资源。此方法还断言干运行和部署通过上述基本检查。它返回一个DeployResultCollection
,该集合汇总了干运行和部署的Results
。
resutls = project.dryrun_and_deploy_all(assert_create_or_delete=True)
results.first_dryrun.assert_all(ResourceState.dry)
results.deploy.assert_all(ResourceState.deployed)
results.last_dryrun.assert_all(ResourceState.dry)
使用inmanta_plugins
夹具测试v1模块中定义的函数和类也是可能的。夹具将inmanta模块作为其属性公开,并在访问时动态导入它们。对于v2模块,建议的方法是只使用顶层导入而不是使用夹具。
def test_example(inmanta_plugins):
inmanta_plugins.testmodule.regular_function("example")
这种动态性是必需的,因为编译器在调用project.compile
时重置模块导入。因此,如果您将模块存储在局部变量中,它将不会在编译过程中幸存。因此,建议您以完全限定方式(使用夹具)访问inmanta_plugins
包中的模块。以下示例演示了这一点。
def test_module_inequality(project, inmanta_plugins):
cached_module = inmanta_plugins.testmodule
assert cached_module is inmanta_plugins.testmodule
project.compile("import testmodule")
assert cached_module is not inmanta_plugins.testmodule
虽然您可以直接从inmanta_plugins
包导入,但夹具对模块重新加载进行了抽象。如果没有夹具,您将需要在project.compile
之后重新导入。
测试插件
以下插件为例
# <module-name>/plugins/__init__.py
from inmanta.plugins import plugin
@plugin
def hostname(fqdn: "string") -> "string":
"""
Return the hostname part of the fqdn
"""
return fqdn.split(".")[0]
一个测试用例,用于测试此插件,看起来像这样
# <module-name>/tests/test_hostname.py
def test_hostname(project):
host = "test"
fqdn = f"{host}.something.com"
assert project.get_plugin_function("hostname")(fqdn) == host
- 第3行:创建一个pytest测试用例,该测试用例需要
project
夹具。 - 第6行:调用函数
project.get_plugin_function(plugin_name: str): FunctionType
,该函数返回名为plugin_name
的插件函数。因此,此行测试当使用参数fqdn
调用插件函数hostname
时是否返回host
。
高级用法
由于pytest-inmanta保留inmanta_plugins
子模块对象以支持顶层导入,任何有状态模块(在模块命名空间中保持状态的全局Python变量)必须定义清理逻辑以在编译之间重置状态。pytest-inmanta期望这样的清理函数是同步函数,位于inmanta_plugins
子模块(任何深度)的顶层作用域(定义在模块对象上,而不是在类中)。它们的名称应以"inmanta_reset_state"开头,并且不应接受任何参数。例如
# <module-name>/plugins/state.py
MY_STATE = set()
def inmanta_reset_state() -> None:
global MY_STATE
MY_STATE = set()
可以定义多个清理函数,在这种情况下,没有定义保证的调用顺序。
选项
以下选项可用。
--venv
:放置测试虚拟环境的文件夹(将由所有测试共享),覆盖INMANTA_TEST_ENV
。此选项依赖于符号链接支持。此选项在所有Windows版本上均不起作用。在Windows 10上,您需要在管理员外壳中运行pytest。使用固定的虚拟环境可以加快测试的运行速度。--pip-index-url
:指定从哪里安装依赖项的pip索引。可以多次指定以添加多个索引。当设置时,即使设置了pip-use-system-config
,也会覆盖系统索引-url。(覆盖PIP_INDEX_URL
,默认为[]
)--pip-pre
,--no-pip-pre
允许pip安装预发布包吗?(覆盖PIP_PRE
,默认为--install-mode != release
)--pip-use-system-config
允许pytest-inmanta使用系统pip配置吗?(覆盖INMANTA_PIP_USE_SYSTEM_CONFIG
,默认为False
)--use-module-in-place
:使得inmanta将你的模块目录的父目录添加到其目录路径中,而不是将你的模块复制到临时libs目录。这允许你对特定版本的依赖模块进行测试。使用此选项可以提高测试速度,因为模块依赖项不会多次下载。--module-repo
:从哪里下载v1模块的位置,覆盖INMANTA_MODULE_REPO
。默认值是inmanta的github组织。可以通过空格分隔它们或通过多次传递参数来传递多个仓库。--install-mode
:在这次测试期间下载的v1模块要使用的安装模式,覆盖INMANTA_INSTALL_MODE
。--no-load-plugins
:不要在Project类中加载插件。覆盖INMANTA_NO_LOAD_PLUGINS
。当在测试插件时,如果不使用此选项,在project.get_plugin_function
方法中,模块的plugin/__init__.py
可能会被加载多次,这可能导致在具有副作用的情况下出现问题,因为它们也会多次执行。--no-strict-deps-check
:选项以对要求使用传统的检查(更宽松)来运行pytest-inmanta。默认情况下将使用新的严格检查。
使用通用的pytest选项--log-cli-level
来显示Inmanta日志器以查看任何设置或清理警告。例如,--log-cli-level=INFO
与pytest-cov兼容性
当pytest-inmanta与pytest-cov pytest插件一起使用时,应设置--use-module-in-place
选项。如果没有设置此选项,报告的测试覆盖率将是不正确的。
使用pytest选项框架
pytest-inmanta
扩展包含一个框架,可以帮助创建在测试套件或测试扩展中使用的pytest选项。
每个选项都可以通过CLI参数或环境变量设置。如果两者都设置,则CLI参数值优先于环境变量。
在创建新选项时,请注意将其放置在pytest始终会加载的位置,例如conftest.py
文件。
此处显示可以使用的不同类型测试参数:pytest_inmanta/test_parameters
。目前支持的类型包括
BooleanTestParameter
EnumTestParameter
FloatTestParameter
IntegerTestParameter
ListTestParameter
PathTestParameter
StringTestParameter
当然,您可以添加并使用自己的选项类型,只要它正确地扩展了基类TestParameter
。
项目详情
pytest_inmanta-3.0.0.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 9f8d715bf6a26a240900c83d933d76476497b043a5bb3331c5179a5e365ff283 |
|
MD5 | b2f95159cfa4e1ed55968da21c70fb7f |
|
BLAKE2b-256 | de08b82826de572b8d3d38b52eccef5d90020ce1e5c80dd920fd5f6431b7983c |