[PYTHON] Tutorial for doing Test Driven Development (TDD) in Flask ―― 1 Test Client

Introduction

We will teach you the know-how necessary for test-driven development with Flask over a total of 5 times (which is planned and subject to change). In this article, I will introduce the minimum sample code and its execution example for automatically testing Web applications and APIs developed with Flask.

1st article 2nd Tutorial for Test Driven Development (TDD) in Flask-2 Decorators 3rd writing 4th writing 5th writing

Target audience

--For those who are going to develop web applications or APIs with Flask --Those who want to study test automation

Overview

The minimum test of API created by Flask with Hello, World! as the return value is automatically performed using the test client.

Directory structure

Place the sample code used in this article in the following directory structure.

flask_01/
├── Dockerfile 
└── app
    ├── flask_app.py
    └── test
        └── test.py

docker version

$ docker --version
Docker version 19.03.12, build 48a66213fe

Code preparation

Dockerfile

Dockerfile


FROM python:3.6
USER root

RUN apt update
RUN /usr/local/bin/python -m pip install --upgrade pip
RUN pip install flask==1.1.2

COPY ./app /root/

WORKDIR /root/test

flask_app.py (tested)

Use a simple API that outputs Hello, World!.

flask_app.py


from flask import Flask
app = Flask(__name__)

@app.route('/hello_world')
def hello_world():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run(host="0.0.0.0",port=5000)

test.py (test code)

Details are given in the last section.

test.py


import sys
sys.path.append('../')
#From the filename of the flask application.What erased py
import flask_app
import unittest

#Class name works in Japanese
class Test_flask_app_Normal system(unittest.TestCase):
    # 1.Set common parameters
    def setUp(self):
        self.ENDPOINT    = "http://localhost:5000/{}"
        self.DATA        = None
        self.STATUS      = "200 OK"
        self.STATUS_CODE = 200
        self.ROUTE       = None
    #Test cases work in Japanese
    def test_1_hello_Being able to access the world(self):
        #Set required parameters for each case
        self.DATA  = b"Hello, World!"
        self.ROUTE = "hello_world"
        # 2.Connect test client and context with with minutes
        with flask_app.app.test_client() as client:
            # 3.Execute API using test client
            response = client.get(self.ENDPOINT.format(self.ROUTE))
        # 4.Perform a test using an assert statement
        assert response.data        == self.DATA
        assert response.status      == self.STATUS 
        assert response.status_code == self.STATUS_CODE

        return

if __name__ == '__main__':
    unittest.main()

Run the test

Check [Directory structure](#directory structure) and execute the following command.

$ ls
Dockerfile      app
$ docker build -t pytest .
~abridgement~
$ docker run -it pytest /usr/local/bin/python /root/test/test.py
.
----------------------------------------------------------------------
Ran 1 test in 0.004s

OK

Explanation of test.py (test code)

1. Set common parameters

Classes that inherit from ʻunittest.TestCasealways executesetUp (self)before executing the test case. Specifically,setUp (self)is executed before executingtest_1_flask_app to be accessible (self). Therefore, even if there are multiple test cases, it will be executed in the same way, so it is good to initialize the common parameters used in the class. Strictly different, but you can recognize that variables initialized in setUp (self)` can be used in common in all test cases in class.

2. Connect the test client and the context with the with statement

It is possible to use the test client by using the with syntax. The beginning of flask_app.app.test_client () is the base name of the python file under test with the extension removed. This time, the test target is flask_app.py, so it will be flask_app.

3. Run the API using the test client

Execute the API for flask_app.py using the get method of the test client in 2. The execution result is stored in the response property.

4. Test using assert statement

Use an assert statement to compare the response property with the expected result set in 1. In this test code, only three types of API return value (response.data), status (response.status), and status code (response.status_code) are compared. If you want to compare it with other execution results, you can check the response property` by using the following python function.


dir(response)

Therefore, it is advisable to select properties that need to be confirmed as appropriate and compare them with assert statements.

Summary

The test code introduced the mysterious use of Flask's test client.

next time

Tutorial for doing Test Driven Development (TDD) in Flask--2 Decorators

Recommended Posts

Tutorial for doing Test Driven Development (TDD) in Flask ―― 1 Test Client
Tutorial for doing Test Driven Development (TDD) in Flask-2 Decorators
[Test Driven Development (TDD)] Chapter 21 Summary
Learning history for participating in team app development in Python ~ Django Tutorial 5 ~
Learning history for participating in team app development in Python ~ Django Tutorial 4 ~
Learning history for participating in team app development in Python ~ Django Tutorial 1, 2, 3 ~
Learning history for participating in team app development in Python ~ Django Tutorial 6 ~
Learning history for participating in team app development in Python ~ Django Tutorial 7 ~
Test Driven Development with Django Part 3
Implement Table Driven Test in Java
Test Driven Development with Django Part 4
Test Driven Development with Django Part 6
Test Driven Development with Django Part 2
Test Driven Development with Django Part 1
Test Driven Development with Django Part 5
Experience Part I "Multinational Currencies" in the book "Test Driven Development" in Python
Test Driven Development Startup with PySide & Pytest
(For myself) Put Flask in VS Code
Tips for building large applications in Flask
Django tutorial summary for beginners by beginners ⑤ (test)