Advertisement
  1. Code
  2. Python

Beginn der testgetriebenen Entwicklung in Python

Scroll to top
Read Time: 20 min

() translation by (you can also view the original English article)

Test-driven development (TDD) ist ein Prozess, der dokumentiert wurde, deutlich über den vergangenen Jahren. Ein Prozess der Backen Sie Ihre tests direkt in Ihr Alltags-Kodierung, im Gegensatz zu einer Art nachträglicher Einfall, sollte etwas sein, das die Entwickler zu suchen, um die norm, sondern als eine ideale fantasy.

Stelle ich die grundlegenden Konzepte der TDD.

Der ganze Prozess ist sehr einfach in den Griff zu bekommen, und es sollte nicht allzu lange dauern, bevor Sie sich Fragen, wie Sie in der Lage waren, etwas zu tun, bevor! Es gibt riesige Gewinne gemacht werden, von TDD—nämlich die Qualität Ihres Codes zu verbessern, aber auch Klarheit und Fokus auf das, was es ist, dass Sie versuchen, zu erreichen, und die Art und Weise Sie es erreichen werden. TDD arbeitet auch nahtlos mit der agilen Entwicklung, und am besten eingesetzt werden können, wenn pair-programming, wie Sie später sehen werden.

In diesem tutorial Stelle ich die grundlegenden Konzepte der TDD, und geben Beispiele in Python, mit der nosetests unit-Test-Paket. Ich werde zusätzlich bieten einige alternative Pakete, sind auch in Python.


Was Ist Test-Driven Development?

Dieser Ansatz ermöglicht es Ihnen, zu entkommen der Falle, dass viele Entwickler in den Herbst.

TDD, in seiner am meisten grundlegenden Begriffe, ist der Prozess der Implementierung von code durch das schreiben der ersten tests sehen, wie Sie scheitern, dann schreiben Sie den code, um die tests übergeben. Sie können dann bauen Sie auf dieser entwickelten code durch entsprechend verändern Sie Ihre test, um zu erwarten, dass das Ergebnis von zusätzlichen Funktionen, dann schreiben Sie den code, um es wieder passen.

Sie können sehen, dass TDD ist sehr viel ein Zyklus, mit deinem code geht durch, wie viele Iterationen des tests, das schreiben und die Entwicklung wie nötig, bis die Funktion beendet ist. Durch die Implementierung dieser tests, bevor Sie den code schreiben, es bringt eine Natürliche Tendenz zu denken, über Ihr problem zu ersten. Während Sie beginnen, bauen Ihre Prüfung, die Sie zu denken haben die Möglichkeit, entwerfen Sie Ihren code. Was wird diese Methode zurück? Was, wenn wir hier eine Ausnahme? Und so weiter.

Durch die Entwicklung auf diese Weise, es bedeutet, Sie betrachten die verschiedenen Routen durch den code, und bedecken Sie diese mit tests, wie gebraucht. Dieser Ansatz ermöglicht es Ihnen, zu entkommen der Falle, dass viele Entwickler fallen in (mich eingeschlossen): Tauchen in ein problem, und schreiben code, der ausschließlich für die erste Lösung, die Sie brauchen, um zu behandeln.

Der Prozess kann wie folgt definiert werden:

  • Schreiben Sie eine ausgefallene Einheit test
  • Stellen Sie die unit-test-pass
  • Umgestalten

Wiederholen Sie diesen Vorgang für jede Funktion, wie es nötig ist.


Agile Entwicklung Mit Test-Driven Development

TDD ist eine perfekte Ergänzung für die ideale und Prinzipien der Agilen Entwicklung, mit einem großen Streben zu liefern inkrementelle updates für ein Produkt mit echter Qualität im Gegensatz zu Quantität. Das Vertrauen in die einzelnen Einheiten von code, unit-Tests bietet bedeutet, dass Sie diese Anforderung erfüllen, Qualität zu liefern, während die Beseitigung der Probleme in Ihrer Produktion-Umgebungen.

"Das bedeutet, dass beide Parteien in der pair-Mädchen engagiert, konzentriert auf das, was Sie tun, und überprüfen die Arbeit der anderen in jeder Phase."

TDD kommt in seine eigene, wenn pair programming, jedoch. Die Fähigkeit zu mischen, bis Ihre Entwicklung workflow beim arbeiten als paar, wie Sie sehen, passen, ist schön. Zum Beispiel kann eine person schreiben der unit-Tests, siehe es passieren, und dann lassen Sie die anderen Entwickler, den code zu schreiben, um die test-pass.

Die Rollen können entweder umgeschaltet werden jedes mal, jeden halben Tag, oder jeden Tag, wie Sie sehen, passen. Dies bedeutet, dass beide Parteien in der pair-Mädchen engagiert, konzentriert auf das, was Sie tun, und überprüfen die Arbeit der anderen in jeder Phase. Das bedeutet ein Gewinn in jeder Hinsicht mit diesem Ansatz, ich denke Sie würde Zustimmen.

TDD auch ein integraler Bestandteil des Verhaltens Driven Development-Prozess, das wird wieder, das schreiben von tests nach vorne, aber in form von Akzeptanztests. Diese sorgen für ein feature "verhält sich" in der Weise, die Sie erwarten, von Ende zu Ende. Mehr Informationen finden Sie einem der kommenden Artikel hier auf Tuts+, werden für BDD in Python.


Syntax für Unit-Tests

Die wichtigsten Methoden, die wir nutzen, in unit-Tests für Python sind:

  • geltend machen: Basis geltend machen, so dass Sie schreiben Sie Ihre eigenen Behauptungen
  • assertEqual(a, b): überprüfen Sie a und b gleich sind
  • assertNotEqual(a, b): überprüfen Sie a und b nicht gleich sind
  • assertIn(a, b): überprüfen Sie, dass a das Element b
  • assertNotIn(a, b): überprüfen Sie, dass a nicht in das Element b
  • assertFalse(a): überprüfen Sie, dass der Wert von a ist False
  • assertTrue(a): prüfen Sie den Wert von a Wahr ist,
  • assertIsInstance(ein, ART): schauen Sie, dass ist der Typ "TYP"
  • assertRaises(FEHLER, a, args): prüfen Sie, dass, wenn ein Aufruf mit args, es wirft FEHLER

Es gibt sicherlich mehrere Methoden zur Verfügung, die Sie anzeigen können,—finden Sie in der Python-Unit-Test-Docs—aber, in meiner Erfahrung, die oben aufgelistet sind, sind unter den am häufigsten verwendet. Wir nutzen diese in unseren Beispielen weiter unten.

Die Installation und Verwendung von Python die Nase

Bevor Sie die folgenden übungen, die Sie installieren, müssen nosetest test-Läufer-Paket. Installation der nosetest runner ist einfach, nach dem standard "pip" installieren-Muster. Es ist in der Regel auch eine gute Idee, um die Arbeit an Ihren Projekten mit virtualenv, die dafür sorgt, dass alle Pakete, die Sie für verschiedene Projekte zu trennen. Wenn Sie nicht vertraut sind mit pip oder virtualenv ist, können Sie finden die Dokumentation hier: VirtualEnv, PIP.

Die pip installieren ist so einfach wie das ausführen dieser Zeile:

1
"pip install nose"

Einmal installiert, führen Sie einen einzigen test-Datei.

1
$ nosetests example_unit_test.py

Oder Sie führen eine Reihe von tests in einem Ordner.

1
$ nosetests /path/to/tests

Der einzige standard, die Sie Folgen müssen, wird zu Beginn eines jeden test-Methode mit "test_", um sicherzustellen, dass die nosetest Läufer finden, dass Ihre tests!

Optionen

Einige nützliche Kommandozeilen-Optionen, die Sie wollen im Auge zu behalten sind:

  • -v: gibt mehr Informationen in der Ausgabe, einschließlich der Namen des tests, der ausgeführt wird.
  • -s oder -nocapture: ermöglicht die Ausgabe der print-Anweisungen, die normalerweise gefangen und verborgen, während der Durchführung der tests. Nützlich für die Fehlersuche.
  • --nologcapture: ermöglicht die Ausgabe von logging-Informationen.
  • --rednose: ein optionales plugin, welches hier heruntergeladen werden kann, bietet aber eine farbige Ausgabe für die tests.
  • --tags=TAGS: können Sie ein @ - TAG über einen bestimmten test nur ausführen, anstatt das gesamte test-suite.

Beispiel Problem und Test-Driven-Ansatz

Wir werden einen Blick auf ein wirklich einfaches Beispiel zur Einführung sowohl unit-Tests in Python das Konzept von TDD. Schreiben wir einen sehr einfachen Rechner, Klasse, addition, Subtraktion und andere einfache Methoden, wie man es erwarten würde.

Nach einem TDD-Ansatz, lassen Sie uns sagen, dass wir eine Anforderung für eine Funktion hinzufügen, die bestimmen die Summe zweier zahlen und Rückgabe der Ausgabe. Schreiben Sie einen fehlschlagenden test.

In ein leeres Projekt, erstellen Sie zwei Pakete für python, die app und testen. Machen Sie Python-Pakete (und damit Unterstützung für das importieren der Dateien in die tests zu einem späteren Zeitpunkt) erstellen Sie eine leere Datei namens __init__.py in jedem Verzeichnis. Dies ist die Python-standard-Struktur für Projekte und muss getan werden, um zu erlauben, Element zu sein und kann über die Verzeichnisstruktur. Für ein besseres Verständnis dieser Struktur, können Sie beziehen sich auf die Pakete für Python-Dokumentation. Erstellen Sie eine Datei namens test_calculator.py in dem test-Verzeichnis mit dem folgenden Inhalt.

1
import unittest
2
3
class TddInPythonExample(unittest.TestCase):
4
5
  def test_calculator_add_method_returns_correct_result(self):
6
		calc = Calculator()
7
		result = calc.add(2,2)
8
		self.assertEqual(4, result)

Schreiben der test ist ziemlich einfach.

  • Zuerst importieren wir die standard-unittest-Modul aus der Python-standard-Bibliothek.
  • Als Nächstes brauchen wir eine Klasse enthalten, die verschiedenen Testfälle.
  • Endlich eine Methode ist notwendig für den test selbst, mit die einzige Voraussetzung ist, dass es ein name mit "test_" am Anfang, so dass es abgeholt werden kann und ausgeführt, indem die nosetest Läufer, die wir in Kürze cover.

Mit der Struktur im Ort, wir können dann schreiben Sie den test-code. Wir initialisieren unsere Rechner so, dass wir die Methoden ausführen. Nach dieser, wir können dann rufen Sie die add-Methode, die wir testen möchten, und speichern Sie Ihren Wert in der Variablen Ergebnis. Sobald dies abgeschlossen ist, können wir dann nutzen unittest ist assertEqual Methode, um sicherzustellen, dass unser Rechner ist add-Methode verhält sich wie erwartet.

Sie verwenden nun die nosetest Läufer, um den test auszuführen. Könnten Sie führen Sie den test unter Verwendung der standard-unittest-Läufer, wenn Sie wollen, indem Sie den folgenden code-block am Ende der test-Datei.

1
if __name__ == '__main__':
2
    unittest.main()

Dies ermöglicht es Ihnen, führen Sie den test mit den standard-Weg in der Ausführung von Python-Dateien, $ python test_calculator.py. Aber für dieses tutorial, Sie gehen zu nutzen Sie die nosetests runner, der hat einige nette features, wie zum Beispiel die execute-Nase-tests gegen ein Verzeichnis aller tests, unter anderen nützlichen Funktionen.

1
$ nosetests test_calculator.py
2
E
3
======================================================================
4
ERROR: test_calculator_add_method_returns_correct_result (test.test_calculator.TddInPythonExample)
5
----------------------------------------------------------------------
6
Traceback (most recent call last):
7
  File "/Users/user/PycharmProjects/tdd_in_python/test/test_calculator.py", line 6, in test_calculator_add_method_returns_correct_result
8
    calc = Calculator()
9
NameError: global name 'Calculator' is not defined
10
11
----------------------------------------------------------------------
12
Ran 1 test in 0.001s
13
14
FAILED (errors=1)

Aus der Ausgabe nosetest uns gegeben hat, können wir sehen, dass das problem betrifft uns nicht importieren-Rechner. Das ist, weil wir noch nicht erstellt, es kommt noch! So lasst uns gehen und definieren unsere Rechner in einer Datei namens calculator.py unter dem app-Verzeichnis, und importieren es:

1
	class Calculator(object):
2
3
		def add(self, x, y):
4
			pass
1
import unittest
2
from app.calculator import Calculator
3
4
class TddInPythonExample(unittest.TestCase):
5
6
	def test_calculator_add_method_returns_correct_result(self):
7
		calc = Calculator()
8
		result = calc.add(2,2)
9
		self.assertEqual(4, result)
10
11
12
if __name__ == '__main__':
13
    unittest.main()

Nun haben wir die Rechner definiert, mal sehen, was nosetest zeigt uns nun:

1
$ nosetests test_calculator.py
2
F
3
======================================================================
4
FAIL: test_calculator_add_method_returns_correct_result (test.test_calculator.TddInPythonExample)
5
----------------------------------------------------------------------
6
Traceback (most recent call last):
7
  File "/Users/user/PycharmProjects/tdd_in_python/test/test_calculator.py", line 9, in test_calculator_add_method_returns_correct_result
8
    self.assertEqual(4, result)
9
AssertionError: 4 != None
10
11
----------------------------------------------------------------------
12
Ran 1 test in 0.001s
13
14
FAILED (failures=1)

So, offensichtlich, unsere add-Methode ist wieder der falsche Wert, als es nicht tun im moment. Handlich, nosetest gibt uns die betreffende Zeile in der test, und dann können wir bestätigen, was wir ändern müssen. Lasst uns die Methode und sehen, ob unser test geht jetzt:

1
	class Calculator(object):
2
3
		def add(self, x, y):
4
			return x+y
1
$ nosetests test_calculator.py
2
.
3
----------------------------------------------------------------------
4
Ran 1 test in 0.000s
5
6
OK

Erfolg! Wir haben festgelegt, unsere add-Methode und es funktioniert wie erwartet. Jedoch, es ist mehr Arbeit zu tun, um diese Methode, um sicherzustellen, dass wir es getestet haben, richtig.

Wir haben in die Falle gegangen, nur Tests der Fall interessiert uns im moment.

Was würde passieren, wenn jemand waren, um etwas anderes als zahlen? Python wird tatsächlich ermöglichen es, die addition von strings und andere Typen, aber in unserem Fall, für unsere Rechner, macht es Sinn, die erlauben nur das hinzufügen von zahlen. Nun fügen wir eine weitere Schwäche test für diesen Fall, die Nutzung der assertRaises Methode zu testen, ob eine Ausnahme ausgelöst wird, hier:

1
import unittest
2
from app.calculator import Calculator
3
4
5
class TddInPythonExample(unittest.TestCase):
6
7
    def setUp(self):
8
        self.calc = Calculator()
9
10
    def test_calculator_add_method_returns_correct_result(self):
11
        result = self.calc.add(2, 2)
12
        self.assertEqual(4, result)
13
14
    def test_calculator_returns_error_message_if_both_args_not_numbers(self):
15
        self.assertRaises(ValueError, self.calc.add, 'two', 'three')
16
17
18
if __name__ == '__main__':
19
    unittest.main()

Sie können sehen, von oben, fügten wir den test und sind jetzt die Prüfung für ein ValueError ausgelöst werden, wenn wir den pass in die Saiten. Wir könnten auch mehr Kontrollen für die anderen Arten, aber für jetzt, wir werden die Dinge einfach halten. Sie können auch feststellen, dass wir haben Gebrauch gemacht von der Methode setup (). Dies ermöglicht uns, die Dinge im Ort, die vor jedem Testfall. So, wie wir unsere Rechner-Objekt zur Verfügung stehen in beiden Testfällen, macht es Sinn, initialisieren Sie diese in der setUp-Methode. Mal sehen, was nosetest zeigt uns nun:

1
$ nosetests test_calculator.py
2
.F
3
======================================================================
4
FAIL: test_calculator_returns_error_message_if_both_args_not_numbers (test.test_calculator.TddInPythonExample)
5
----------------------------------------------------------------------
6
Traceback (most recent call last):
7
  File "/Users/user/PycharmProjects/tdd_in_python/test/test_calculator.py", line 15, in test_calculator_returns_error_message_if_both_args_not_numbers
8
    self.assertRaises(ValueError, self.calc.add, 'two', 'three')
9
AssertionError: ValueError not raised
10
11
----------------------------------------------------------------------
12
Ran 2 tests in 0.001s
13
14
FAILED (failures=1)

Klar, nosetests zeigt uns, dass wir nicht die Erhöhung der ValueError, wenn wir erwarten, zu sein. Jetzt haben wir eine neue test fehlschlägt, können wir den code der Lösung übergeben.

1
class Calculator(object):
2
    def add(self, x, y):
3
        number_types = (int, long, float, complex)
4
5
        if isinstance(x, number_types) and isinstance(y, number_types):
6
            return x + y
7
        else:
8
            raise ValueError

Aus dem code oben, Sie können sehen, dass wir Hinzugefügt haben, eine kleine Ergänzung zu überprüfen, die Typen der Werte sind und ob Sie mit dem übereinstimmen, was wir wollen. Ein Ansatz für dieses problem könnte bedeuten, dass Sie Folgen, duck-typing, und einfach versuchen, es zu benutzen, als eine Zahl, und die "try-except" die Fehler, die ausgelöst werden würde, in anderen Fällen. Das oben ist ein bisschen von einer Kante-Fall und bedeutet, dass wir überprüfen müssen, bevor Sie fortfahren. Wie bereits erwähnt, strings verkettet werden kann mit der " plus-symbol, so dass wir nur zulassen wollen zahlen. Die Nutzung der isinstance Methode ermöglicht es uns, um sicherzustellen, dass die bereitgestellten Werte können nur zahlen sein.

Zum Abschluss der Prüfung, es gibt ein paar verschiedene Fälle, die wir hinzufügen können. Da es zwei Variablen, bedeutet dies, dass sowohl potenziell nicht zahlen. Fügen Sie die test-Fall-Abdeckung aller Szenarien.

1
import unittest
2
from app.calculator import Calculator
3
4
5
class TddInPythonExample(unittest.TestCase):
6
    def setUp(self):
7
        self.calc = Calculator()
8
9
    def test_calculator_add_method_returns_correct_result(self):
10
        result = self.calc.add(2, 2)
11
        self.assertEqual(4, result)
12
13
    def test_calculator_returns_error_message_if_both_args_not_numbers(self):
14
        self.assertRaises(ValueError, self.calc.add, 'two', 'three')
15
16
    def test_calculator_returns_error_message_if_x_arg_not_number(self):
17
        self.assertRaises(ValueError, self.calc.add, 'two', 3)
18
19
    def test_calculator_returns_error_message_if_y_arg_not_number(self):
20
        self.assertRaises(ValueError, self.calc.add, 2, 'three')
21
22
23
if __name__ == '__main__':
24
    unittest.main()

Wenn wir alle diese tests jetzt können wir bestätigen, dass die Methode, die unseren Anforderungen entspricht!

1
$ nosetests test_calculator.py
2
....
3
----------------------------------------------------------------------
4
Ran 4 tests in 0.001s
5
6
OK

Andere Unit-Test-Pakete

py.test

Dies ist ein ähnlicher test runner zu nosetest werden, welche die gleichen Konventionen, was bedeutet, dass Sie können führen Sie Ihre tests in einer der beiden. Ein nettes feature von pytest ist, dass es erfasst Ihren Ausgang aus dem test unten in einem separaten Bereich, das heißt, Sie können schnell sehen, nichts gedruckt auf der Kommandozeile (siehe unten). Ich habe festgestellt, pytest, um nützlich zu sein bei der Ausführung einzelner tests, im Gegensatz zu einer suite von tests.

Zum installieren der pytest Läufer, Folgen Sie den gleichen pip installieren Sie die Prozedur, die Sie Folgen, um zu installieren nosetest. Einfach ausführen $ pip install pytest und es wird greifen die neueste version und installieren Sie auf Ihrem Computer. Sie können dann führen Sie den Läufer gegen Ihre suite von tests, indem Sie das Verzeichnis der test-Dateien, $ py.test/, oder Sie können geben Sie den Pfad zu der test-Datei, die Sie ausführen möchten: $ py.test test/calculator_tests.py.

1
$ py.test test/test_calculator.py
2
================================================================= test session starts =================================================================
3
platform darwin -- Python 2.7.6 -- py-1.4.26 -- pytest-2.6.4
4
collected 4 items 
5
6
test/test_calculator.py ....
7
8
============================================================== 4 passed in 0.02 seconds ===============================================================

Ein Beispiel pytest die Ausgabe beim drucken in tests oder code ist unten dargestellt. Dies kann nützlich sein, um schnell Debuggen von tests und sehen, einige der Daten, die es zu manipulieren. HINWEIS: wird nur angezeigt, Ausgabe der code auf Fehler oder Ausfälle in Ihren tests, sonst pytest unterdrückt jegliche Ausgabe.

1
$ py.test test/test_calculator.py 
2
================================================================= test session starts =================================================================
3
platform darwin -- Python 2.7.6 -- py-1.4.26 -- pytest-2.6.4
4
collected 4 items 
5
6
test/test_calculator.py F...
7
8
====================================================================== FAILURES =======================================================================
9
________________________________________ TddInPythonExample.test_calculator_add_method_returns_correct_result _________________________________________
10
11
self = <test.test_calculator.TddInPythonExample testMethod=test_calculator_add_method_returns_correct_result>
12
13
    def test_calculator_add_method_returns_correct_result(self):
14
        result = self.calc.add(3, 2)
15
>       self.assertEqual(4, result)
16
E       AssertionError: 4 != 5
17
18
test/test_calculator.py:11: AssertionError
19
---------------------------------------------------------------- Captured stdout call -----------------------------------------------------------------
20
X value is: 3
21
Y value is: 2
22
Result is 5
23
========================================================= 1 failed, 3 passed in 0.03 seconds ==========================================================

UnitTest

Python eingebaute unittest Paket, das wir verwendet haben, erstellen unsere tests wirklich durchgeführt werden, sich selbst, und gibt schöne Ausgabe. Dies ist nützlich, wenn Sie nicht möchten, installieren Sie alle externen Pakete und halten alles rein, um die standard-Bibliothek. Um es zu verwenden, fügen Sie einfach den folgenden block am Ende der test-Datei.

1
if __name__ == '__main__':
2
    unittest.main()

Führen Sie den test mit python calculator_tests.py. Hier ist die Ausgabe, die Sie erwarten können:

1
$ python test/test_calculator.py 
2
....
3
----------------------------------------------------------------------
4
Ran 4 tests in 0.004s
5
6
OK

Debug-Code Mit dem HVE

Oft, wenn Sie die folgenden TDD, werden Sie Probleme mit Ihrem code und den tests scheitern. Es gibt Fälle, wo, wenn Sie Ihre tests fehlschlagen, wird es nicht sofort offensichtlich ist, warum das passiert ist. In solchen Fällen wird es notwendig sein, gelten einige debugging-Techniken, um Ihren code zu verstehen, wie genau der code ist Manipulation der Daten und nicht immer die genaue Antwort oder Ergebnis, das Sie erwarten.

Es gibt Fälle, wo, wenn Sie Ihre tests fehlschlagen, wird es nicht sofort offensichtlich ist, warum das passiert ist

Glücklicherweise, wenn Sie finden, sich selbst in eine solche position, es gibt ein paar Ansätze, die Sie ergreifen können, um zu verstehen, was der code tut und das Problem beheben, um Ihre tests übergeben. Die einfachste Methode, und viele Anfänger beim ersten schreiben von Python-code, ist das hinzufügen von print-Anweisungen an bestimmten Punkten in Ihrem code und sehen, was Sie ausgegeben, wenn die Durchführung von tests.

Debuggen Mit Print-Anweisungen

Wenn Sie bewusst verändern unsere Rechner code so, dass es fehlschlägt, können Sie bekommen eine Vorstellung davon, wie das Debuggen von code funktioniert. Ändern Sie den code in der add-Methode der app/calculator.py tatsächlich subtrahieren Sie die beiden Werte.

1
class Calculator(object):
2
    def add(self, x, y):
3
        number_types = (int, long, float, complex)
4
5
        if isinstance(x, number_types) and isinstance(y, number_types):
6
            return x - y
7
        else:
8
            raise ValueError

Beim ausführen des tests jetzt, den test, die prüft, ob der add-Methode richtig gibt vier beim hinzufügen von zwei plus zwei nicht, da es jetzt 0 zurück. Um zu überprüfen, wie es ist zu erreichen mit diesem Abschluss, könnten Sie fügen Sie einige print-Anweisungen, um zu überprüfen, dass es den Erhalt der beiden Werte richtig und dann überprüfen Sie die Ausgabe. Dies würde dann dazu führen, Sie zu schließen, die eine Logik für die addition der beiden zahlen ist falsch. Fügen Sie die folgenden print-Anweisungen, um den code in app/calculator.py.

1
class Calculator(object):
2
    def add(self, x, y):
3
        number_types = (int, long, float, complex)
4
5
        if isinstance(x, number_types) and isinstance(y, number_types):
6
            print 'X is: {}'.format(x)
7
            print 'Y is: {}'.format(y)
8
            result = x - y
9
            print 'Result is: {}'.format(result)
10
            return result
11
        else:
12
            raise ValueError

Nun, wenn Sie ausführen nosetest gegen die Prüfungen, die es schön zeigt Ihnen die erfassten Ausgang für den ausgefallenen test, geben Ihnen eine chance, das problem zu verstehen und korrigieren Sie den code, um die addition statt Subtraktion.

1
$ nosetests test/test_calculator.py
2
F...
3
======================================================================
4
FAIL: test_calculator_add_method_returns_correct_result (test.test_calculator.TddInPythonExample)
5
----------------------------------------------------------------------
6
Traceback (most recent call last):
7
  File "/Users/user/PycharmProjects/tdd_in_python/test/test_calculator.py", line 11, in test_calculator_add_method_returns_correct_result
8
    self.assertEqual(4, result)
9
AssertionError: 4 != 0
10
-------------------- >> begin captured stdout << ---------------------
11
X is: 2
12
Y is: 2
13
Result is: 0
14
15
--------------------- >> end captured stdout << ----------------------
16
17
----------------------------------------------------------------------
18
Ran 4 tests in 0.002s
19
20
FAILED (failures=1)

Erweiterte Debug Mit dem HVE

Als Sie anfangen zu schreiben, erweiterte code -, print-Anweisungen allein werden nicht ausreichen, oder beginnen zu langweilig zu schreiben, die alle über dem Platz und müssen gereinigt werden, bis später. Als der Prozess benötigen, um debug alltäglich geworden beim schreiben von code, die Werkzeuge entwickelt haben, um Debuggen von Python-code einfacher und interaktiver.

Eines der am häufigsten verwendeten Werkzeuge ist pdb (oder Python Debugger). Das tool ist enthalten in der standard-Bibliothek und erfordert lediglich das hinzufügen einer Zeile, wo Sie möchten, um das Programm zu stoppen Ausführung und geben Sie in die pdb, normalerweise bekannt als "Haltepunkt". Mit unseren fehlerhaften code in der add-Methode, versuchen Sie die folgende Zeile hinzufügen, bevor Sie die beiden Werte subtrahiert werden.

1
class Calculator(object):
2
    def add(self, x, y):
3
        number_types = (int, long, float, complex)
4
5
        if isinstance(x, number_types) and isinstance(y, number_types):
6
            import pdb; pdb.set_trace()
7
            return x - y
8
        else:
9
            raise ValueError

Wenn Sie mit nosetest, um den test auszuführen, werden Sie sicher zu führen mit dem -s flag, das sagt nosetest nicht erfassen, standard-Ausgabe, ansonsten wird Ihr test wird nur hängen und nicht geben Sie die pdb-prompt. Mit dem standard-unittest-Läufer und pytest erfordert nicht einen solchen Schritt.

Mit dem pdb-code-snippet in Ort, wenn Sie führen Sie den test jetzt, die Ausführung des code bricht an der Stelle an der Sie platziert die pdb-Linie, und ermöglichen Ihnen die Interaktion mit der code und Variablen, die geladen werden wie an der Stelle, der Ausführung. Wenn die Ausführung zunächst beendet, und Sie sind angesichts der pdb-prompt, geben Sie die Liste, um zu sehen, wo Sie in den code und in welcher Zeile Sie sind derzeit auf.

1
$ nosetests -s
2
> /Users/user/PycharmProjects/tdd_in_python/app/calculator.py(7)add()
3
-> return x - y
4
(Pdb) list
5
  2          def add(self, x, y):
6
  3  	        number_types = (int, long, float, complex)
7
  4  	
8
  5  	        if isinstance(x, number_types) and isinstance(y, number_types):
9
  6  	            import pdb; pdb.set_trace()
10
  7  ->	            return x - y
11
  8  	        else:
12
  9  	            raise ValueError
13
[EOF]
14
(Pdb) 

Sie können interagieren mit Ihrem code, wenn Sie waren innerhalb einer Python-Eingabeaufforderung, und so versuchen, zu evaluieren, was in den x-und y-Variablen an dieser Stelle.

1
(Pdb) x
2
2
3
(Pdb) y
4
2

Sie können weiterhin zu "spielen", um mit dem code, wie Sie benötigen, um herauszufinden, was falsch ist. Sie können geben Sie Hilfe in jedem beliebigen Punkt, um eine Liste der Befehle, aber das core set werden Sie wahrscheinlich benötigen, sind:

  • n: Schritt vorwärts zur nächsten Zeile bei der Ausführung.
  • Liste: zeigen fünf Zeilen jeder Seite, wo Sie derzeit ausführen, um zu sehen, den code beteiligt, die mit der aktuellen Ausführung zeigen.
  • args: eine Liste der Variablen, die in der aktuellen Ausführung zeigen.
  • fortfahren: führen Sie den code bis zur Fertigstellung.
  • springen : führen Sie den code bis zur angegebenen Zeilennummer.
  • quit/beenden: stop pdb.

Fazit

Test-Driven Development ist ein Prozess, der sowohl Spaß an der Praxis, und äußerst vorteilhaft für die Qualität Ihrer Produktion code. Seine Flexibilität in Ihrer Anwendung auf alles, was von großen Projekten mit vielen team Mitgliedern rechts hinunter zu einem kleinen solo-Projekt bedeutet, dass es ist eine fantastische Methodik zu befürworten, um Ihr team.

Ob pair programming oder die Entwicklung von sich selbst, der Prozess der Herstellung einer fehlerhaften Testdurchlauf ist äußerst befriedigend. Wenn du schon immer argumentiert, dass die tests waren nicht notwendig, hoffentlich ist dieser Artikel hat schwankte Ihr Ansatz für zukünftige Projekte.

Machen TDD ein Teil Ihres täglichen workflow heute.

Heads-Up!

Wenn Sie diesen Artikel Ihren Appetit geweckt hat für die Welt der Tests in Python, warum nicht überprüfen Sie heraus das Buch "Testing Python", geschrieben von dem Artikel, Autor und veröffentlicht auf Amazon und anderen guten Händler vor kurzem. Besuchen Sie diese Seite um kaufen Sie Ihr Exemplar von das Buch heute, und unterstützen Ihre Tuts+ Mitwirkende.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.