本文介绍了pytest 配置问题(从鼻子测试(71 秒)到 pytest(153​​6 秒)的转换)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:

pytest(由政策决定)运行与 nosetest 相同的测试套件(585 个测试)需要 1536 秒,后者运行 71 秒.

pytest (decided by policy) takes 1536 seconds to run the same test suite (585 tests) as nosetest, which runs in 71 seconds.

pytest.ini 文件是:

[pytest]
python_files = tests_*.py *_tests.py
norecursedirs = .idea  (pycharm env).
testpaths = tests

并将文件放在项目的根目录下:

And the file is placed at the root of the project:

root
 |-+ mod1
 | |-- core.py
 | |-- utils.py
 |-+ mod2
 | |-- core.py
 | |-- utils2.py
 |-+ tests
 | |-- test_mod1
 | |-- test_mod2
 |-+ utils (don't test).
 | |-- u1.py
 | |-- u2.py
 |- pytest.ini
 |- readme.md

我检查过的事情(遵循其他 14 篇 SO 帖子的建议):

Things I've checked (following advice from the 14 other SO posts):

  • 通过/失败的数量是相同的.
  • 当使用 pytests 单独运行测试时,它们需要大约 20 毫秒.
  • 使用 pytests 运行文件夹时,10-20 个测试需要 14-15 秒.
  • 测试套件有一个环境,没有 env 或 os 魔法.只是很多技术逻辑.
  • 每个 test_xyz.py 文件都有自己独立的 def setupdef teardown,用于创建/删除 sqlite 数据库.测试通过添加新事务和检查添加内容与数据库交互.示例:
  • The number of Pass/Fails is the same.
  • When running the tests individually with pytests they take ~ 20ms.
  • When running the folder with pytests 10-20 tests take 14-15 seconds.
  • The test suite has one environment, there's no env or os magic. Just lots of technical logic.
  • Each test_xyz.py file has it's own isolated def setup and def teardown that creates/drop an sqlite database. The tests interact with the database, by adding new transactions and checking the additions. Example:
global db

def setup():
   db = get_new_db()

def teardown():
   pass

def test_01():
   w = Widget(db)  # create widget instance.
   w.add_friend('[email protected]')
   assert '[email protected]' in w.friends()

问题:

  1. 我真的需要在每 585 次测试的 setupteardown 上贴上 @pytest.fixtures(scope='module') 吗?我希望不会.

  1. Do I really have to plaster @pytest.fixtures(scope='module') on the setup and teardown of every 585 tests? I hope not.

如何使 pytest 的运行时与 nosetests 类似?

What can I do to get the runtime of pytest to be similar to nosetests?

推荐答案

我不知道为什么 pytest 选择在 pytest_runtest_setup 钩子中调用模块设置函数每个测试运行一次而不是模块范围的自动使用装置,但是 这里是:

I'm not sure why pytest chose to invoke the module setup function in a pytest_runtest_setup hook that runs once per each test instead of a module-scoped autouse fixture, but here it is:

@hookimpl(trylast=True)
def pytest_runtest_setup(item):
    if is_potential_nosetest(item):
        if not call_optional(item.obj, "setup"):
            # call module level setup if there is no object level one
            call_optional(item.parent.obj, "setup")
        # XXX this implies we only call teardown when setup worked
        item.session._setupstate.addfinalizer((lambda: teardown_nose(item)), item)

这意味着您需要将设置/拆卸函数重命名为 setup_module()/teardown_module().如果您使用的是 Linux/MacOS,您可以使用 sed 结合 grep 进行批量重命名:

This means you'll need to rename the setup/teardown functions to setup_module()/teardown_module(). If you're on Linux/MacOS, you can use sed combined with grep for batch renaming:

$ grep -lr "\(def setup():\|def teardown():\)" | \
  xargs sed -i 's/def setup():/def setup_module():/g;s/def teardown():/def teardown_module():/g'

这篇关于pytest 配置问题(从鼻子测试(71 秒)到 pytest(153​​6 秒)的转换)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-12 22:26