[PYTHON] Unit test flask with pytest

Introduction

It is common for development testing to be automated using libraries and frameworks. So I tried to use pytest to automate unit testing of flask, but I couldn't find a simple example, so I've put together a simple example and a brief description.

environment

Installation

pip install pytestJust install with.

What you need to automate with pytest

What you need to automate unit tests with pytest is the source to be tested (the development to be tested) and the source that describes the test method. The source of the test method gives the arguments under test and the results of the function and describes how to compare them.

Simple function unit test automation

Before automating flask unit tests, let's look at how to use pytest through a simple function.

Source to be tested

Since testing is not possible without the source to be tested, prepare the source to be tested. In the example, we prepared a function that adds and returns arguments, but if it is the original development, the development product is equivalent.

testing_mod.py


def add_calc(a, b):
    return a + b

Source that describes the test method

Create a source that describes how to call the source to be tested and the result of the source. This source calls the function of the source under test, compares the result returned by the function under test with the result assumed here, and if it is correct, it is OK, and if it is incorrect, it is NG. In the example, import the testing_mod to be tested with `import testing_mod`, pass 1 and 2 to `testing_mod.add_calc ()`, and if the result returned is 3, it is OK. I am.

py_test_main.py


import pytest
import testing_mod

def test_ok_sample():
    result = testing_mod.add_calc(1, 2)
    assert 3 == result

Unit test execution

Now that we have the source of the test target and test method, we want to see the result for each function, so execute it with the -v option.

# pytest -v py_test_main.py

py_test_main.py .         [100%]                                                                                                                                       
====== 1 passed in 0.05s ======
PS C:\Users\xxxx\program\python> pytest -v py_test_main.py                                   
====== test session starts ======
platform win32 -- Python 3.6.5, pytest-5.3.5, py-1.8.1, pluggy-0.13.1 -- c:\users\xxxx\appdata\local\programs\python\python36-32\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\xxxx\program\python
collected 1 item                                                                                                                     
py_test_main.py::test_ok_sample PASSED     [100%] 

====== 1 passed in 0.02s ======

Looking at the result, the test_ok_sample created earlier became PASSED and ended normally, so the test is OK. The more functions you create, the more functions you will see.

Simple flask unit test automation

Automate flask unit testing. Unlike the simple function automation above, flask requires communication from the client, but unit tests use the functionality of flask to automate unit tests.

Source to be tested

Create the source for flask. In the example, we will create something that returns the root string when accessing /. If it is the original development, the development product is equivalent. For flask, see Summary of previous flasks.

flask_mod.py


from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/')
def root():
    return "root"

Source that describes the test method

Unlike the source of the function, the source that describes how to test flask needs to generate a client of flask and then make a request using that client to check the result.

Generating a test flask client

First, generate a client for testing. Import the app of the source under test and change the test config of the app to true. Then use the app `test_client ()` to generate the client. In the example below, the import of the source under test would be `from flask_mod import app`.

py_test_main.py


import pytest
from flask_mod import app

def test_flask_simple():
    app.config['TESTING'] = True
    client = app.test_client() 

Execution of the function under test

Using the client generated above, issue a request to the URL under test using the get and post functions. The result is a response from flask, so check with pytest's `assertion` to see if it gives the expected answer. In the example below, ``` result = client.get ('/')` `` issues a get request to / and the result is stored in result, so data (body) and root are compared. I will.

py_test_main.py


import pytest
from flask_mod import app

def test_flask_simple():
    app.config['TESTING'] = True
    client = app.test_client() 
    result = client.get('/')
    assert b'root' == result.data

Unit test execution

Now that you have the source for the test target and test method, run it.

# pytest -v py_test_main.py

====== 1 passed in 0.22s =======
PS C:\Users\xxxx\program\python\flask> pytest -v .\pytest_flask.py
====== test session starts ======
platform win32 -- Python 3.6.5, pytest-5.3.5, py-1.8.1, pluggy-0.13.1 -- c:\users\xxxx\appdata\local\programs\python\python36-32\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\xxxx\program\python\flask
collected 1 item

pytest_flask.py::test_flask_simple PASSED  [100%]

====== 1 passed in 0.20s =======

Looking at the result, the test_flask_simple created earlier became PASSED and ended normally, so the test is OK. If you create a lot of functions, the number of functions here will increase.

Example when unit test is in error

As a test, let's see the result when the character string to be compared with the character string returned by flask is set as sample.

# pytest -v pytest_flask.py
======= test session starts =======
platform win32 -- Python 3.6.5, pytest-5.3.5, py-1.8.1, pluggy-0.13.1 -- c:\users\xxxx\appdata\local\programs\python\python36-32\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\xxxx\program\python\flask
collected 1 item

pytest_flask.py::test_flask_simple FAILED                                                                                                                          [100%]

============ FAILURES ============= 
____________ test_flask_simple ____________

    def test_flask_simple():
        app.config['TESTING'] = True
        client = app.test_client()
        result = client.get('/')
>       assert b'sample' == result.data
E       AssertionError: assert b'sample' == b'root'
E         At index 0 diff: b's' != b'r'
E         Full diff:
E         - b'sample'
E         + b'root'

pytest_flask.py:8: AssertionError
======== 1 failed in 0.26s ========

Since sample and root are different, `AssertionError: assert b'sample' == b'root'` is displayed.

in conclusion

Unit test automation can be very useful if you have less effort to create automation scripts. The framework is a way to reduce that effort, but in addition to the above, there are other useful functions such as pre-processing and post-processing of the test, and trying multiple parameters with the same test method. ~~ Next, I will summarize the convenient methods. ~~ A convenient method is summarized in Give the parameters of the unit test of flask cleanly with pytest. In addition, the method of checking the coverage is summarized in Check the coverage of python with pytest-cov.

Recommended Posts

Unit test flask with pytest
Flask unit test environment (test_client)
Test standard output with Pytest
Unit test log output with python
Controlling test reruns with Luigi + pytest
Test Driven Development Startup with PySide & Pytest
numpy unit test
Give pytest clean parameters for flask unit tests
Rollback DB for each test with Flask + SQLAlchemy
Primality test with Python
Strengthen with code test ⑦
Strengthen with code test ⑨
Use Mock with pytest
Strengthen with code test ⑤
Strengthen with code test ④
Primality test with python
IP restrictions with Flask
Strengthen with code test ②
Unit test Databricks Notebook
Strengthen with code test ①
python unit test template
Hello world with flask
Programming with Python Flask
Strengthen with code test ⑧
Strengthen with code test ⑨
Deploy Flask with ZEIT Now
Test embedded software with Google Test
Touch Flask + run with Heroku
Hello World with Flask + Hamlish
API with Flask + uWSGI + Nginx
SNS Flask (Ajax) made with Flask
Web application development with Flask
Load test Websocket with Locust
View flask coverage with pytest-cov
Web application with Python + Flask ② ③
File upload with Flask + jQuery
Web application with Python + Flask ④
[Pytest] [mock] Web development beginners summarized unit test and mock in python.
Test Driven Development with Django Part 3
SNS Flask (Model) edition made with Flask
[LINE login] Verify state with Flask
Test Driven Development with Django Part 4
Test Driven Development with Django Part 6
[Memo] Links for developing with Flask
Creating a Flask server with Docker
Run the app with Flask + Heroku
Persist Flask API server with forever
[Python] Use Basic/Digest authentication with Flask
Test Driven Development with Django Part 2
Basic authentication and Digest authentication with Flask
Creating a simple app with flask
Build Flask environment with Dockerfile + docker-compose.yml
SNS made with Flask Flask (Blueprint, bcrypt)
Test Driven Development with Django Part 1
Post bulletin board creation with flask
Application development with Docker + Python + Flask
Test Driven Development with Django Part 5
Image upload function with Vue.js + Flask
Setting to debug test by entering the contents of the library with pytest