2

Lassen Sie uns sagen, ich habe ein Article Modell, wie folgt aus:Komponententest prüft, ob Datenbankabfragen korrekt sind - was kann man spotten?

from django.db import models 

class Article(models.Model): 
    author = models.CharField(max_length=100) 
    title = models.CharField(max_length=200) 
    body = models.TextField() 

Diese Naivität ist einfach im Vergleich zu meinem tatsächlichen Nutzung (author ein ForeignKey auf ein anderes Modell sein sollte, etc.), aber auf diese Weise ist es klarer.

Stellen Sie sich vor, ich möchte die Titel aller Artikel von bestimmten Autoren auflisten, aber die Stücke jedes Autors zusammenhalten. Man könnte es als eine Liste von Listen dargestellt werden:

def get_beatles_articles_titles(): 
    beatles = [ 
     "John Lennon", 
     "Paul McCartney", 
     "George Harrison", 
     "Ringo Starrr", 
    ] 
    return [article.author for author in beatles 
      for article in Article.objects.filter(author=author)] 

Oh, eine verschachtelte Liste Verständnis, so dass unsere Methode nicht so einfach ist. Es besteht die große Chance, dass sich irgendwo ein Bug befindet, also sollten wir es irgendwie testen! Die einfachste Lösung scheint darin zu bestehen, einige Article Instanzen zu erstellen, die jedem Autor entsprechen (und sie in der Datenbank zu speichern) und zu überprüfen, ob alle von ihnen korrekt abgerufen wurden.

Mit diesem Test können wir sehen, dass es einen Tippfehler in unserem ursprünglichen Code gibt, also hat es sich als nützlich erwiesen.

Der Zugriff auf die Datenbank ist jedoch verpönt zugunsten der Spott der Dinge (kein Wunder, ich habe erlebt, dass Zeitunterschied kann erheblich sein). Was kann im obigen Test verspottet werden? Ich bin besonders besorgt über die Korrektheit meiner .filter Abfrage (es könnte ziemlich komplex werden), so will ich nicht QuerySet s sähen, würde mir eine DB geben.

Idealerweise würde Ich mag so etwas wie dieses verwenden (Pseudo-Code folgt):

johns_article = Article(author="John Lennon") 
fake_query = MockQuery(author__contains="John") 
assertTrue(fakeQuery.contains(johns_article)) 

Antwort

1

Zugriff auf Datenbank auf für spöttische Dinge

verpönt Warum ist das? ? Gemeinsame Anliegen sind:

  • Prüfgeschwindigkeit
  • Test Zuverlässigkeit
  • Test flakiness
  • Test Parallelisierung
  • Befestigung Schaffung
  • Datenmanagement im Allgemeinen

Wenn Sie testen Ihre Datenbankinteraktion würde der einzige Weg sein, Ihren Test erneut auszuführen st eine Datenbank. Django hat Sie abgedeckt und einen Rahmen geschaffen, der alle oben genannten Bedenken berücksichtigt. Der Django TestCase behandelt all das für Sie. Es verwaltet eine Testdatenbank, stellt Tools für die Bereitstellung bereit, führt alle Tests in Transaktionen aus und räumt schnell auf, indem es nach jeder Transaktion zurücksetzt.

Ich stimme auf jeden Fall zu, dass für schnelle Tests sollten sie auf der Ebene der Einheit durchgeführt werden und stumpf alle Zusammenarbeit und Datei/Socket-Zugang, aber in diesem Fall sollte django Sie abgedeckt haben.

Sie verwenden bereits die django-Datenbank, die für jeden Testlauf bereitgestellt wird. Warum also nicht darauf zugreifen?

Also im Grunde ist dein Test richtig, django hat die Tools dafür erstellt, es ist überhaupt kein Anti-Pattern. Eine gemeinsame Strategie besteht darin, mehrere Stufen von Tests zu haben. Sie könnten einen "Unit-Test" - oder "Small-Test" -Framework haben und einen Test-Runner, der keine IO-Tests durchführt, wo die meisten Ihrer Tests laufen, wo alle Kollaborationen verspottet werden. Implementieren Sie anschließend eine Reihe von Tests in Django TestCase, um die Datenbankinteraktion zu testen.


Wenn youre mit Start-Test/django gibt es ein paar Dinge, die auf lange Sicht helfen könnte:

  1. Ihre Anfragen Profil kann get_beatles_articles_titles optimiert und mit weniger Abfragen erfolgen
  2. Verwenden Sie die bulk_create Methode anstelle von mehreren create Methoden
  3. Mit einer Abstraktion, um Ihre Testmodelle instanziieren, mein Favorit ist Factory-Boy. Dies hilft Ihnen, die Änderungen an den Anforderungen für die Erstellung von Modellen zu vermeiden. Darüber hinaus können Sie sinnvolle und dynamische Standardeinstellungen erstellen, sodass der Erstellungsprozess wesentlich prägnanter ist.
+0

Danke für die Erinnerung an 'bulk_create'. Ehrlich gesagt, ich möchte eine solche Funktion irgendwann sehen, aber danke für die Erklärung, warum es nicht so viel ist! – Szymon

Verwandte Themen