Освоєння MagicMock: Уроки, отримані під час створення ETL пайплайну

pic

Привіт усім, нещодавно я завершив проект з ETL pipeline за участю Python, Azure Event Hub та Tableau, де я отримував дані прогнозу погоди, обробляв їх і візуалізував на панелі управління. Під час створення та тестування конвеєра однією з основних інструментів, що допомогли мені глибше зрозуміти unit testing, став MagicMock з модуля unittest.mock Python.

Я хотів би поділитися своїм досвідом роботи з MagicMock, як я використовував цей інструмент у своєму проекті і чому він є справжнім проривом для тестування Python-додатків.

Що таке MagicMock?

MagicMock є частиною бібліотеки unittest.mock Python. Це потужний інструмент, який дозволяє заміняти частини системи, що тестується, на мок-об’єкти і визначати їх поведінку під час тестування.

Простими словами:

• Він імітує поведінку реальних об’єктів (наприклад, відповіді API, виклики бази даних).

• Дає змогу перевіряти, як був викликаний метод, імітувати відповіді та запобігати реальним викликам API.

• Допомагає зробити тести швидшими, більш ізольованими і надійними.

Як я використовував MagicMock у своєму проекті ETL

Випадок 1: Мокаємо виклик API

У своєму проекті я отримував дані про погоду за допомогою API. Під час тестування я хотів переконатися в наступному:

  1. Функція працює правильно, коли API повертає успішну відповідь.

  2. Не було здійснено жодних реальних викликів API (щоб заощадити трафік і уникнути залежностей від зовнішніх сервісів).

Ось як я використовував MagicMock для цього:

import unittest  
from unittest.mock import patch, MagicMock  
from src.fetch_data_api import fetch_data_api, FORECAST_DAYS  
class TestWeatherForecastSuccess(unittest.TestCase):  
@patch('requests.get')  
def test_fetch_data_api(self, mock_get):  
# Мокаємо успішну відповідь API  
mock_response = MagicMock()  
mock_response.status_code = 200  
mock_response.json.return_value = {  
"days": [{"datetime": "2024–06–01", "temp": 22, "conditions": "Clear"}] * 14  
}  
mock_get.return_value = mock_response  
result = fetch_data_api("Vancouver", FORECAST_DAYS)  
# Перевірки  
self.assertEqual(len(result), 14)  
mock_get.assert_called_once_with(  
"https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/Vancouver?unitGroup=metric&key=Your_API_Key&contentType=json&include=days"  
)

Що я навчився:

  • Імітація поведінки API:
mock_get.return_value = mock_response
  • За допомогою цього я зміг імітувати відповідь API зі статусом 200 OK і JSON-пакетом.

Ізольоване тестування: Мені не потрібен був реальний API-ключ або активне підключення до Інтернету.

  • Перевірка:
mock_get.assert_called_once_with(…)

Це допомогло переконатися, що API було викликано з правильним URL.

Випадок 2: Мокаємо Azure Event Hub Producer

На іншому етапі я відправляв дані про погоду до Azure Event Hub. Для тестування функціональності передачі даних я замокав клієнта Event Hub, використовуючи MagicMock, щоб переконатися в наступному:

  1. Дані були правильно відформатовані.

2.
Виробник Event Hub був ініціалізований та викликаний належним чином.

Ось як я використовував MagicMock:

import unittest  
from unittest.mock import patch, MagicMock  
from src.push_data_eventhub import push_data_eventhub  
class TestPushForecastToEventHub(unittest.TestCase):  
@patch('src.push_data_eventhub.EventHubProducerClient')  
def test_push_data_eventhub_success(self, mock_producer_client):  
# Мокаємо виробника Event Hub  
mock_producer_instance = MagicMock()  
mock_producer_client.from_connection_string.return_value = mock_producer_instance  
mock_batch = MagicMock()  
mock_producer_instance.create_batch.return_value = mock_batch  
sample_forecast_data = {"Vancouver": [{"datetime": "2024–06–01", "temp": 22, "conditions": "Clear"}]}  
push_data_eventhub(sample_forecast_data)  
# Перевірки  
mock_producer_client.from_connection_string.assert_called_once()  
print("Тест на відправку до Event Hub пройшов успішно!")

Чому це важливо?

Мокання реальних клієнтів: Замість того, щоб підключатися до Event Hub, я замокав EventHubProducerClient і його методи.

Імітація пакетних операцій: Мокаючи createbatch та sendbatch, я зміг перевірити, як мій код взаємодіяв з API Event Hub.

Покращена надійність: Такий підхід забезпечив, що мої тести не зламаються через зовнішні залежності, такі як проблеми з мережею.

Чому MagicMock такий корисний?

Є кілька причин, чому він так корисний, ось вони:

Ізоляція: Він розділяє код, що тестується, від зовнішніх систем (наприклад, API, баз даних, хмарних сервісів).

Контроль: Можна симулювати різні сценарії (наприклад, успіх, помилки, таймаути), не маючи реальних умов.

Перевірка: Він допомагає перевірити, чи працює ваш код як очікується (наприклад, перевірка правильних API-ендпоінтів, викликів методів тощо).

Економія часу: Тести виконуються швидше, оскільки не здійснюються реальні зовнішні виклики.

Основні висновки

  1. Мокайте зовнішні залежності: Використовуйте MagicMock для симуляції відповідей від API, хмарних клієнтів чи інших зовнішніх систем.

  2. Зосередьтеся на поведінці: Тестування за допомогою MagicMock допомагає перевірити, як ваш код поводиться в різних умовах.

  3. Практика робить майстерність: Чим більше ви використовуєте моки, тим комфортніше вам буде розробляти надійні, ізольовані тести.

Перекладено з: Mastering MagicMock: Lessons Learned While Building an ETL Pipeline

Leave a Reply

Your email address will not be published. Required fields are marked *