#Основные возможности
## 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(), мы можем быть уверены, что любой переданный аргумент будет соответствовать утверждению.