Schreiben Sie testgetriebenen FizzBuzz-Code mit Python doctest.

Einführung

Ich habe ein testgetriebenes FizzBuzz-Programm mit dem Standard-Bibliotheks-Doctest geschrieben.

Was ist doctest (Zitat)

http://docs.python.jp/2/library/doctest.html (Zitat starten) Das doctest-Modul sucht nach Text, der wie eine interaktive Python-Sitzung aussieht, führt den Inhalt der Sitzung aus und prüft, ob er sich genau so verhält, wie er geschrieben wurde. doctest wird häufig für die folgenden Zwecke verwendet.

Überprüfen Sie, ob der Inhalt der Dokumentzeichenfolge auf dem neuesten Stand ist, indem Sie überprüfen, ob alle interaktiven Ausführungsbeispiele in der Dokumentzeichenfolge (Dokumentationszeichenfolge) des Moduls wie geschrieben funktionieren. Ein Regressionstest wird erreicht, indem überprüft wird, ob die interaktiven Ausführungsbeispiele in der Testdatei oder im Testobjekt wie erwartet funktionieren. Sie können ein Tutorial-Dokument für ein Paket schreiben, das viele Eingabe- / Ausgabebeispiele verwendet. Ein Dokument kann ein "lesbarer Test" oder ein "ausführbares Dokument" sein, je nachdem, ob Sie sich auf Eingabe- / Ausgabebeispiele oder Kommentare konzentrieren. (Ende des Zitierens)

doctest scheint ein hervorragendes Werkzeug zu sein, das für Regressionstests beim Überprüfen von Dokumenten (Kommentaren) verwendet werden kann. Ich habe keine andere Wahl, als es zu versuchen.

Testgetriebene Entwicklungsmethode (Zitat)

http://www.atmarkit.co.jp/ait/articles/1403/05/news035.html (Zitat starten (nur Überschrift)) [1] Schreiben Sie einen Testcode, der fehlschlägt [2] Schreiben Sie den zu testenden Code so, dass der Test von Fehler zu Erfolg wechselt [3] Fügen Sie Testcode hinzu, der dazu führt, dass der Test fehlschlägt [4] Schreiben Sie den zu testenden Code so, dass der Test von Fehler zu Erfolg wechselt [5] Refactor bei erfolgreichem Test (Ende des Zitierens)

Dieses Mal werden wir dieser Methode folgen.

Spezifikationen dieser Funktion

Ich habe die Spezifikationen entsprechend festgelegt. Funktionsname: fizzbuzz (n) Funktion: Wenn der Eingabewert n ein Vielfaches von 3 ist, wird der String 'Fizz' zurückgegeben und Wenn der Eingabewert n ein Vielfaches von 5 ist, wird der String 'Buzz' zurückgegeben und Wenn der Eingabewert n ein Vielfaches von 15 ist, wird der String 'FizzBuzz' zurückgegeben und Ansonsten eine Funktion, die die ganze Zahl n ausgibt.

n muss eine Ganzzahl sein, die durch einen Ganzzahltyp, einen langen Ganzzahltyp oder einen Gleitkomma-Minoritätstyp dargestellt wird. (Für Gleitkomma-Minderheitstypen muss der Bruchteil 0 sein.) Wenn eine kleine Zahl eingegeben wird, wird eine InputError-Ausnahme zurückgegeben.

[1] Schreiben Sie einen Testcode, der fehlschlägt

Zunächst die vorübergehende Umsetzung

def fizzbuzz(n):
  '''
Wenn der Eingabewert n ein Vielfaches von 3 ist'Fizz'Gibt die Zeichenfolge zurück
Wenn der Eingabewert n ein Vielfaches von 5 ist'Buzz'Gibt die Zeichenfolge zurück
Wenn der Eingabewert n ein Vielfaches von 15 ist'FizzBuzz'Gibt die Zeichenfolge zurück
Ansonsten eine Funktion, die die ganze Zahl n ausgibt.
Beispiel:
  >>> fizzbuzz(3)
  'Fizz'
  
n muss eine Ganzzahl sein, die durch einen Ganzzahltyp, einen langen Ganzzahltyp oder einen Gleitkomma-Minoritätstyp dargestellt wird.
(Für Gleitkomma-Minderheitstypen muss der Bruchteil 0 sein.)
Wenn eine kleine Zahl eingegeben wird, wird InputError zurückgegeben.
  '''
  
  return 'Fizz'

if __name__ == '__main__':
  import doctest
  doctest.testmod()

Ausführen (-v ist eine Option für die detaillierte Ausgabe). Wenn Sie -v nicht hinzufügen, werden die Informationen nur ausgegeben, wenn der Test fehlschlägt.

python fizzbuzz_doctest.py -v 

In diesem Zustand kommt ok heraus.

Versuchen Sie, einen Testfall hinzuzufügen

>>> fizzbuzz(5)
'Buzz'

Der folgende Fehler wird ausgegeben.

File "fizzbuzz_doctest.py", line12, in __main__.fizzbuzz
Failed example:
    fizzbuzz(5)
Expected:
    'Buzz'
Got:
    'Fizz'
1 items had no tests:
    __main__

[2] Schreiben Sie den zu testenden Code so, dass der Test von Fehler zu Erfolg wechselt

Ändern Sie wie folgt.

  if (n%3) == 0:
    return 'Fizz'
  elif (n%5) == 0:
    return 'Buzz'

[3] Fügen Sie Testcode hinzu, der dazu führt, dass der Test fehlschlägt

Wiederholen der obigen [1]

[4] Schreiben Sie den zu testenden Code so, dass der Test von Fehler zu Erfolg wechselt

Wiederholen der obigen [2]

Ergänzung

Ausnahmetests müssen anscheinend mit Traceback beginnen. Sie können auch die mittlere Zeile mit ... weglassen.

  >>> fizzbuzz(5.5)
  Traceback (most recent call last):
      ...
  ValueError: n must be integer. n: 5.500000

Code (Zwischenstufe)

# coding: utf-8

def fizzbuzz(n):
  '''
Wenn der Eingabewert n ein Vielfaches von 3 ist'Fizz'Gibt die Zeichenfolge zurück
Wenn der Eingabewert n ein Vielfaches von 5 ist'Buzz'Gibt die Zeichenfolge zurück
Wenn der Eingabewert n ein Vielfaches von 15 ist'FizzBuzz'Gibt die Zeichenfolge zurück
Ansonsten eine Funktion, die die ganze Zahl n ausgibt.
Beispiel:
  >>> fizzbuzz(3)
  'Fizz'
  
  >>> fizzbuzz(36)
  'Fizz'
  
  >>> fizzbuzz(5)
  'Buzz'
  
  >>> fizzbuzz(50)
  'Buzz'
  
  >>> fizzbuzz(15)
  'FizzBuzz'
  
  >>> fizzbuzz(45)
  'FizzBuzz'
  
  >>> fizzbuzz(2)
  2
  
  >>> fizzbuzz(49)
  49
  
n muss eine Ganzzahl sein, die durch einen Ganzzahltyp, einen langen Ganzzahltyp oder einen Gleitkomma-Minoritätstyp dargestellt wird.
(Für Gleitkomma-Minderheitstypen muss der Bruchteil 0 sein.)
Wenn eine kleine Zahl eingegeben wird, wird ValueError zurückgegeben.
  
  >>> fizzbuzz(1.0)
  1

  >>> fizzbuzz(5.0)
  'Buzz'
  
  >>> fizzbuzz(5.5)
  Traceback (most recent call last):
      ...
  ValueError: n must be integer. n: 5.500000
  
  '''
  if n != int(n):
    raise ValueError( 'n must be integer. n: %f' % n )
  n = int(n)

  if (n%15) == 0:
    return 'FizzBuzz'
  elif (n%3) == 0:
    return 'Fizz'
  elif (n%5) == 0:
    return 'Buzz'
  else:
    return n

if __name__ == '__main__':
  import doctest
  doctest.testmod()

[5] Refactor bei erfolgreichem Test

Es scheint, dass der endgültige Code durch Refactoring erhalten werden kann, während der Betrieb durch Testen sichergestellt wird.

Sie können beispielsweise die folgenden Änderungen vornehmen: Um die Referenzkosten der if-Anweisung zu reduzieren, erstellen Sie im Voraus eine Liste mit dem Rest, geteilt durch 15 von 1 bis 15, und bestimmen Sie die zurückzugebende Zeichenfolge anhand dieser Liste.

  '''
  if (n%15) == 0:
    return 'FizzBuzz'
  elif (n%3) == 0:
    return 'Fizz'
  elif (n%5) == 0:
    return 'Buzz'
  else:
    return n
  '''
  
  fizzbuzz_list = []
  for i in range(15):
    if (i%15) == 0:
      fizzbuzz_list.append('FizzBuzz')
    elif (i%5) == 0:
      fizzbuzz_list.append('Buzz')
    elif (i%3) == 0:
      fizzbuzz_list.append('Fizz')
    else:
      fizzbuzz_list.append(0)
  r = int(n%15)
  return fizzbuzz_list[r] if fizzbuzz_list[r] else n

Sie können einen Regressionstest mit dem folgenden Befehl durchführen, ohne einen neuen Test zu schreiben.

python fizzbuzz_doctest.py -v

Lassen Sie uns den Algorithmus weiter ändern.

  '''
  if (n%15) == 0:
    return 'FizzBuzz'
  elif (n%3) == 0:
    return 'Fizz'
  elif (n%5) == 0:
    return 'Buzz'
  else:
    return n

  
  fizzbuzz_list = []
  for i in range(15):
    if (i%15) == 0:
      fizzbuzz_list.append('FizzBuzz')
    elif (i%5) == 0:
      fizzbuzz_list.append('Buzz')
    elif (i%3) == 0:
      fizzbuzz_list.append('Fizz')
    else:
      fizzbuzz_list.append(0)
  '''

  fizzbuzz_list =  ['FizzBuzz', 0, 0, 'Fizz', 0, 'Buzz', 'Fizz', 0, 0, 'Fizz', 'Buzz', 0, 'Fizz', 0, 0 ]
  r = n%15
  return fizzbuzz_list[r] if fizzbuzz_list[r] else n

Sie können den Regressionstest wie zuvor mit dem folgenden Befehl ausführen.

python fizzbuzz_doctest.py -v

Endgültiger Code

Nicht nur der Code, sondern auch die Dokumentation ist vollständig.

# coding: utf-8

def fizzbuzz(n):
  '''
Wenn der Eingabewert n ein Vielfaches von 3 ist'Fizz'Gibt die Zeichenfolge zurück
Wenn der Eingabewert n ein Vielfaches von 5 ist'Buzz'Gibt die Zeichenfolge zurück
Wenn der Eingabewert n ein Vielfaches von 15 ist'FizzBuzz'Gibt die Zeichenfolge zurück
Ansonsten eine Funktion, die die ganze Zahl n ausgibt.
Beispiel:
  >>> fizzbuzz(3)
  'Fizz'
  
  >>> fizzbuzz(36)
  'Fizz'
  
  >>> fizzbuzz(5)
  'Buzz'
  
  >>> fizzbuzz(50)
  'Buzz'
  
  >>> fizzbuzz(15)
  'FizzBuzz'
  
  >>> fizzbuzz(45)
  'FizzBuzz'
  
  >>> fizzbuzz(2)
  2
  
  >>> fizzbuzz(49)
  49
  
n muss eine Ganzzahl sein, die durch einen Ganzzahltyp, einen langen Ganzzahltyp oder einen Gleitkomma-Minoritätstyp dargestellt wird.
(Für Gleitkomma-Minderheitstypen muss der Bruchteil 0 sein.)
Wenn eine kleine Zahl eingegeben wird, wird ValueError zurückgegeben.
  
  >>> fizzbuzz(1.0)
  1
  
  >>> fizzbuzz(5.0)
  'Buzz'
  
  >>> fizzbuzz(5.5)
  Traceback (most recent call last):
      ...
  ValueError: n must be integer. n: 5.500000
  
  '''
  if n != int(n):
    raise ValueError( 'n must be integer. n: %f' % n )
  n = int(n)

  fizzbuzz_list = ['FizzBuzz', 0, 0, 'Fizz', 0, 'Buzz', 'Fizz', 0, 0, 'Fizz', 'Buzz', 0, 'Fizz', 0, 0 ]
  r = n%15
  return fizzbuzz_list[r] if fizzbuzz_list[r] else n

if __name__ == '__main__':
  import doctest
  doctest.testmod()

Fazit

Es scheint einfach zu bedienen zu sein, da Sie Dokumente gleichzeitig testen und erstellen können. Es wurde darauf hingewiesen, dass der Code aufgrund der langen Kommentare schwer zu lesen ist. Die beiden Vorteile bestehen jedoch darin, dass das Verlassen des Dokuments die Wartbarkeit verbessert und die Qualität durch Ausführen des Regressionstests garantiert werden kann. fühlen wie.

Recommended Posts

Schreiben Sie testgetriebenen FizzBuzz-Code mit Python doctest.
Schreiben Sie FizzBuzz ohne "="
Schreiben Sie Selentestcode in Python
Überprüfen Sie den Python-Codestil mit pep8
Schreiben Sie den Ethereum-Vertragscode mit Serpent
Führen Sie Python-Code unter C ++ aus (mit Boost.Python).
Holen Sie sich Python-Quellcode-Metriken mit Radon
Schreiben Sie FizzBuzz mit map (), redu (), filter (), rekursiv
Schreiben Sie mit f2py ein Python-Modul in fortran
python setup.py testet den Code mit Multiprocess
FizzBuzz in Python3
Schreiben Sie Python-ähnlichen Code
Schreiben wir FizzBuzz mit einem Fehler: Python-Version
Debuggen mit VS-Code mit Boost Python Numpy
Starten Sie Python
Python-Zeichencode
FizzBuzz in Python
[Python] Code, der Algorithmen kennt
Scraping mit Python
Ich möchte in Python schreiben! (1) Überprüfung des Codeformats
Verzeichnisstruktur für die testgetriebene Entwicklung mit pytest in python
[Python] Ich habe sofort versucht, die VS-Code-Erweiterung von Pylance zu verwenden.
Schreiben wir Python-Code, der Go-Code analysiert und Go-Code generiert
So erstellen Sie ein Python-Paket mit VS Code
Schreiben Sie Daten mit dem Python-Anforderungsmodul in KINTONE
Lesen und schreiben Sie NFC-Tags mit Python mit PaSoRi
Schreiben Sie Code in UnitTest, eine Python-Webanwendung
[Einführung in Python] So schreiben Sie sich wiederholende Anweisungen mit for-Anweisungen
Schreiben Sie Python-ähnlichen Code (Dictionary)
Bearbeiten Sie Redmine mit Python Redmine
Fibonacci-Sequenz mit Python
Schreiben Sie Python2-Code in Python3 um (2to3)
Infomap Python-Zeichencode
Vor dem Schreiben von Python-Code
Schreiben Sie Python in MySQL
Datenbereinigung mit Python
Verwenden von Python # externen Paketen
WiringPi-SPI-Kommunikation mit Python
Altersberechnung mit Python
Suchen Sie Twitter mit Python
Namensidentifikation mit Python
Python Fordert den Statuscode an
Hinweise zur Verwendung von Python-Unterprozessen
Ich habe versucht, doctest zu verwenden
Versuchen Sie es mit Tweepy [Python2.7]
[Einführung in Python] Wie man bedingte Verzweigungen mit if-Anweisungen schreibt
[Python] Kapitel 01-03 Über Python (Schreiben und Ausführen eines Programms mit PyCharm)