#Основные возможности ## pytest.mark.parametrize Используется в Pytest для параметризации тестовых функций. Позволяет определить набор входных данных для тестовой функции и запустить эту функцию несколько раз для каждого набора данных. ``` import pytest @pytest.mark.parametrize("input_str, expected_output", [ ("hello", "HELLO"), ("world", "WORLD"), ("", "") ]) def test_uppercase(input_str, expected_output): assert input_str.upper() == expected_output ``` @pytest.mark.parametrize также поддерживает аргумент ids, который позволяет задать пользовательские идентификаторы для каждого набора параметров, переданных в тест. ``` import pytest def reverse_string(s): return s[::-1] @pytest.mark.parametrize("s,expected", [ ("hello", "olleh"), ("world", "dlrow"), ("", ""), ("a", "a"), ], ids=["test1", "test2", "test3", "test4"]) def test_reverse_string(s, expected): assert reverse_string(s) == expected ``` ## pytest.mark.skip Используется для пропуска выполнения тестовой функции. ``` import pytest @pytest.mark.skip(reason="Test not ready yet") def test_something(): assert True ``` ## pytest.fixture Используетсядля создания фикстур. Фикстуры - это объекты, которые предоставляют определенные данные или ресурсы, необходимые для выполнения тестовых функций. ``` import pytest @pytest.fixture def input_str(): return "hello" def test_uppercase(input_str): assert input_str.upper() == "HELLO" ``` Pytest автоматически вызывать фикстуру input_str и передавать ее значение в качестве аргумента в функцию test_uppercase. Мы можем использовать фикстуру в нескольких тестовых функциях, просто передавая ее как аргумент в эти функции. ## monkeypatch Это механизм в Pytest, который позволяет временно изменять значения и поведение функций и переменных во время выполнения тестов. Пример использования monkeypatch: ``` def test_something(monkeypatch): monkeypatch.setattr("os.getcwd", lambda: "/fake/path") assert os.getcwd() == "/fake/path" ``` Мы также можем использовать monkeypatch для временного изменения значений переменных. Например: ``` def test_another(monkeypatch): monkeypatch.setenv("APP_ENV", "testing") assert os.environ["APP_ENV"] == "testing" ``` ## testdir Инструмент в Pytest, который предоставляет простой способ создания временной директории и файлов для тестирования. Позволяет создавать, изменять и удалять файлы и директории во время выполнения тестов. ``` def test_something(testdir): # Создание временного файла test_file = testdir.makefile(".txt", "hello world") # Проверка, что файл существует и содержит правильный текст assert test_file.exists() assert test_file.read() == "hello world" # Создание временной директории и файла внутри нее test_dir = testdir.mkdir("testdir") test_subfile = test_dir.join("subfile.txt") test_subfile.write("test content") # Проверка, что файл внутри директории существует и содержит правильный текст assert test_subfile.exists() assert test_subfile.read() == "test content" ``` ## mocker.patch Это метод объекта mocker, который позволяет временно заменить атрибуты объекта на мокирующие объекты. Это может быть полезно при тестировании кода, который зависит от сторонних библиотек или модулей. ``` def test_something(mocker): mock_func = mocker.patch("my_module.my_function") mock_func.return_value = 42 assert my_module.my_function() == 42 mock_func.assert_called_once() ``` ### Пример 1: замена метода класса ``` def test_something(mocker): class MyClass: def my_method(self): return 42 mock_method = mocker.patch.object(MyClass, "my_method") mock_method.return_value = 24 instance = MyClass() assert instance.my_method() == 24 mock_method.assert_called_once_with() ``` ### Пример 2: замена функции модуля ``` def test_something(mocker): mock_func = mocker.patch("my_module.my_function") mock_func.side_effect = lambda x: x * 2 assert my_module.my_function(2) == 4 assert my_module.my_function("foo") == "foofoo" mock_func.assert_called_with() ``` ### Пример3 создание исключения ``` def test_something(mocker): mock_func = mocker.patch("my_module.my_function") mock_func.side_effect = Exception("Something went wrong") with pytest.raises(Exception, match="Something went wrong"): my_module.my_function(2) ``` ## mocker.patch.object Это метод объекта mocker в библиотеке pytest-mock, который позволяет мокировать методы объектов, в том числе классов. ``` class MyClass: def my_method(self, arg): return arg * 2 def test_something(mocker): obj = MyClass() mock_method = mocker.patch.object(obj, "my_method") mock_method.return_value = 42 assert obj.my_method(2) == 42 mock_method.assert_called_once_with(2) ``` ## mocker.patch.multiple Это метод объекта mocker в библиотеке pytest-mock, который позволяет мокировать несколько методов объекта одновременно. ``` class MyClass: def method1(self): return "foo" def method2(self, arg): return arg * 2 def test_something(mocker): obj = MyClass() mocks = mocker.patch.multiple(obj, method1=mocker.Mock(return_value="bar"), method2=mocker.Mock(return_value=42)) assert obj.method1() == "bar" assert obj.method2(2) == 42 mocks["method1"].assert_called_once_with() mocks["method2"].assert_called_once_with(2) ``` ## mocker.patch.dict Метод объекта mocker в библиотеке pytest-mock, который позволяет мокировать словари. ``` def test_something(mocker): my_dict = {"a": 1, "b": 2, "c": 3} mocker.patch.dict(my_dict, {"b": 42, "d": 4}) assert my_dict == {"a": 1, "b": 42, "c": 3, "d": 4} ``` ## mock_open Утилита в библиотеке unittest.mock, которая позволяет создавать моки для встроенной функции open() в Python. Это позволяет эмулировать открытие, чтение и запись файлов в тестах. ``` from unittest.mock import mock_open, patch def test_something(): with patch("builtins.open", mock_open(read_data="Hello, world!")) as mock_file: result = my_function("file.txt") mock_file.assert_called_once_with("file.txt", "r") assert result == "Hello, world!" def my_function(filename): with open(filename, "r") as f: return f.read() ``` ## PropertyMock Класс в библиотеке unittest.mock, который позволяет создавать моки для свойств классов и объектов. ``` from unittest.mock import PropertyMock, patch class MyClass: @property def my_property(self): return "hello" def test_something(): with patch.object(MyClass, "my_property", new_callable=PropertyMock) as mock_property: mock_property.return_value = "world" obj = MyClass() assert obj.my_property == "world" ``` ## ANY это константа в библиотеке unittest.mock, которая может использоваться вместо конкретного значения при создании моков. ``` from unittest.mock import Mock, ANY def test_something(): mock = Mock() mock.my_method(ANY) mock.my_method.assert_called_once_with("hello") ``` Создаем объект Mock и вызываем его метод my_method() с аргументом ANY. Константа ANY означает, что мы не уточняем конкретное значение аргумента, передаваемого в метод. В данном случае, мы можем передать любой аргумент в метод my_method(). Поскольку мы передали ANY в качестве аргумента при вызове my_method(), мы можем быть уверены, что любой переданный аргумент будет соответствовать утверждению.