Поиск…


Тестирование нашего приложения 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


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow