Hallo, ist um diese Zeit, dass das "geröstete Grüntee Latte Geschmack" Protein eines bestimmten M ○ Proteins im Verkauf gekauft nicht in Suppe trinken ** wie ein Geschmack von ** Garnelen (was
Übrigens, basierend auf der Richtlinie, dass die API unseres Django-Servers ** 120% im Test abdeckt **, schreiben wir den Testcode jeden Tag ungefähr doppelt so viel wie den Implementierungscode. Unter solchen Umständen werde ich heute kurz vorstellen, "wie die in der Helper-Klasse implementierte öffentliche Funktion über die API getestet wird (und wo sie hängen geblieben ist").
Die folgenden zwei Funktionen wurden implementiert (der Funktionsname usw. ist ein Dummy für die Veröffentlichung, und settings.py und urls.py sind bereits separat festgelegt).
app/views.py
from rest_framework.views import APIView
from app.helper import helper_foo
from app.models import HogehogeSerializer
class HogehogeListAPIView(APIView):
"""Implementieren Sie die Post-Funktionalität in der API-Ansicht mithilfe des Django-Frameworks
"""
permission_classes = (permissions.IsAuthenticated,)
def post(self, request, format=None):
""" API Post/hogehoge
"""
serializer = HogehogeSerializer(data=request.data)
if serializer.is_valid(): #Anforderungsdaten überprüfen
try:
with transaction.atomic():
serializer.save()
helper_foo(serializer.data) #Rufen Sie die Hilfsfunktion auf
except Exception as error:
return Response(status=status.HTTP_400_BAD_REQUEST)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
app/helper.py
import boto3
def helper_foo(data):
"""Hilfsfunktion
Erstellen Sie einen S3-Bucket basierend auf den Daten
"""
client = boto3.client("s")
"""
Erstellen Sie einen Bucket (werfen Sie einen Fehler, wenn er fehlschlägt)
"""
client.create_bucket(...
Und hier ist der Inhalt von pytest
app/tests.py
from django.test import TestCase
from django.conf import settings
from rest_framework.test import APIClient
class HogehogeAPITest(TestCase):
def setUp(self):
self.client = APIClient()
self.data = #Erstellen Sie Testdaten
def test_hogehoge_post(self):
response = self.client.post('/hogehoge',
self.data},
format='json')
self.assertEqual(response.status_code, 201)
#Überprüfen Sie mit verschiedenen Asserts
Der Code, der das S3Bucket tatsächlich erstellt, wird im Test ausgeführt, und das zusätzliche S3Bucket erhöht sich jedes Mal, wenn der Test ausgeführt wird.
Wird ausgeführt, indem die Funktion wie folgt mit einem Patch im Mock-Modul von Unittest verspottet werden kann
Ziel gibt app.helper.foo_helper
an.
app/tests.py
from unittest.mock import patch
from django.test import TestCase
from django.conf import settings
from rest_framework.test import APIClient
class HogehogeAPITest(TestCase):
def setUp(self):
self.client = APIClient()
@patch('app.helper.helper_foo')
def test_hogehoge_post(self, mock_function):
response = self.client.post('/hogehoge',
self.data},
format='json')
self.assertEqual(response.status_code, 201)
#Überprüfen Sie mit verschiedenen Asserts
self.assertEqual(mock_function.call_count, 1) #Überprüfen Sie, ob die Mock-Funktion einmal aufgerufen wurde
Bei der Ausführung schlägt das Testergebnis fehl und die folgende Meldung wird angezeigt
self.assertEqual(mock_function.call_count, 1)
AssertionError: 0 != 1
Oh, ist die Funktion nicht verspottet? Wenn Sie die AWS-Konsole überprüfen, ist S3Bucket (leider) gut gemacht.
Nach der Untersuchung verschiedener Dinge lautet die Referenzlogik von Patch wie folgt.
Jetzt wollen wir some_function testen, aber SomeClass mit patch () verspotten. Das Problem ist, dass beim Importieren von Modul b, was wir tun müssen, SomeClass aus Modul a importiert wird. Wenn wir patch () zum Verspotten verwenden aus a.SomeClass dann hat es keine Auswirkung auf unseren Test; Modul b hat bereits einen Verweis auf die echte SomeClass und es sieht so aus, als ob unser Patching keine Auswirkung hatte. (Quelle 3 / library / unittest.mock.html # where-to-patch))
Mit anderen Worten Wenn Modul b in Modul a importiert wird, wird Modul b von Modul a referenziert, sodass die Referenzierung mit b.someclass (helper.helper_foo hier) den Test nicht beeinflusst. Und das
Also habe ich das Mock-Ziel von "app.helper.foo_helper" in "app.views.foo_helper" geändert.
app/tests.py
from unittest.mock import patch
from django.test import TestCase
from django.conf import settings
from rest_framework.test import APIClient
class HogehogeAPITest(TestCase):
def setUp(self):
self.client = APIClient()
@patch('app.views.helper_foo')
def test_hogehoge_post(self, mock_function):
response = self.client.post('/hogehoge',
self.data},
format='json')
self.assertEqual(response.status_code, 201)
#Überprüfen Sie mit verschiedenen Asserts
self.assertEqual(mock_function.call_count, 1) #Überprüfen Sie, ob die Mock-Funktion einmal aufgerufen wurde
Dies bestätigte, dass der Test funktionierte und kein S3-Bucket generiert wurde.
Ich benutze Python seit fast 10 Jahren, aber zum ersten Mal konnte ich den Mechanismus der Modulreferenz während des Imports verstehen.
das ist alles. Testcode ist in Bereichen interessant, in denen es verschiedene Entdeckungen gibt, daher hoffe ich, dass Qiita in diesen Tagen um weitere Pytest-Artikel erweitert wird.
Recommended Posts