在不同的进程中运行py.test测试

发布于 2021-01-29 14:57:11

我正在尝试测试tensorflow程序。我正在使用参数化的py.test夹具设置tensorflow会话:

@pytest.fixture(scope="session", params=configuration)
def session(request):
    if request.param == 'tensorflow':
        return tf.Session()
    elif request.param == 'tensorflow-eager':
        tfe.enable_eager_execution()
        return tf.Session()
    elif ...

Tensorflow具有全局状态,因此一些测试启动会污染它。例如,启用急切执行后,无法禁用它。有没有一种方法可以指示py.test为每个测试创建一个新进程?还是使用参数化夹具来配置测试环境的另一种方法?用法示例:

@pytest.mark.parametrize("bias_type", ['variable', 'ndarray', 'list', 'tuple'])
@pytest.mark.parametrize("kernel_type", ['variable', 'ndarray', 'list', 'tuple'])
@pytest.mark.parametrize("input_type", ['variable', 'ndarray', 'list', 'tuple'])
def test_convolution(session, input_type, kernel_type, bias_type):
    ...
关注者
0
被浏览
100
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    如评论中所建议,使用pytest- xdist将是解决方案。该插件设计用于并行或分布式执行测试(甚至可以执行多平台),但是非常适合满足您在单独的过程中运行每个测试的请求-
    您可以使用--forked参数来实现。

    免责声明

    --forked参数在Windows上不起作用,因为Windows不支持fork-exec模型,并且不提供任何替代fork()

    快速演示

    让我们定义一个夹具,它将在运行每个测试之前尝试打开急切的执行:

    from tensorflow.contrib.eager.python import tfe
    
    import pytest
    
    
    @pytest.fixture(scope='function', autouse=True)
    def eager(request):
        tfe.enable_eager_execution()
    

    很显然,该夹具将无法通过所有测试,但第一个测试将失败,因为急切的执行只能进行一次。通过一些虚拟测试:

    def test_spam():
        assert True
    
    def test_eggs():
        assert True
    
    def test_bacon():
        assert True
    

    普通运行pytest失败,按预期进行:

    $ pytest -v
    ============================== test session starts ================================
    platform darwin -- Python 3.6.3, pytest-3.3.1, py-1.5.2, pluggy-0.6.0 -- /Users/hoefling/.virtualenvs/stackoverflow/bin/python3.6
    cachedir: .cache
    rootdir: /Users/hoefling/projects/private/stackoverflow/so-48234032, inifile:
    plugins: forked-0.2, mock-1.6.3, hypothesis-3.44.4
    collected 3 items
    
    test_spam.py::test_spam PASSED                                                [ 33%]
    test_spam.py::test_eggs ERROR                                                 [ 66%]
    test_spam.py::test_bacon ERROR                                                [100%]
    
    ...
    E       ValueError: Do not call tfe.enable_eager_execution more than once in the
    same process. Note eager-mode methods such as tfe.run() also call 
    tfe.enable_eager_execution.
    ...
    

    现在安装pytest-xdist

    $ pip install pytest-xdist
    

    并重新运行测试:

    $ pytest -v --forked
    ============================== test session starts ================================
    platform darwin -- Python 3.6.3, pytest-3.3.1, py-1.5.2, pluggy-0.6.0 -- /Users/hoefling/.virtualenvs/stackoverflow/bin/python3.6
    cachedir: .cache
    rootdir: /Users/hoefling/projects/private/stackoverflow/so-48234032, inifile:
    plugins: forked-0.2, xdist-1.22.0, mock-1.6.3, hypothesis-3.44.4
    collected 3 items
    
    test_spam.py::test_spam PASSED                                                [ 33%]
    test_spam.py::test_eggs PASSED                                                [ 66%]
    test_spam.py::test_bacon PASSED                                               [100%]
    
    ============================= 3 passed in 6.09 seconds ============================
    

    测试仍然按顺序运行,但是每个测试都在一个自己的子流程中,因此它们都不会失败。

    现在您可以开始尝试并行执行,例如

    $ pytest -v --forked --numprocesses=auto
    

    等等。有关更多信息和更多用法示例,请参阅插件文档



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看