Ребята Производитель приложений Application Application Application Application Application Application Application Application Application Application Applications и Click Of Things (IoT) с аналитикой и визуализацией данных. Я инженер в ребятах, и наша ежедневная цель беспрепятственно и чисто включает данные датчика в информацию, которая имеет значение. Найм инженерной команды для разработки платформы, которую оба Функции И выглядит великолепно дорого за время, так и деньги, поэтому мы сделали это для вас. Одной из функций, которую многие клиенты наслаждаются, является историческая отчетность, которая генерируется и сохраняется с Amazon S3.
При разработке этой функции нам необходимо для создания модульного теста с использованием Python для проверки надежности функций. Используя издевался класс BOTO3 модуль. Как мы находились в тестовой среде, мы не могли допустить загрузку файлов на наше ведро S3 и не имели правильных учетных данных, поэтому нам нужно было найти способ издеваться в класс, но, включая (или фактически вынимать) следующие функции:
- Не общайтесь с Amazon, так как мне не нужно ничего загружать.
- Не поднимайте исключение, не имея правильных полномочий.
По понятным причинам я не могу скопировать и вставить исходный код Ubidots, но с целью этой статьи я включил пример, аналогичный тому, что мы используем ежедневно.
Давайте начнем с самой важной части поста: код!
Создать модель
Это будет наш «модель сообщений», и у него есть метод, который позволит нам создать отчет и отправить его по электронной почте.
import StringIO from django.db import models from boto3.session import Session class Report(models.Model): # ... # Information about the model def create_report_and_send_by_email(self): stream = StringIO.StringIO() self.create_report(stream) # Go back to the first bit of the stream stream.seek(0) session = Session(aws_access_key_id=AWS_ACCESS_KEY, aws_secret_access_key=AWS_SECRET_ACCESS_KEY) s3 = session.resource('s3') s3.Bucket(AWS_BUCKET_DATA).put_object( Key='file.pdf', Body=stream.read(), ACL='public-read', Expires=(datetime.datetime.now() + datetime.timedelta(days=1)).strftime('%Y/%m/%d'), ContentType='application/pdf' ) # Do some other stuff and send the file by email # More methods # ...
Здесь я реализовал только один метод нашей модели, поскольку это в центре внимания этой статьи, но обычно эта модель будет иметь дополнительные поля и другие методы, которые были оставлены исключительно для простоты причин.
Создать тест
Это будет файл, который реализует тесты на нашу модель, вы можете прочитать немного больше о записи и запущенных модульных тестах в Django Документация сайта Отказ
from django.core import mail from django.test import TestCase from reports.models.report import Report class ReportTest(TestCase): def tearDown(self): Report.objects.all().delete() mail.outbox = [] def test_create_report_and_send_by_email(self): info = # This is a dict with the information of the fake Report report = Report.objects.create(**info) # There shouldn't be emails in the outbox self.assertEqual(len(mail.outbox), 0) report.create_report_and_send_by_email(self) # There should be one email in the outbox self.assertEqual(len(mail.outbox), 1)
Если бы нам было запустить этот код без правильных учетных данных AWS, он поднимет исключение, что говорит, что учетные данные не являются правильными, и поэтому наш тест потерпит неудачу.
Вот когда нам нужно сделать макет Сессия класс от BOTO3 ; Предотвращение заседания изготовления соединения с Amazon S3. В этом случае мы ожидаем, что нечего возвращаться, единственное, что мы собираемся сделать с макетом, предотвращают связь с Amazon S3.
Создать макет
Первое, что нам нужно сделать, это импортировать Макет
и BOTO3
Библиотеки в нашем тестовом файле.
import mock from boto3.session import Session
Теперь нам нужно создать нашу модель для занятий сеансом и ресурсами, и мы реализуем методы, которые мы используем с теми же аргументами для проведения нашего теста. Ниже вы найдете нашу «FakeSession» и «Fakeresource», которые будут использоваться в качестве наших макетов классов.
class FakeResource(): def Bucket(self, bucket): return self def put_object(self, Key=None, Body=None, ACL='', Expires='', ContentType=''): # We do nothing here, but return the same data type without data return {} class FakeSession(Session): def resource(self, name): return FakeResource()
Теперь, когда эти два издевательства созданы классы, мы можем добавить их в тестовый случай, используя патч. Используя патч, тест будет работать с использованием этих поддельных классов вместо реальных из BOTO3 Отказ
@mock.patch('reports.models.report.Session', FakeSession) def test_create_report_and_send_by_email(self): # Same implementation we used before # ...
Как видите, патч выполнен в пространство имен модуля, который мы тестируем, не к пространству имен исходного модуля, который мы хотим изменить.
Добавление издевательства на тест
Наш тестовый код (включая предыдущие шаги) выглядит так:
import mock from django.core import mail from django.test import TestCase from boto3.session import Session from reports.models.report import Report class FakeResource(): def Bucket(self, bucket): return self def put_object(self, Key=None, Body=None, ACL='', Expires='', ContentType=''): # We do nothing here, but return the same data type without data return {} class FakeSession(Session): def resource(self, name): return FakeResource() @mock.patch('reports.models.report.Session', FakeSession) class ReportTest(TestCase): def tearDown(self): Report.objects.all().delete() mail.outbox = [] def test_create_report_and_send_by_email(self): info = {"name": "Fake report"} # This is a dict with the information of the fake Report report = Report.objects.create(**info) # There shouldn't be emails in the outbox self.assertEqual(len(mail.outbox), 0) report.create_report_and_send_by_email(self) # There should be one email in the outbox self.assertEqual(len(mail.outbox), 1)
Когда этот новый тестовый корпус выполнен, он будет использовать реализации, которые мы создали в FakeSessions, каждый раз, когда заседается сеанс из BOTO3.
Использование декоратора для исправлений мы смогли сделать макет из третьих сторон ( BOTO3 ) Работают тем, как нам нужно проверить некоторые модули; Даже при отсутствии некоторых параметров, которые в противном случае были бы доступны в производственной среде, используя урок MOCK, мы могли бы проверить наш модуль без необходимости создания данных контента для запуска программы.
Мысли авторов: этот макет должен быть сделан только тогда, когда это необходимо. Важно подумать о том, как эта модификация влияет на испытание модуля; В случае этого произведения мы только модифицированные модули для предотвращения подключения к Amazon и не подняли исключение. Для наших потребностей функция S3 не была важна для правильного поведения теста.
Если вы нашли эту статью полезную, пожалуйста, оставьте свою реакцию и поделитесь ее в ваших сетях! И вы также очень можете оставить отзыв в разделе комментариев ❤ ️.
Оригинал: “https://dev.to/d4vsanchez/mocking-and-patching-in-python-for-unit-testing-3j08”