Mock-объекты mock (англ.) – ложный, фиктивный, мнимый, фальшивый, поддельный.

Презентация:



Advertisements
Похожие презентации
Занятие Регулярные выражения Памятка (основные элементы регулярных выражений): a+ – любая последовательность a a* – любая последовательность a или.
Advertisements

Нескучное тестирование с pytest Роман Иманкулов / 14 июня 2014.
Функции Лекция 8. Назначение функций Функции - самостоятельные программные единицы, спроектированные для решения конкретной задачи. Функции по структуре.
Д.з Язык С++ - занятие 31. Задача 1: 1/1 + 1/3 + 1/5 … #include using namespace std; int main() { int n; cin >> n; double sum = 0;// Сумма for.
Высокоуровневые методы информатики и программирования Лекция 9 Делегаты.
Наследование Наследование – это отношение является между классами. class Person { string first_name; int birth_year;... } class Student : Person { float.
Доброгодин Евгений Санкт-Петербургский Государственный Университет Математико – Механический Факультет 222 группа. ВВОД/ВЫВОД
Преобразования типов В языке C/C++ имеется несколько операций преобразования типов. Они используются в случае, если переменная одного типа должна рассматриваться.
EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты для расчетов используется доллар,
ООП Классы Данные отдельно, методы отдельно struct Node { Node* next; void* data; }; struct List { Node* first; int size; }; void* allocate() { … } void.
Объектно – ориентированное программирование (ООП) Артишевская Юлия, 222 группа Артишевская Юлия, 222 группа.
Software engineering Дмитриев Андрей Владиславович ©
Язык Python Универсальный язык программирования Интерпретируемый язык.
Часть 1. Основы ООП Исключения.. Структурный подход Неисправимые ошибки – вывести информацию и умереть. Исправимые ошибки – уведомить вызывающую.
Работа с файлами Сазонов Д.О. ПМиЭММ Часть 2. Тема занятия: Работа с файлами через потоки Для реализации файлового ввода/вывода, необходимо включить в.
Занятие 4 def simple_iterator yield 2 # передача управления в блок итератора yield 7 yield 1 end simple_iterator {|i| puts i } 15. Итераторы изнутри.
b5_java_s4
ТЕМА: «ПРОВЕРКА УСЛОВИЯ» 8 – 9 класс Логунова Наталия Борисовна учитель информатики и ИКТ высшей категории МОСКВА, 2012.
SoapUI Содержание лекции Зачем нужен SoapUI? Основные возможности Тестовый проект – Students Использование SoapUI для анализа WSDL Создание заглушек.
Лекция 9 Функции. Массивы-параметры функции Передача массива в функцию Пример: void array_enter(int a[], int size) { int i; for (i = 0; i < size; i++)
Транксрипт:

Mock-объекты mock (англ.) – ложный, фиктивный, мнимый, фальшивый, поддельный

Первый пример Мы хотим протестировать функцию f: def f(x): return g(x) * g(x)

НО: 1)Функция g еще не написана

ИЛИ: 2) Функция g работает недетерминировано: def g(x): return randint(5 * x)

ИЛИ: 3) Функция g слишком сложна, в ней тоже могут быть ошибки. Хотим протестировать f независимо

ИЛИ: 4) Функция g имеет нежелательные при тестировании побочные эффекты: def g(x): file = open(1.txt, w) file.write(blablabla)

Простейшее решение Пишем заглушку (stub): def g(x): return 5 ИДЕЯ: заменить настоящую функцию g на более удобную при тестировании

Более сложный пример def f(x): if x > 0 and x < 10: return g(x) elif x

Что хочется протестировать? Требуется убедиться, что функция f вызывает функцию g только в нужных случаях и нужное количество раз. ИДЕЯ: Наша фальшивая g не только возвращает фиксированное значение, но и запоминает информацию о своих вызовах.

Что для этого нужно? 1)Использовать g как объект (хранить состояние) 2)Чтобы объект можно было вызвать – () – он должен быть callable

Как это должно выглядеть? g = … f(5) g.assert_called_once_with(5) f(-5) g.assert_any_call(5) g.assert_any_call(-5)

Стандартный модуль unittest.mock (начиная с python3.3) from unittest.mock import Mock g = Mock(return_value = 5) …

Мокаем метод объекта def is_empty(group): return len(group.members()) == 0 group1 = Group() group1.members = Mock(return_value= [aaa, bbb, ccc]) is_empty(group1) group1.members.assert_called_with()

Мокаем объект group1 = Mock() group1.members.return_value = [aaa, bbb, ccc] Все необходимые методы/поля создаются на лету: group1.count()

НО: mock.__str__.return_value = foo вызовет исключение magic-методы (__xxx__) Mock не создает (они часто используются неявно, например, __str__, __eq__ и их автоматическое переопределение не всегда желательно)

MagicMock Аналог Mock, дополнительно позволяющий создавать magic-методы from unittest.mock import MagicMock m = MagicMock() m.__str__.return_value = 'foo' print(m) Выведет foo

Объекты из стандартных библиотек …тоже можно мокать: from unittest.mock import Mock import random random.randint = Mock(return_value = 100) print(random.randint(10))

Мокать можно всё from unittest.mock import Mock print = Mock() print('***')

Mock-объект хранит историю вызовов >>> mock = Mock(return_value=None) >>> mock() >>> mock(3, 4) >>> mock(key='fish', next='w00t!') >>> mock.call_args_list [call(), call(3, 4), call(key='fish', next='w00t!')]

…которую можно сравнивать с ожидаемыми значениями [call(), call(3, 4), call(key='fish', next='w00t!')] >>> expected = [(), ((3, 4),), ({'key':'fish', 'next':'w00t!'},)] >>> mock.call_args_list == expected True

Если return_value не определено … то возвращается Mock-объект: >>> open = Mock() >>> f = open("1.txt") >>> print(f) Для его методов также создаются новые Мock- объекты: >>> s = f.read() >>> print(s)

НО! from unittest.mock import Mock open = Mock() with open("1.txt") as f: s = f.read() вызовет исключение: AttributeError: __exit__

Замена на MagicMock лечит но проблемы остаются… Решение из коробки: from unittest.mock import mock_open open = mock_open(read_data='To be or...') with open("1.txt") as f: print(f.read()) print(open.mock_calls)

Выведет To be or... [call('1.txt'), call().__enter__(), call().read(), call().__exit__(None, None, None)]

Преимущества mock_open 1)Корректно работает и вместо отдельного open, и в конструкции с with 2)Необязательный параметр read_data (только для read!!!) 3)поддерживает только стандартный методы для файлов и выдает исключения для остальных: >>> f.aaa() AttributeError: Mock object has no attribute 'aaa'

patch func.py: def f(x): return g(x) * g(x) def g(x):...

func_test.py import unittest from func import f class FTest(unittest.TestCase): def test_f(self): result = f(5) self.assertEqual(result, 9) if __name__ == '__main__': unittest.main()

patch from unittest.mock import return_value = 3) def test_f(self, mock_g): result = f(5) self.assertEqual(result, 9)

Преимущества Mock-объектов 1)Независимое тестирование одного метода или класса 2)Скорость тестирования (не выполняется лишний код) 3)Стимулирует к правильному проектированию 4)Избавление от недетерминированного поведения 5)Генерация сложно воспроизводимых в реальных условиях ошибок 6)Запись и анализ логов вызовов функций