[PYTHON] Verwenden Sie Mock mit Pytest

Einführung

Als ich den Testcode mit pytest schrieb, hatte ich Schwierigkeiten mit Mock, also habe ich ihn zusammengefasst.

Was ist Mock?

Mock ist ein Modul, das Unit-Tests für bestimmte Objekte erleichtert.

Vorbereitung

  1. Installieren Sie pytest

    pip install pytest pytest-mock
    
  2. Erstellen Sie den zu testenden Code

Verzeichnisaufbau

```bash
root
├─src
│   └─script.py ・ ・ ・ Zu testender Quellcode
└─tests
    ├─__init__.py ・ ・ ・ leere Datei
    └─script.py ・ ・ ・ Testcode
```

Zu testender Quellcode

```python:src/script.py
import requests


def sample1(url):
    return sample2(url)


def sample2(url):
    try:
        response = requests.get(url)
        return response.status_code
    except Exception:
        return 0


class SampleClass:
    def __init__(self):
        self._req = requests

    def get(self, url):
        try:
            response = self._req.get(url)
            return response.status_code
        except Exception:
            return 0
```

Durchführen von Tests mit Mock

Verspotten Sie die Funktion

Ersetzen Sie die Funktion sample2, wenn Sie die Funktion sample1 testen.

Geben Sie den Rückgabewert der Funktion an

Testcode

tests/test_script.py


from src.script import sample1


def test_sample1_mock_sample2_200(mocker):
    """
Lassen Sie die sample2-Funktion 200 zurückgeben.
    """
    status_code = 200
    url = "https://hogehoge.com"
    mocker.patch("src.script.sample2", return_value=status_code)
    assert sample1(url) == status_code


def test_sample1_mock_sample2_404(mocker):
    """
Lassen Sie die sample2-Funktion 404 zurückgeben.
    """
    status_code = 404
    url = "https://fugafuga.com"
    mocker.patch("src.script.sample2", return_value=status_code)
    assert sample1(url) == status_code

Ausführungsergebnis

 > pytest
======================== test session starts ========================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\root
plugins: cov-2.10.0, mock-3.3.1
collected 2 items

tests\test_script.py ..                                        [100%] 

========================= 2 passed in 0.19s =========================

Ändern Sie dynamisch den Rückgabewert einer Funktion

Testcode

tests/test_script.py


from src.script import sample1


def test_sample1_mock_sample2(mocker):
    """
Die Funktion sample2 ist 200 per URL,404,Versuchen Sie, eine von 0 zurückzugeben.
    """
    def return_status_code(url):
        """
200 per URL,404,Gibt einen von 0 zurück
        """
        if url == "https://hogehoge.com":
            return 200
        elif url == "https://fugafuga.com":
            return 404
        else:
            return 0

    mocker.patch("src.script.sample2", side_effect=return_status_code)
    assert sample1("https://hogehoge.com") == 200
    assert sample1("https://fugafuga.com") == 404
    assert sample1("https://higehige.com") == 0

Ausführungsergebnis

 > pytest
======================== test session starts ========================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\root
plugins: cov-2.10.0, mock-3.3.1
collected 1 item

tests\test_script.py .                                         [100%] 

========================= 1 passed in 0.20s =========================

Beim Aufrufen einer Funktion eine Ausnahme auslösen

Testcode

tests/test_script.py


import pytest
from src.script import sample1


def test_sample1_mock_sample2_exception(mocker):
    """
Lösen Sie eine Ausnahme aus, wenn die Funktion sample2 aufgerufen wird.
    """
    url = "https://hogehoge.com"
    mocker.patch("src.script.sample2", side_effect=Exception)
    with pytest.raises(Exception):
        sample1(url)

Ausführungsergebnis

 > pytest
======================== test session starts ========================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\root
plugins: cov-2.10.0, mock-3.3.1
collected 1 item

tests\test_script.py .                                         [100%] 

========================= 1 passed in 0.17s =========================

Verspotten Sie die Funktion des Moduls

Ersetzen Sie die get-Funktion des Anforderungsmoduls, wenn Sie die sample2-Funktion testen.

Geben Sie den Rückgabewert der Modulfunktion an

Testcode

tests/test_script.py


import requests
from src.script import sample2


def test_sample2_mock_requests_200(mocker):
    """
Anforderungen, die von der sample2-Funktion ausgeführt werden.Ersetzen Sie get.
Der Rückgabewert ist auch der Status in Mock_Ersetzen Sie den Code so, dass er 200 zurückgibt.
    """
    status_code = 200
    url = "https://hogehoge.com"
    response_mock = mocker.Mock()
    response_mock.status_code = status_code
    mocker.patch.object(requests, "get", return_value=response_mock)
    assert sample2(url) == status_code


def test_sample2_mock_requests_404(mocker):
    """
Anforderungen, die von der sample2-Funktion ausgeführt werden.Ersetzen Sie get.
Der Rückgabewert ist auch der Status in Mock_Ersetzen Sie den Code so, dass er 404 zurückgibt.
    """
    status_code = 404
    url = "https://fugafuga.com"
    response_mock = mocker.Mock()
    response_mock.status_code = status_code
    mocker.patch.object(requests, "get", return_value=response_mock)
    assert sample2(url) == status_code

Ausführungsergebnis

 > pytest
======================== test session starts ========================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\root
plugins: cov-2.10.0, mock-3.3.1
collected 1 item

tests\test_script.py ..                                        [100%] 

========================= 2 passed in 0.22s =========================

Auslösen einer Ausnahme beim Aufrufen einer Modulfunktion

Testcode

tests/test_script.py


import requests
from src.script import sample2


def test_sample2_mock_request_exception(mocker):
    """
Anfragen mit sample2 Funktion.Lösen Sie eine Ausnahme aus, wenn get aufgerufen wird.
    """
    status_code = 0
    url = "https://hogehoge.com"
    mocker.patch.object(requests, "get", side_effect=Exception)
    assert sample2(url) == status_code

Ausführungsergebnis

 > pytest
======================== test session starts ========================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\root
plugins: cov-2.10.0, mock-3.3.1
collected 1 item

tests\test_script.py .                                         [100%] 

========================= 1 passed in 0.19s =========================

Verspotten Sie die in der Methode der Klasse aufgerufene Funktion

Ersetzen Sie beim Testen der get-Methode der SampleClass-Klasse die get-Funktion von _req, die im Inneren aufgerufen wird.

Gibt den Rückgabewert einer Funktion an, die innerhalb einer Klassenmethode aufgerufen wird

Testcode

tests/test_script.py


from src.script import SampleClass


class TestSampleClass:
    def test_get_200(self, mocker):
        """
Wird von der get-Methode von SampleClass aufgerufen_req.Ersetzen Sie get.
Der Rückgabewert ist auch der Status in Mock_Ersetzen Sie den Code so, dass er 200 zurückgibt.
        """
        status_code = 200
        url = "https://hogehoge.com"
        sample = SampleClass()
        response_mock = mocker.Mock()
        response_mock.status_code = status_code
        req_mock = mocker.MagicMock()
        req_mock.get = mocker.Mock(return_value=response_mock)
        mocker.patch.object(sample, "_req", req_mock)
        assert sample.get(url) == status_code

Ausführungsergebnis

 > pytest
======================== test session starts ========================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\root
plugins: cov-2.10.0, mock-3.3.1
collected 1 item

tests\test_script.py .                                         [100%] 

========================= 1 passed in 0.21s =========================

Lösen Sie eine Ausnahme aus, wenn Sie eine Funktion aufrufen, die innerhalb einer Klassenmethode aufgerufen wird

Testcode

tests/test_script.py


from src.script import SampleClass


class TestSampleClass:
    def test_get_exception(self, mocker):
        """
Mit der get-Methode von SampleClass_req.Lösen Sie eine Ausnahme aus, wenn get aufgerufen wird.
        """
        status_code = 0
        url = "https://hogehoge.com"
        sample = SampleClass()
        req_mock = mocker.MagicMock()
        req_mock.get = mocker.Mock(side_effect=Exception)
        mocker.patch.object(sample, "_req", req_mock)
        assert sample.get(url) == status_code

Ausführungsergebnis

 > pytest
======================== test session starts ========================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\root
plugins: cov-2.10.0, mock-3.3.1
collected 1 item

tests\test_script.py .                                         [100%] 

========================= 1 passed in 0.21s =========================

Zusammenfassung

Ich habe es gerade selbst recherchiert und ausprobiert, daher weiß ich nicht, ob es der richtige Weg ist, es zu verwenden.

Recommended Posts

Verwenden Sie Mock mit Pytest
Verwenden Sie mecab-ipadic-neologd mit igo-python
Verwenden Sie RTX 3090 mit PyTorch
Verwenden Sie pipdeptree mit virtualenv
[Python] Verwenden Sie JSON mit Python
Verwenden Sie den Indikator mit pd.merge
Verwenden Sie Gentelella mit Django
Ich möchte datetime.datetime.now () auch mit pytest verspotten!
Getestet mit boto3 + mock
Verwenden Sie Mecab mit Python 3
Verwenden Sie Tensorboard mit Chainer
Verwenden Sie DynamoDB mit Python
Verwenden Sie pip mit MSYS2
Verwenden Sie Python 3.8 mit Anaconda
Verwenden Sie Copyright mit Spacemacs
Verwenden Sie Python mit Docker
Verwenden Sie TypeScript mit Django-Kompressor
Verwenden Sie WENIGER mit Django
Verwenden Sie MySQL mit Django
Verwenden Sie Enum mit SQLAlchemy
Verwenden Sie Tensorboard mit NNabla
Verwenden Sie GPS mit Edison
Verwenden Sie nim mit Jupyter
Verwenden Sie die Trello-API mit Python
Verwenden Sie gemeinsam genutzten Speicher mit gemeinsam genutzten Bibliotheken
Verwenden Sie benutzerdefinierte Tags mit PyYAML
Verwenden Sie Richtungsdiagramme mit networkx
Verwenden Sie TensorFlow mit Intellij IDEA
Verwenden Sie die Twitter-API mit Python
Versuchen Sie Google Mock mit C.
Verwenden Sie pip mit Jupyter Notebook
Testen Sie den Kolben mit einem Pytest
Verwenden Sie DATE_FORMAT mit dem SQLAlchemy-Filter
Testen Sie die Standardausgabe mit Pytest
Verwenden Sie TUN / TAP mit Python
Verwenden Sie sqlite3 mit NAO (Pepper)
Verwenden Sie die load_extensions von sqlite mit Pyramid
Verwenden Sie Windows 10-Schriftarten mit WSL
Verwendung von Chainer mit Jetson TK1
Verwenden Sie SSL mit Sellerie + Redis
Verwenden Sie Cython mit Jupyter Notebook
Verwenden Sie Maxout + CNN mit Pylearn2
Verwenden Sie WDC-433SU2M2 mit Manjaro Linux
Verwenden Sie OpenBLAS mit numpy, scipy
Verwenden Sie die Unterschall-API mit Python3
Verwenden von Sonicwall NetExtener mit Systemd
Verwenden Sie prefetch_related bequem mit Django
Verwenden Sie einen AWS-Interpreter mit Pycharm
Verwenden von Bokeh mit IPython Notebook
Verwenden Sie Python-ähnliche Bereiche mit Rust
Verwenden Sie MLflow mit Databricks ④ - Anrufmodell -
Verwenden Sie pyright mit CentOS7, emacs lsp-mode
Python: So verwenden Sie Async mit
Verwenden der SQL-Datenbank von Azure mit SQL Alchemy
Verwenden Sie eine Point Grey-Kamera mit Python (PyCapture2).
Verwenden Sie vl53l0x mit RaspberryPi (Python)
Verwenden Sie PX-S1UD / PX-Q1UD mit Jetson Nano
Mock in Python-Wie man Mox benutzt
Verwenden Sie die Vorschaufunktion mit aws-cli
So verwenden Sie virtualenv mit PowerShell