πŸ” Как ΠΏΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Flask-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅: ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ΅ руководство

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Flask, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ unittest для написания ΠΈ запуска ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹Ρ… тСстов. Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ:

import unittest
from your_app import app

class FlaskAppTest(unittest.TestCase):
    # УстановитС Ρ„Π»Π°Π³ тСстирования для вашСго прилоТСния Flask
    app.testing = True

    def setUp(self):
        self.app = app.test_client()

    def test_home_page(self):
        # ΠžΡ‚ΠΏΡ€Π°Π²ΡŒΡ‚Π΅ GET-запрос Π½Π° Π³Π»Π°Π²Π½ΡƒΡŽ страницу вашСго прилоТСния
        response = self.app.get('/')
        
        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ состояния Ρ€Π°Π²Π΅Π½ 200 (ΡƒΡΠΏΠ΅ΡˆΠ½Ρ‹ΠΉ запрос)
        self.assertEqual(response.status_code, 200)
        
        # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ содСрТимоС ΠΎΡ‚Π²Π΅Ρ‚Π° Π½Π° соотвСтствиС ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠΌΡƒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρƒ
        self.assertEqual(response.data, b'ΠŸΡ€ΠΈΠ²Π΅Ρ‚, ΠΌΠΈΡ€!')

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

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ создали класс тСстов FlaskAppTest, Π³Π΄Π΅ ΠΌΡ‹ установили Ρ„Π»Π°Π³ тСстирования для прилоТСния Flask. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΌΠ΅Ρ‚ΠΎΠ΄ setUp(), ΠΌΡ‹ создаСм ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° тСстирования для прилоТСния. Π—Π°Ρ‚Π΅ΠΌ Ρƒ нас Π΅ΡΡ‚ΡŒ тСстовый ΠΌΠ΅Ρ‚ΠΎΠ΄ test_home_page(), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ отправляСт GET-запрос Π½Π° Π³Π»Π°Π²Π½ΡƒΡŽ страницу прилоТСния ΠΈ провСряСт ΠΊΠΎΠ΄ состояния ΠΈ содСрТимоС ΠΎΡ‚Π²Π΅Ρ‚Π°.

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ тСстовыС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ вашСго прилоТСния Flask. ЗапуститС этот тСстовый Ρ„Π°ΠΉΠ», Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.

Π”Π΅Ρ‚Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΡ‚Π²Π΅Ρ‚

Как Ρ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Flask ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅

ВСстированиС являСтся Π²Π°ΠΆΠ½ΠΎΠΉ Ρ‡Π°ΡΡ‚ΡŒΡŽ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π° Flask. ΠšΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ΅ тСстированиС ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚ΡŒ ошибки ΠΈ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ прилоТСния. Π’ Π΄Π°Π½Π½ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ рассмотрим основныС ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Ρ‹ ΠΈ инструмСнты для тСстирования Flask прилоТСния.

1. Установка зависимостСй для тСстирования

ΠŸΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ ΠΊΠ°ΠΊ Π½Π°Ρ‡Π°Ρ‚ΡŒ тСстированиС Flask прилоТСния, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ нСсколько зависимостСй:

pip install pytest Flask-Testing

`pytest` являСтся популярным Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΎΠΌ для написания тСстов, Π° `Flask-Testing` прСдоставляСт Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ инструмСнты для тСстирования Flask ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ.

2. Запуск Flask прилоТСния Π² тСстовом ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠΈ

Для тСстирования Flask прилоТСния, Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ тСстовоС ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅. Π’ Flask Π΅ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ тСстовоС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ Π² сСбя всС настройки, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для тСстирования. НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ создания тСстового прилоТСния:

from flask import Flask

def create_app():
    app = Flask(__name__)
    app.config['TESTING'] = True
    return app

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ это тСстовоС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ для запуска тСстов.

3. НаписаниС тСстов

Для написания тСстов Flask прилоТСния, ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ pytest. НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Ρ‹ основныС шаги для написания тСстовых случаСв:

  1. Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠΉΡ‚Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ:
  2. import pytest
  3. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ фикстуру для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ прилоТСния:
  4. @pytest.fixture
    def app():
        app = create_app()
        return app
  5. ΠΠ°ΠΏΠΈΡˆΠΈΡ‚Π΅ тСстовый случай:
  6. def test_home_page(client):
        response = client.get('/')
        assert response.status_code == 200
        assert b"Welcome to the home page" in response.data
  7. ЗапуститС тСсты с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹:
  8. pytest

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ тСстовыС случаи для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Ρ… возмоТностСй вашСго прилоТСния.

4. ΠœΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈ тСстированиС API

ΠŸΡ€ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ API Π² Flask ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ, Π²Π°ΠΆΠ½ΠΎ ΠΈΠΌΠ΅Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Ρ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π±Π΅Π· нСпосрСдствСнной ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ… запросов. Для этого ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΌΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ запросы ΠΊ API. НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ `responses` для мокирования запросов:

import responses

@responses.activate
def test_api(client):
    responses.add(responses.GET, 'http://api.example.com/users', json={'users': [{ 'name': 'John' }]}, status=200)
    
    response = client.get('/users')
    assert response.status_code == 200
    assert response.json == {'users': [{ 'name': 'John' }]} 

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΌΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‚Π²Π΅Ρ‚Ρ‹ ΠΎΡ‚ API ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ нашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ эти ΠΎΡ‚Π²Π΅Ρ‚Ρ‹.

5. ΠŸΠΎΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΊΠΎΠ΄Π° тСстами

Одной ΠΈΠ· основных Ρ†Π΅Π»Π΅ΠΉ тСстирования Flask прилоТСния являСтся ΠΏΠΎΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΊΠΎΠ΄Π° тСстами. ΠŸΠΎΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΊΠΎΠ΄Π° позволяСт ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ всС Π²Π°ΠΆΠ½Ρ‹Π΅ части прилоТСния Ρ‚Π΅ΡΡ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ.

Для измСрСния покрытия ΠΊΠΎΠ΄Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ инструмСнт `coverage`. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ для запуска тСстов с ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠ΅ΠΌ покрытия ΠΊΠΎΠ΄Π°:

pytest --cov=your_app

ПослС выполнСния этой ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ ΠΎΡ‚Ρ‡Π΅Ρ‚ ΠΎ ΠΏΠΎΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ ΠΊΠΎΠ΄Π° тСстами, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠΊΠ°ΠΆΠ΅Ρ‚, ΠΊΠ°ΠΊΠΈΠ΅ части ΠΊΠΎΠ΄Π° ΠΏΠΎΠΊΡ€Ρ‹Ρ‚Ρ‹, Π° ΠΊΠ°ΠΊΠΈΠ΅ Π½Π΅Ρ‚.

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

ВСстированиС являСтся Π²Π°ΠΆΠ½ΠΎΠΉ Ρ‡Π°ΡΡ‚ΡŒΡŽ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π° Flask. Π’ Π΄Π°Π½Π½ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ рассмотрСли основныС ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Ρ‹ ΠΈ инструмСнты для тСстирования Flask прилоТСния. ΠœΡ‹ установили Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ зависимости, создали тСстовоС ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅, написали тСсты, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ pytest, ΠΈ ΠΏΠΎΠΊΡ€Ρ‹Π»ΠΈ ΠΊΠΎΠ΄ тСстами. НадСюсь, эта ΡΡ‚Π°Ρ‚ΡŒΡ ΠΏΠΎΠΌΠΎΠ³Π»Π° Π²Π°ΠΌ Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΠΎΠ½ΡΡ‚ΡŒ процСсс тСстирования Flask ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΈ ΠΏΠΎΠ²Ρ‹ΡΠΈΡ‚ΡŒ качСство вашСго ΠΊΠΎΠ΄Π°.

Π’ΠΈΠ΄Π΅ΠΎ ΠΏΠΎ Ρ‚Π΅ΠΌΠ΅

Getting Started With Testing in Flask

how to unit test flask routes and requests with pytest

Integration Testing For Flask Applications - Python API Testing

ΠŸΠΎΡ…ΠΎΠΆΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ:

πŸ” Как ΠΏΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Flask-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅: ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ΅ руководство