首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Pytest和动态夹具模块

Pytest和动态夹具模块
EN

Stack Overflow用户
提问于 2015-04-21 05:53:54
回答 3查看 2.9K关注 0票数 3

我正在使用pytest为一个可以在本地和云中运行的软件编写功能测试。我想创建两个模块,每个模块都有相同的模块/装置名称,并让pytest加载一个或另一个,这取决于我是在本地运行测试还是在云中运行测试:

代码语言:javascript
复制
/fixtures
/fixtures/__init__.py
/fixtures/local_hybrids
/fixtures/local_hybrids/__init__.py
/fixtures/local_hybrids/foo.py
/fixtures/cloud_hybrids
/fixtures/cloud_hybrids/__init__.py
/fixtures/cloud_hybrids/foo.py
/test_hybrids/test_hybrids.py

foo.py (两者都有):

代码语言:javascript
复制
import pytest
@pytest.fixture()
def my_fixture():
    return True

/fixtures/__init__.py

代码语言:javascript
复制
if True:
    import local_hybrids as hybrids
else:
    import cloud_hybrids as hybrids

/test_hybrids/test_hybrids.py

代码语言:javascript
复制
from fixtures.hybrids.foo import my_fixture

def test_hybrid(my_fixture):
   assert my_fixture

最后一个代码块当然不起作用,因为import fixtures.hybrids查看的是文件系统,而不是__init__.py的“伪”名称空间,后者与from fixtures import hybrids不同,后者可以正常工作(但这样就不能使用fixture,因为名称将包含点符号)。

我意识到我可以使用pytest_generate_test来动态地改变固定装置(也许?)但是我真的很讨厌在这个函数中手动管理每个fixture……我希望动态导入(如果x,导入这个,否则导入那个)是标准的Python,不幸的是它与fixtures机制冲突:

代码语言:javascript
复制
import fixtures
def test(fixtures.hybrids.my_fixture):  # of course it doesn't work :)
    ...

我还可以在init中一个接一个地导入每个fixture函数;更多的跑腿工作,但仍然是愚弄pytest并获得不带点的fixture名称的可行选择。

让我看看黑魔法。:)能做到吗?

EN

回答 3

Stack Overflow用户

发布于 2015-04-22 02:49:33

我认为在您的情况下,最好定义一个fixture - environment或其他更好的名称。

这个fixture可以只是一个来自os.environ‘’KEY‘的getter,也可以添加像here这样的自定义命令行参数,然后像使用here一样使用它,最终的用法是here

我想说的是,您需要将思维转换为依赖注入:一切都应该是固定的。在您的情况下(在我的插件中也是如此),运行时环境应该是一个fixture,它被签入到依赖于该环境的所有其他fixture中。

票数 1
EN

Stack Overflow用户

发布于 2016-03-11 00:31:17

你可能在这里遗漏了一些东西:如果你想重用这些fixture,你需要明确地说出来:

代码语言:javascript
复制
from fixtures.hybrids.foo import my_fixture

@pytest.mark.usefixtures('my_fixture')
def test_hybrid(my_fixture):
    assert my_fixture

在这种情况下,您可以调整pytest,如下所示:

代码语言:javascript
复制
from local_hybrids import local_hybrids_fixture
from cloud_hybrids import cloud_hybrids_fixture

fixtures_to_test = {
    "local":None,
    "cloud":None
}

@pytest.mark.usefixtures("local_hybrids_fixture")
def test_add_local_fixture(local_hybrids_fixture):
    fixtures_to_test["local"] = local_hybrids_fixture

@pytest.mark.usefixtures("cloud_hybrids_fixture")
def test_add_local_fixture(cloud_hybrids_fixture):
    fixtures_to_test["cloud"] = cloud_hybrids_fixture

def test_on_fixtures():
    if cloud_enabled:
        fixture = fixtures_to_test["cloud"]
    else:
        fixture = fixtures_to_test["local"]
    ...

如果周围有更好的解决方案,我也很感兴趣;)

票数 0
EN

Stack Overflow用户

发布于 2017-05-16 06:28:58

我真的不认为在python中有一种“好方法”可以做到这一点,但仍然可以通过少量的that来实现。您可以使用要使用的装置更新子文件夹的sys.path,并直接导入装置。在脏的情况下,它看起来像这样:

对于您的fixtures/__init__.py:

代码语言:javascript
复制
if True:
    import local as hybrids
else:
    import cloud as hybrids

def update_path(module):
    from sys import path
    from os.path import join, pardir, abspath
    mod_dir = abspath(join(module.__file__, pardir))
    path.insert(0, mod_dir)

update_path(hybrids)

并在客户机代码(test_hybrids/test_bribds.py)中:

代码语言:javascript
复制
import fixtures
from foo import spam

spam()

在其他情况下,您可以使用更复杂的操作将所有模块/包/函数等直接从云/本地文件夹假移动到fixture的__init__.py中。尽管如此,我认为-它不值得一试。

还有一件事-黑魔法不是最好的使用,我建议你使用一个带点的符号"import X from Y“-这是一个更稳定的解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29759117

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档