Flask
тестирование
Поиск…
Тестирование нашего приложения Hello World
Вступление
В этом минималистском примере, используя pytest
мы собираемся проверить, действительно ли наше приложение Hello World возвращает «Hello, World!». с кодом состояния HTTP OK 200, при нажатии с запросом GET на URL /
Сначала давайте установим pytest
в наш virtualenv
pip install pytest
И только для справки, это наше приветственное приложение мира:
# hello.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello, World!'
Определение теста
Вдоль стороны hello.py
, мы определяем тестовый модуль, называемый test_hello.py
который будет обнаружен py.test
# test_hello.py
from hello import app
def test_hello():
response = app.test_client().get('/')
assert response.status_code == 200
assert response.data == b'Hello, World!'
Просто для обзора, на данный момент наша структура проекта, полученная с помощью команды tree
:
.
├── hello.py
└── test_hello.py
Выполнение теста
Теперь мы можем запустить этот тест с py.test
команды py.test
, которая автоматически обнаружит наш test_hello.py
и тестовую функцию внутри него
$ py.test
Вы должны увидеть некоторый вывод и указание на то, что прошел 1 тест, например
=== test session starts ===
collected 1 items
test_hello.py .
=== 1 passed in 0.13 seconds ===
Тестирование API JSON, реализованного в Flask
В этом примере предполагается, что вы знаете, как тестировать приложение Flask с использованием pytest
Ниже представлен API, который принимает вход JSON с целыми значениями a
и b
например {"a": 1, "b": 2}
, добавляет их и возвращает сумму a + b
в ответе JSON, например {"sum": 3}
.
# hello_add.py
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/add', methods=['POST'])
def add():
data = request.get_json()
return jsonify({'sum': data['a'] + data['b']})
Тестирование этого API с помощью pytest
Мы можем протестировать его с помощью pytest
# test_hello_add.py
from hello_add import app
from flask import json
def test_add():
response = app.test_client().post(
'/add',
data=json.dumps({'a': 1, 'b': 2}),
content_type='application/json',
)
data = json.loads(response.get_data(as_text=True))
assert response.status_code == 200
assert data['sum'] == 3
Теперь запустите тест командой py.test
.
Доступ и изменение переменных сеанса в тестах с помощью Flask-Testing
Большинство веб-приложений используют объект сеанса для хранения важной информации. В этом примере показано, как вы можете протестировать такое приложение с помощью Flask-Testing. Полный рабочий пример также доступен на github .
Итак, сначала установите Flask-Testing в свой virtualenv
pip install flask_testing
Чтобы иметь возможность использовать объект сеанса, вы должны установить секретный ключ
app.secret_key = 'my-seCret_KEy'
Представим, что у вас есть функция приложения, которая должна хранить некоторые данные в переменных сеанса, подобных этому
@app.route('/getSessionVar', methods=['GET', 'POST'])
def getSessionVariable():
if 'GET' == request.method:
session['sessionVar'] = 'hello'
elif 'POST' == request.method:
session['sessionVar'] = 'hi'
else:
session['sessionVar'] = 'error'
return 'ok'
Чтобы проверить эту функцию, вы можете импортировать flask_testing и позволить вашему тестовому классу наследовать flask_testing.TestCase. Импортируйте также все необходимые библиотеки
import flask
import unittest
import flask_testing
from myapp.run import app
class TestMyApp(flask_testing.TestCase):
Очень важно, прежде чем начать тестирование, - это реализовать функцию create_app, иначе будет исключение.
def create_app(self):
return app
Для тестирования вашего приложения работает так, как вам хотелось бы, у вас есть несколько возможностей. Если вы хотите просто заверить, что ваша функция задает определенные значения для переменной сеанса, вы можете просто сохранить контекст и получить доступ к флажку.
def testSession1(self):
with app.test_client() as lTestClient:
lResp= lTestClient.get('/getSessionVar')
self.assertEqual(lResp.status_code, 200)
self.assertEqual(flask.session['sessionVar'], 'hello')
Еще один полезный трюк состоит в том, чтобы различать методы GET и POST, например, в следующей тестовой функции
def testSession2(self):
with app.test_client() as lTestClient:
lResp= lTestClient.post('/getSessionVar')
self.assertEqual(lResp.status_code, 200)
self.assertEqual(flask.session['sessionVar'], 'hi')
Теперь представьте, что ваша функция ожидает, что переменная сеанса будет установлена и реагирует на разные значения, такие как
@app.route('/changeSessionVar')
def changeSessionVariable():
if session['existingSessionVar'] != 'hello':
raise Exception('unexpected session value of existingSessionVar!')
session['existingSessionVar'] = 'hello world'
return 'ok'
Чтобы протестировать эту функцию, вы должны использовать так называемую транзакцию сеанса и открыть сеанс в контексте тестового клиента. Эта функция доступна, так как флакон 0,8
def testSession3(self):
with app.test_client() as lTestClient:
#keep the session
with lTestClient.session_transaction() as lSess:
lSess['existingSessionVar'] = 'hello'
#here the session is stored
lResp = lTestClient.get('/changeSessionVar')
self.assertEqual(lResp.status_code, 200)
self.assertEqual(flask.session['existingSessionVar'], 'hello world')
Запуск тестов, как обычно, для unittest
if __name__ == "__main__":
unittest.main()
И в командной строке
python tests/test_myapp.py
Еще один хороший способ запустить ваши тесты - использовать unittest Discovery следующим образом:
python -m unittest discover -s tests