python 测试之 pytest flask app 初探

Posted:   May 02, 2020

Edited:   May 02, 2020

Status:   Writing

Tags :   Python

Categories :   Python

Were equations, pictures or diagrams not properly rendered, please refresh the page. If the problem persists, you can contact me.

背景

使用 pytest 测试 flask api service

框架之选择

为什么选 pytest? 并没有特别原因, 只是刚好看到有个 pytest-flask package, 就先试试了, 用起来还好, 就记录一下.

框架中用到了 fixture, 就是在实际测试的前后加入 setup, teardown 等操作, 是测试必备之选.

测试的几大要素就不多说了.

直接上步骤

安装: pip install pytest-flask

目录结构:

- module1
    - __init__.py
    - src
        - __init__.py
        - app.py
        - config.py
    - test
        - __init__.py
        - conftest.py
        - pytest.ini
        - test_f1.py

创建 flask api service

参考 Application Setup — Flask Documentation (1.1.x)

  • 用工厂模式, 在 init.py 中创建 create_app 方法
  • 在 app.py 中导入: from src.app import create_app

src/init.py:

import os
from flask import Flask

def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__, instance_relative_config=False)
    app.config.from_mapping(
        SECRET_KEY='dev',
        DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
    )

    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_pyfile('config.py', silent=True)
    else:
        # load the test config if passed in
        app.config.from_pyfile(test_config)

    # ensure the instance folder exists
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    # a simple page that says hello
    @app.route('/hello')
    def hello():
        return 'Hello, World!'

    return app

app.py:

from . import create_app
app = create_app()

测试 api service

在 conftest.py 中创建 fixture: @pytest.fixture

import os
import tempfile
import pytest
from src.app import create_app

@pytest.fixture
def client():
    flask_app = create_app() 
    # Flask provides a way to test your application by exposing the Werkzeug test Client
    # and handling the context locals for you.
    client = flask_app.test_client()
    # Establish an application context before running the tests.
    ctx = flask_app.app_context()
    ctx.push()
    yield client  # this is where the testing happens!
    ctx.pop()

在 test_f1.py 中:

import os
def test_f1(client, capsys):
    '''Test f1
    '''
    res = client.get('/hello')
    captured = capsys.readouterr()
    assert 'error' not in captured.err
    assert b'Hello, World!' in res.data

测试范围

有些 test 如果想 ignore 怎么办?

在 conftest.py 中添加:

collect_ignore = [
    "test_f1.py"
    ]

当运行 pytest 的时候, “test_f1.py”就不会在 collected 列表中了.

参考: Changing standard (Python) test discovery — pytest documentation

Tutorials

ChangLog

  • 2020-05-03 init

Comments


Be the first one to comment on this page!
You can use extended GitHub flavored markdown in your comment. Commenting FAQs & Guidelines