使用特定设置启动Flask应用程序,运行查询并存储测试响应

2024-03-29 12:52:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经为我的Flask应用程序实现了单元测试。我用pytest。我的目标是确保一些预定义的查询总是返回相同的输出(一些json)。你知道吗

为了做到这一点,我使用一个fixture来启动一个带有测试设置的应用程序:

# Session for scope, otherwise server is reloaded everytime
@pytest.fixture(scope="session")
def app():

    os.environ["FLASK_ENV"] = "development"
    os.environ["TEST_SETTINGS"] = os.path.join(
        ds.WORK_DIR, "..", "tests", "settings.py"
    )

    app = create_app()

    # http://flask.pocoo.org/docs/1.0/api/#flask.Flask.test_client
    app.testing = True

    return app

然后我用pytest运行一个测试函数,它不是真正的测试函数:

# Freeze time for consistent output
@pytest.mark.usefixtures("live_server")
@pytest.mark.freeze_time("2018-01-01")
class TestLiveServer:

    @pytest.mark.skip(reason="should only be used to update the test data")
    def test_export(self):
        """Not a test function.

        Used to export questions outputs in json file to freeze the expected output

        """

        for q in TESTED_QUESTIONS:
            r = requests.post(
                url_for("query_direct", _external=True), json={"query": q}
            )
            print(r.text)

            filename = (
                "".join(filter(lambda c: str.isalnum(c) or c == " ", q))
                .lower()
                .replace(" ", "_")
                + ".json"
            )
            export_path = os.path.join("tests", "fake_responses", filename)

            data = {"query": q, "response": r.json()}

            with open(export_path, "w") as outfile:
                json.dump(data, outfile, indent=4, sort_keys=True)
                outfile.write("\n")

为了生成冻结的输出,我取消对pytest标记的注释,然后运行这个特定的测试。正如你所看到的,它不是很优雅,也不容易出错。有时我忘记重新启用标记,如果我一次运行所有测试,它首先重新生成假输出,然后再对它们运行单元测试。如果发生这种情况,我的测试不会失败,也不会发现潜在的错误(这就扼杀了这些测试的重点)。你知道吗

有没有一种方法可以单独运行这个特定的函数,或者使用一些pytest标志之类的东西?你知道吗


Tags: topathtestjsontrueappfordata
1条回答
网友
1楼 · 发布于 2024-03-29 12:52:22

这应该是一个独立的东西,而不是pytest测试套件的一部分(因为它不是一个测试),但是您可以通过利用pytest的skipping facilities绕过它。你知道吗

# redefine test_export to feature a conditional skip
@pytest.mark.skipif(not os.getenv('FREEZE_OUTPUTS'), reason='')
def test_export(self):

这里我们跳过这个测试,除非设置了FREEZE_OUTPUTS环境变量。你知道吗

然后可以通过从命令行调用以下命令来运行此测试(仅定义此调用的环境变量):

$ FREEZE_OUTPUTS=1 py.test <your_test_file>::TestLiveServer::test_export

它只会运行那个测试。在所有其他情况下,它将被跳过。你知道吗

您甚至可以按照上面的方法,将它声明为包含在session levelautouse=Trueso it's always included上的fixture,然后在fixture本身中添加一些逻辑来检查您是否定义了FREEZE_OUTPUTS,如果是的话,运行有问题的逻辑。比如:

@pytest.fixture(scope='session', autouse=True)
def frozen_outputs():
    if os.getenv('FREEZE_OUTPUTS'):
        # logic for generating the outputs goes here
    return  # do nothing otherwise

相关问题 更多 >