Рубрики
Без рубрики

Издевание и исправляющие в Python для тестирования подразделения

Ubidoss – это легкий дочерний и щелчок в Интернете вещей (IOT) построителя приложений с данными … Помечено Python, тестирование, учебник, Джанго.

Ребята Производитель приложений Application Application Application Application Application Application Application Application Application Application Applications и Click Of Things (IoT) с аналитикой и визуализацией данных. Я инженер в ребятах, и наша ежедневная цель беспрепятственно и чисто включает данные датчика в информацию, которая имеет значение. Найм инженерной команды для разработки платформы, которую оба Функции И выглядит великолепно дорого за время, так и деньги, поэтому мы сделали это для вас. Одной из функций, которую многие клиенты наслаждаются, является историческая отчетность, которая генерируется и сохраняется с Amazon S3.

При разработке этой функции нам необходимо для создания модульного теста с использованием Python для проверки надежности функций. Используя издевался класс BOTO3 модуль. Как мы находились в тестовой среде, мы не могли допустить загрузку файлов на наше ведро S3 и не имели правильных учетных данных, поэтому нам нужно было найти способ издеваться в класс, но, включая (или фактически вынимать) следующие функции:

  1. Не общайтесь с Amazon, так как мне не нужно ничего загружать.
  2. Не поднимайте исключение, не имея правильных полномочий.

По понятным причинам я не могу скопировать и вставить исходный код 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”