模块化灯具时,PyTest在包含多个测试文件的目录上失败

时间:2017-10-17 14:19:55

标签: python python-3.x unit-testing flask pytest

我使用Py.Test测试Python Flask应用程序中的函数。

当我使用一个" app_test.py"包含所有灯具和测试的文件。现在我已经将灯具拆分成他们自己的模块,并将测试分成不同的模块,每个模块都会导入我遇到问题的灯具模块。

如果我单独对每个模块运行测试,一切都很顺利: pytest tests/test_1.pypytest tests/test_2.pypytest tests/test_3.py等。但是,如果我想使用一个命令按顺序运行所有测试,例如pytest tests

我得到第一个测试通过模块,所有未来的模块报告错误:

AssertionError: A setup function was called after the first request was handled.  
This usually indicates a bug in the application where a module was not imported 
and decorators or other functionality was called too late.
E  To fix this make sure to import all your view modules, database models 
and everything related at a central place before the application starts 
serving requests.

一个文件中的所有测试和装置看起来都是这样的:

# app_test.py

from flask_app import create_app
@pytest.fixtures(scope="session")
def app(request):
    app = create_app()
    with app.app_context():
        yield app

@pytest.fixture(scope="session"):
def client(request, app):
    client = app.test_client()
    return client


def test1(client):
    # test body

def test2(client):
    # test body

...

我运行$ pytest app_test.py,一切运行完美。

现在让我们说我们将它们分成三个不同的模块:fixures.py,test_1.py和test_2.py。代码现在看起来像这样。

# tests/fixtures.py
from flask_app import create_app
@pytest.fixtures(scope="session")
def app(request):
    app = create_app()
    with app.app_context():
        yield app

@pytest.fixture(scope="session"):
def client(request, app):
    client = app.test_client()
    return client
# tests/test_1.py
from tests.fixtures import app, client
def test_1(client):
    # test body
# tests/test_2.py
from tests.fixtures import app, client
def test_2(client):
    # test body

如果我们运行$ pytest tests,那么tests / test_1.py将通过,而tests / test_2.py将引发错误。

我已查看此gist,并尝试使用@pytest.mark.usefixture标记测试函数但未成功。

如何在包含多个测试文件的目录上运行带有模块化灯具的Py.Test?

2 个答案:

答案 0 :(得分:5)

你稍微不正确地使用灯具。

具体来说,您声明了多个具有相同名称且具有相同功能对象的灯具,但在不同模块中检测到。从pytest的角度来看,这些应该是单独的函数,因为pytest会dir(module)来检测测试&文件夹具。但不知何故,由于同一个函数对象,我认为,pytest会记住它们是一样的;所以一旦你到达第二个测试文件,它会尝试本地检测到的灯具名称,但发现它已经准备好并失败了。

正确的用法是创建一个伪插件conftest.py,然后将所有灯具放在那里。声明后,这些灯具将可用于该目录和所有子目录中的所有文件。

注意:不得将此类灯具导入测试文件。灯具不是功能。 Pytest自动准备它们并将它们提供给测试。

# tests/conftest.py
import pytest
from flask_app import create_app

@pytest.fixtures(scope="session")
def app(request):
    app = create_app()
    with app.app_context():
        yield app

@pytest.fixture(scope="session"):
def client(request, app):
    client = app.test_client()
    return client

测试文件(注意没有导入!):

# tests/test_1.py
def test_1(client):
    # test body

# tests/test_2.py
def test_2(client):
    # test body

查看更多:https://docs.pytest.org/en/latest/writing_plugins.html

答案 1 :(得分:0)

如果您正在使用应用程序实例,那么它将为您工作:

metadata