2

问题:

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

这些pytest.ini文件是:

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

并且该文件被放置在项目的根目录下:

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 帖子的建议):

  • 通过/失败的数量是相同的。
  • 当使用 pytests 单独运行测试时,它们需要大约 20 毫秒。
  • 使用 pytests 运行文件夹时,10-20 次测试需要 14-15 秒。
  • 测试套件只有一个环境,没有 env 或 os 魔法。只是很多技术逻辑。
  • 每个 test_xyz.py 文件都有自己的独立文件def setupdef teardown可以创建/删除一个 sqlite 数据库。测试通过添加新事务和检查添加与数据库交互。例子:
global db

def setup():
   db = get_new_db()

def teardown():
   pass

def test_01():
   w = Widget(db)  # create widget instance.
   w.add_friend('a@b.com')
   assert 'a@b.com' in w.friends()

问题:

  1. 我真的必须在每 585 次测试中setup涂抹@pytest.fixtures(scope='module')吗?teardown我希望不是。

  2. 我该怎么做才能使运行时pytest类似于nosetests

4

1 回答 1

2

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

@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/teardown 函数重命名为setup_module()/ teardown_module()。如果您使用的是 Linux/MacOS,则可以使用sed组合 withgrep进行批量重命名:

$ grep -lr "\(def setup():\|def teardown():\)" | \
  xargs sed -i 's/def setup():/def setup_module():/g;s/def teardown():/def teardown_module():/g'
于 2019-05-03T21:01:56.573 回答