Найти Π² Π”Π·Π΅Π½Π΅
Анастасия Π‘ΠΎΡ„Ρ‚

πŸ”— Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ΅ тСстированиС: ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° связСй ΠΌΠ΅ΠΆΠ΄Ρƒ модулями

🧠 Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ΅ тСстированиС? Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ΅ тСстированиС β€” это процСсс ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ взаимодСйствия ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ модулями ΠΈΠ»ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌΠΈ систСмы. Если ΡŽΠ½ΠΈΡ‚-тСсты ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Ρ‚ΠΎ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ тСсты ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‚, ΠΊΠ°ΠΊ эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ вмСстС. ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρƒ нас Π΅ΡΡ‚ΡŒ Π΄Π²Π° модуля: database.py ΠΈ user_service.py. ΠœΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ user_service ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ взаимодСйствуСт с Π±Π°Π·ΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ…. # database.py
def get_user_by_id(user_id):
# Π—Π΄Π΅ΡΡŒ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ запрос ΠΊ Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ…
return {"id": user_id, "name": "John Doe"}
# user_service.py
from database import get_user_by_id
def get_user_info(user_id):
user = get_user_by_id(user_id)
return f"User: {user['name']}, ID: {user['id']}" Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст: # test_integration.py
from user_service import get_user_info
def test_get_user_info():
result = get_user_info(1)
assert result == "User: John Doe, ID: 1" Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ провСряСм, Ρ‡Ρ‚ΠΎ user_service ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· database ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ
ОглавлСниС

🧠 Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ΅ тСстированиС?

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ΅ тСстированиС β€” это процСсс ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ взаимодСйствия ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ модулями ΠΈΠ»ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌΠΈ систСмы. Если ΡŽΠ½ΠΈΡ‚-тСсты ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Ρ‚ΠΎ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ тСсты ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‚, ΠΊΠ°ΠΊ эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ вмСстС.

πŸ” Π—Π°Ρ‡Π΅ΠΌ ΠΎΠ½ΠΎ Π½ΡƒΠΆΠ½ΠΎ?

  • ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° взаимодСйствия: ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ ΠΎΠ±ΠΌΠ΅Π½ΠΈΠ²Π°ΡŽΡ‚ΡΡ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ.
  • ΠžΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ ошибок: Π²Ρ‹ΡΠ²ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ Π²ΠΈΠ΄Π½Ρ‹ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ.
  • ΠŸΠΎΠ²Ρ‹ΡˆΠ΅Π½ΠΈΠ΅ увСрСнности: ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ систСма Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΊΠ°ΠΊ Π΅Π΄ΠΈΠ½ΠΎΠ΅ Ρ†Π΅Π»ΠΎΠ΅.

πŸ› οΈ Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ для ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ тСстирования

  • Python: pytest, unittest, requests
  • JavaScript: Mocha, Chai, Jest
  • Java: JUnit, TestNG

πŸ§ͺ ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 1: ВзаимодСйствиС ΠΌΠ΅ΠΆΠ΄Ρƒ слоями прилоТСния (Π½ΠΎΠ²ΠΈΡ‡ΠΎΠΊ)

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρƒ нас Π΅ΡΡ‚ΡŒ Π΄Π²Π° модуля: database.py ΠΈ user_service.py. ΠœΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ user_service ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ взаимодСйствуСт с Π±Π°Π·ΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ….

# database.py
def get_user_by_id(user_id):
# Π—Π΄Π΅ΡΡŒ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ запрос ΠΊ Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ…
return {"id": user_id, "name": "John Doe"}

# user_service.py
from database import get_user_by_id

def get_user_info(user_id):
user = get_user_by_id(user_id)
return f"User: {user['name']}, ID: {user['id']}"

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст:

# test_integration.py
from user_service import get_user_info

def test_get_user_info():
result = get_user_info(1)
assert result == "User: John Doe, ID: 1"

Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ провСряСм, Ρ‡Ρ‚ΠΎ user_service ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· database ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚.

πŸ§ͺ ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 2: ВзаимодСйствиС с внСшним API (ΠΌΠΈΠ΄Π»)

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, наш сСрвис отправляСт запросы ΠΊ Π²Π½Π΅ΡˆΠ½Π΅ΠΌΡƒ API для получСния ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ ΠΏΠΎΠ³ΠΎΠ΄Π΅.

# weather_service.py
import requests

def get_weather(city):
response = requests.get(f"http://api.weather.com/{city}")
return response.json()

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст с использованиСм ΠΌΠΎΠΊΠ°:

# test_weather_service.py
from unittest.mock import patch
from weather_service import get_weather

@patch('weather_service.requests.get')
def test_get_weather(mock_get):
mock_get.return_value.json.return_value = {"temperature": 22}
result = get_weather("Cancun")
assert result["temperature"] == 22

Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ ΠΌΠΎΠΊΠ°Π΅ΠΌ внСшний запрос, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ Π·Π°Π²ΠΈΡΠ΅Ρ‚ΡŒ ΠΎΡ‚ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ API, Π½ΠΎ провСряСм, Ρ‡Ρ‚ΠΎ наш сСрвис ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ ΠΎΡ‚Π²Π΅Ρ‚.

πŸ§ͺ ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 3: ВзаимодСйствиС ΠΌΠ΅ΠΆΠ΄Ρƒ микросСрвисами (ΡΠ΅Π½ΡŒΠΎΡ€)

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρƒ нас Π΅ΡΡ‚ΡŒ Π΄Π²Π° микросСрвиса: order_service ΠΈ payment_service. ΠœΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ создании Π·Π°ΠΊΠ°Π·Π°, автоматичСски инициируСтся процСсс ΠΎΠΏΠ»Π°Ρ‚Ρ‹.

# order_service.py
import requests

def create_order(order_data):
response = requests.post("http://payment_service/pay", json=order_data)
return response.status_code

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст:

# test_order_service.py
import requests
from unittest.mock import patch
from order_service import create_order

@patch('order_service.requests.post')
def test_create_order(mock_post):
mock_post.return_value.status_code = 200
order_data = {"product_id": 1, "quantity": 2}
result = create_order(order_data)
assert result == 200

Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ провСряСм, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ создании Π·Π°ΠΊΠ°Π·Π°, сСрвис отправляСт запрос ΠΊ payment_service ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΡƒΡΠΏΠ΅ΡˆΠ½Ρ‹ΠΉ ΠΎΡ‚Π²Π΅Ρ‚.

πŸ§ͺ ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 4: ВзаимодСйствиС с Π±Π°Π·ΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ… (ΠΌΠΈΠ΄Π»)

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρƒ нас Π΅ΡΡ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ сохраняСт ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ….

# user_repository.py
import sqlite3

def save_user(user):
conn = sqlite3.connect('test.db')
cursor = conn.cursor()
cursor.execute("INSERT INTO users (name) VALUES (?)", (user['name'],))
conn.commit()
conn.close()

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст:

# test_user_repository.py
import sqlite3
from user_repository import save_user

def test_save_user():
user = {"name": "Alice"}
save_user(user)
conn = sqlite3.connect('test.db')
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE name=?", (user['name'],))
result = cursor.fetchone()
conn.close()
assert result is not None

Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ провСряСм, Ρ‡Ρ‚ΠΎ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ….

πŸ§ͺ ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 5: ВзаимодСйствиС ΠΌΠ΅ΠΆΠ΄Ρƒ слоями прилоТСния с использованиСм ΠΌΠΎΠΊΠ° (профСссионал)

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρƒ нас Π΅ΡΡ‚ΡŒ сСрвис, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ отправляСт увСдомлСния ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ.

# notification_service.py
from email_service import send_email

def notify_user(user, message):
send_email(user['email'], message)

Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст с использованиСм ΠΌΠΎΠΊΠ°:

# test_notification_service.py
from unittest.mock import patch
from notification_service import notify_user

@patch('notification_service.send_email')
def test_notify_user(mock_send_email):
user = {"email": "test@example.com"}
message = "Hello!"
notify_user(user, message)
mock_send_email.assert_called_with(user['email'], message)

Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ провСряСм, Ρ‡Ρ‚ΠΎ сСрвис ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ email.

🧩 Π—Π°Π΄Π°Ρ‡ΠΈ для ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ

  1. Новичок: ΠΠ°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, которая сохраняСт Π΄Π°Π½Π½Ρ‹Π΅ Π² Ρ„Π°ΠΉΠ».
  2. Мидл: ΠΠ°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, которая взаимодСйствуСт с внСшним API.
  3. Π‘Π΅Π½ΡŒΠΎΡ€: ΠΠ°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст для микросСрвиса, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ взаимодСйствуСт с нСсколькими Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ сСрвисами.
  4. ΠŸΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»: ΠΠ°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, которая ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ отправляСт увСдомлСния ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ.
  5. ЭкспСрт: ΠΠ°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст для слоТной бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ, которая Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ взаимодСйствиС с нСсколькими модулями ΠΈ внСшними сСрвисами

ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ! НиТС β€” 🧩 ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ для ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ с ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Ρ‹ΠΌΠΈ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡΠΌΠΈ, ΠΊΠΎΠ΄ΠΎΠΌ ΠΈ коммСнтариями ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ строчкС. Всё ΠΎΡ‚ уровня Π½ΠΎΠ²ΠΈΡ‡ΠΊΠ° Π΄ΠΎ экспСрта. Погнали!

🧩 Новичок: Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст β€” сохранСниС Π΄Π°Π½Π½Ρ‹Ρ… Π² Ρ„Π°ΠΉΠ»

πŸ”§ Ѐункция:

# file_writer.py
def save_to_file(filename, data):
with open(filename, "w") as f:
f.write(data)

πŸ”¬ Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст:

# test_file_writer.py
import os
from file_writer import save_to_file

def test_save_to_file():
test_filename = "test_output.txt"
test_data = "Hello, integration!"

save_to_file(test_filename, test_data)

with open(test_filename, "r") as f:
content = f.read()

assert content == test_data

os.remove(test_filename) # Π£Π±ΠΈΡ€Π°Π΅ΠΌ Π·Π° собой

🧠 ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ:

  • ПишСм Ρ„Π°ΠΉΠ», Ρ‡ΠΈΡ‚Π°Π΅ΠΌ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ β€” провСряСм, Ρ‡Ρ‚ΠΎ запись сработала.
  • НС Π·Π°Π±Ρ‹Π²Π°Π΅ΠΌ Ρ‡ΠΈΡΡ‚ΠΈΡ‚ΡŒ послС сСбя.

🧩 Мидл: Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст β€” Π²Ρ‹Π·ΠΎΠ² внСшнСго API

πŸ”§ Ѐункция:

# cat_facts.py
import requests

def get_cat_fact():
r = requests.get("https://catfact.ninja/fact")
return r.json()["fact"]

πŸ”¬ Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст (c requests-mock):

# test_cat_facts.py
import requests
import requests_mock
from cat_facts import get_cat_fact

def test_get_cat_fact():
with requests_mock.Mocker() as m:
m.get("https://catfact.ninja/fact", json={"fact": "Cats are awesome."})
fact = get_cat_fact()
assert fact == "Cats are awesome."

🧠 ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ:

  • requests_mock Π΄Π°Ρ‘Ρ‚ ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½ΠΎΡΡ‚ΡŒ β€” внСшний API ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΠΏΠ°ΡΡ‚ΡŒ, Π° тСсты Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ прСдсказуСмыми.

🧩 Π‘Π΅Π½ΡŒΠΎΡ€: Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст β€” микросСрвис Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ сСрвисы

πŸ”§ БСрвис:

# order_service.py
import requests

def create_order(order_data):
response = requests.post("http://payment-service/pay", json=order_data)
if response.status_code != 200:
raise Exception("Payment failed")
return {"status": "created", "payment": response.json()}

πŸ”¬ Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст:

# test_order_service.py
from unittest.mock import patch
from order_service import create_order

@patch("order_service.requests.post")
def test_create_order_success(mock_post):
mock_post.return_value.status_code = 200
mock_post.return_value.json.return_value = {"payment_id": "abc123"}

data = {"item": "coffee", "price": 100}
result = create_order(data)

assert result["status"] == "created"
assert result["payment"]["payment_id"] == "abc123"

🧠 ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ:

  • МокаСм Π²Ρ‹Π·ΠΎΠ² payment-service, Π½ΠΎ тСстируСм вСсь процСсс создания Π·Π°ΠΊΠ°Π·Π° ΠΊΠ°ΠΊ Π΅Π΄ΠΈΠ½ΠΎΠ΅ Ρ†Π΅Π»ΠΎΠ΅.

🧩 ΠŸΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»: Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст β€” Π‘Π” + ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅

πŸ”§ ΠœΠΎΠ΄ΡƒΠ»ΠΈ:

# user_repo.py
import sqlite3

def get_user_email(user_id):
conn = sqlite3.connect("test.db")
cur = conn.cursor()
cur.execute("SELECT email FROM users WHERE id = ?", (user_id,))
result = cur.fetchone()
conn.close()
return result[0] if result else None

# notifier.py
from user_repo import get_user_email

def send_notification(user_id, sender):
email = get_user_email(user_id)
if email:
sender.send(email, "Welcome!")
return True
return False

πŸ”¬ Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст:

# test_notifier.py
import sqlite3
from notifier import send_notification
from unittest.mock import Mock

def setup_test_db():
conn = sqlite3.connect("test.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS users (id INTEGER, email TEXT)")
cur.execute("DELETE FROM users")
cur.execute("INSERT INTO users VALUES (1, 'test@example.com')")
conn.commit()
conn.close()

def test_send_notification():
setup_test_db()
fake_sender = Mock()

result = send_notification(1, fake_sender)

fake_sender.send.assert_called_with("test@example.com", "Welcome!")
assert result is True

🧠 ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ:

  • Π­Ρ‚ΠΎ ΡƒΠΆΠ΅ ΠΏΠΎΠ»Π½ΠΎΡ†Π΅Π½Π½Ρ‹ΠΉ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½: Π‘Π” + Π»ΠΎΠ³ΠΈΠΊΠ° + ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ°.
  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΌΠΎΠΊ для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ писСм, Π½ΠΎ Ρ€Π΅Π°Π»ΡŒΠ½ΡƒΡŽ Π‘Π” (sqlite, Ρ‡Ρ‚ΠΎΠ±Ρ‹ просто).

🧩 ЭкспСрт: Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст слоТной бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ

πŸ“˜ Π‘Ρ†Π΅Π½Π°Ρ€ΠΈΠΉ:

  • ΠšΠ»ΠΈΠ΅Π½Ρ‚ оформляСт подписку
  • ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅Ρ‚ΡΡ ΠΏΠ»Π°Ρ‚Ρ‘ΠΆ
  • БохраняСтся Π² Π‘Π”
  • ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅Ρ‚ΡΡ email

πŸ”§ Код:

# subscription.py
from payment_service import charge_card
from user_repo import save_subscription
from mailer import send_email

def process_subscription(user, card_info):
if not charge_card(card_info):
raise Exception("Payment failed")

save_subscription(user["id"])
send_email(user["email"], "Subscription activated!")
return True

πŸ”¬ Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ тСст:

# test_subscription.py
from subscription import process_subscription
from unittest.mock import patch

@patch("subscription.send_email")
@patch("subscription.save_subscription")
@patch("subscription.charge_card")
def test_process_subscription(mock_charge, mock_save, mock_send):
mock_charge.return_value = True

user = {"id": 1, "email": "user@example.com"}
card = {"number": "4111 1111 1111 1111"}

result = process_subscription(user, card)

mock_charge.assert_called_once_with(card)
mock_save.assert_called_once_with(user["id"])
mock_send.assert_called_once_with(user["email"], "Subscription activated!")
assert result is True

🧠 ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ:

  • Π‘Π»ΠΎΠΆΠ½Ρ‹ΠΉ тСст провСряСт вСсь ΠΏΠΎΡ‚ΠΎΠΊ бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ
  • ВсС сторонниС ΠΌΠΎΠ΄ΡƒΠ»ΠΈ (ΠΏΠ»Π°Ρ‚Ρ‘ΠΆ, Π‘Π”, письма) β€” ΠΌΠΎΠΊΠ½ΡƒΡ‚Ρ‹
  • ВСст Π΄Π°Ρ‘Ρ‚ ΡƒΠ²Π΅Ρ€Π΅Π½Π½ΠΎΡΡ‚ΡŒ: Ссли ΠΎΠ΄ΠΈΠ½ кусок отвалится β€” ΡƒΠ²ΠΈΠ΄ΠΈΠΌ сразу