背景
我正在使用 pytest 来测试将数据推送到数据库的网络抓取工具。该类仅提取 html 并将 html 推送到数据库以便稍后解析。我的大部分测试都使用虚拟数据来表示 html。
问题
我想做一个测试,从网站上抓取一个网页,但我希望测试自动关闭,除非指定。类似的情况可能是,如果您有一个您不想总是运行的昂贵或耗时的测试。
预期解决方案
除非我让 pytest 运行所有被抑制的测试,否则我期待某种抑制测试的标记,但我没有在文档中看到它。
我做了什么
- 我目前正在使用跳过标记并将其注释掉。
- 尝试使用 skipif 标记,并使用命令提示符下的此命令
pytest test_file.py 1
和测试文件中的以下代码为 python 脚本提供参数。问题是,当我尝试为我的 test_file 提供参数时,pytest 期望它是另一个文件名,所以我收到错误消息“没有测试在 0.00 秒内运行,错误:找不到文件:1”
if len(sys.argv) == 1:
RUN_ALL_TESTS = False
else:
RUN_ALL_TESTS = True
...
# other tests
...
@pytest.mark.skipif(RUN_ALL_TESTS)
def test_scrape_website():
...
我也许可以将测试视为固定装置并使用
@pytest.fixture(autouse=False)
,但不确定如何覆盖自动使用变量How to skip a pytest using an external fixture? 中陈述了类似的解决方案但是这个解决方案似乎比我需要的更复杂。
原文由 shane armstrong 发布,翻译遵循 CC BY-SA 4.0 许可协议
有几种方法可以处理这个问题,但我将介绍我在 Python 基线中看到的两种常见方法。
1)通过将“可选”测试放在另一个目录中来分隔测试。
不确定你的项目布局是什么样的,但你可以这样做(只有测试目录很重要,其余的只是一个玩具示例布局):
然后,当你调用pytest时,你可以通过做
pytest test/unit
来调用它—如果你 只想 运行单元测试(即只有test_something*.py
文件),或者pytest test/integration
你 只想 运行集成测试(即只test_optional.py
),或者pytest test
如果你想运行 所有 测试。因此,默认情况下,您可以只运行pytest test/unit
。我建议将这些调用包装在某种脚本中。我更喜欢
make
因为它对这种类型的包装很强大。然后你可以说make test
它只运行你的默认(快速)测试套件,或者make test_all
,它会运行所有测试(可能会或可能不会很慢)。您可以包装的示例 Makefile:
2) 使用
@pytest.mark.skipif
装饰器明智地标记您的测试,但使用环境变量作为触发器我不太喜欢这个解决方案,对我来说感觉有点随意(很难说出在任何给定的情况下正在运行哪一组测试
pytest
运行)。但是,您可以做的是定义一个环境变量,然后将该环境变量绑定到模块中以检测您是否要运行所有测试。环境变量依赖于 shell,但我会假装你有一个 bash 环境,因为它是一个流行的 shell。你可以做
export TEST_LEVEL="unit"
只是为了快速单元测试(所以这将是你的默认值),或者export TEST_LEVEL="all"
为你所有的测试。然后在你的测试文件中,你可以像这样做你最初想做的事情:注意: 将测试级别命名为“单元”和“集成”是无关紧要的。您可以随意命名它们。您还可以有很多级别(比如夜间测试或性能测试)。
此外,我认为选项 1 是最好的方法,因为它不仅明确允许测试分离,而且还可以为测试的含义和表示添加语义和清晰度。但是软件中没有“一刀切”,您必须根据您的具体情况来决定您喜欢哪种方法。
喂!