unittest was ist das?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
sonium
User
Beiträge: 66
Registriert: Mittwoch 27. Oktober 2004, 21:04

Irgendwie hab ich schon öfters davon gehört, aber kann damit nicht recht was anfangen. Zwar weiß ich jetzt, dass es eine Vorgehensweise ist kleinere Codeabschnitte seperat zu testen, hab aber keine Ahnung wie das gehen soll. http://agiletesting.blogspot.com/2005/0 ... ttest.html ist ziemlich unverständlich (finde ich). Eine Testklasse abzuleiten um dann alle Methoden zu überschreiben soll die Orginalklasse testen?

evtl kennt jemand ein besseres Tutorial, das auch mal erklärt warum man das so macht.
- http://bash.org/?400459
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Unit-Tests sind eine tolle Methode von Extreme Programming (XP). Es geht darum, dass du parallel zu dem Code den du schreibst, auch Tests schreibst, welche die soeben implementierten Funktionen testen.

Optimal ist es so, dass du erst Unittests schreibst und dann die Funktionen, die diese Unittests erfüllen.

Das sieht dann so aus: Du willst eine Funktion schreiben, die das Doppelte von der angegebenen Zahl zurückgibt. Also schreibst du erst einen Unittest, der beispielsweise die Funktion mit dem Wert 2 füttert, und der 4 als Ergebnis erwartet. Nun schreibst du einen weiteren Test, der den String "a" der Funktion übermittelt und testest ob die Funktion einen ValueError ausgibt. Wenn du die Unittest laufen lässt, dann stellst du fest, dass deine Funktion beide Tests nicht besteht, da es sie noch nicht gibt. Also schreibst du eine Funktion die return wert * 2 ausgibt. Dann startest du den test von neuem und stellst fest, dass sie den ersten Test erfüllt, den zweiten jedoch nicht. Nun erweiterst du die Funktion so, dass sie auch den zweiten Test erfüllt und du bist ferig. Oder du schreibst mehr Tests, die die Funktion auf Herz und Nieren prüft.

Test-first Programming (also Unittests schreiben und dann erst den Code) bietet den Vorteil, dass du die API deiner Funktionen so definierst wie du sie brauchst und dann die Funktionen so machst, dass sie die API bereitstellen. Dadurch vermeidest du, dass sich die API ändert, weil sie vorher schlecht war: die API ist von Anfang an so, wie sie sein sollte. Ein weiterer Vorteil ist, dass wenn du eine Funktion änderst und die Unittests ausführst udn diese Funktion nach der änderung noch genausogut Funktioniert wie vorher, dann hast du keine neuen Fehler eingeführt. Das hängt natürlich auch von der Qualität der Unit-Tests ab.

Einen guten Einstieg bietet Dive Into Python, beginnend mit
Kapitel 13 (Unit testing).

Ich muss sagen, dass ich Unit-Tests viel zu selten schreibe, das gebe ich zu, denn dazu muss man doch auch einiges an Durchhaltevermögen haben. Aber es lohnt sich.

Neben dem in dem Artikel vorgestelltem Modul unittest und dem ebenfalls in Pyhton mitgeliefertem doctest gibt es noch py.test. Alle drei wurden von Grig Gheorghiu verglichen, jedoch gibt es noch TurboGears' TestGears, welches vermutlich in TurboGears 0.9 von nose ersetzt wird.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
sonium
User
Beiträge: 66
Registriert: Mittwoch 27. Oktober 2004, 21:04

ok, ist ja ganz hilfreich. Allerdings auch ne menge zusätzlicher Aufwand. Am meisten bringt es wohl wenn man mit mehreren Leuten an einem Projekt arbeitet. Allerdings find es schwierig sinnvolle Tests zu entwerfen. Gibts dazu irgendwelche Richtlinien? (außer jetzt dass jeder test nur eine Bedingung testet)
- http://bash.org/?400459
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hi,

auch ich muß zugeben, daß ich unittest nicht konsequent genug einsetzte, aber dennoch ist es für mich verdammt nützlich. Und ich arbeite meist alleine für mich.
Richtlinien kenne ich keine, allerdings 1001 wohlgemeinten Ratschlag. Schau einmal die links von Leonidas durch, da wirst Du schon einige solche Ratschläge finden. Aber letztlich wirst Du feststellen, daß niemand Dir hierbei Dein Hirnschmalz streichen wird - das mußt Du schon selber reinstecken :wink: .
Wie so oft wächst auch die Qualität Deiner unittests durch das wiederholte Schreiben dieser Dinger. Das ist manchmal gar nicht so einfach. Aber am Ende sparst Du schon Zeit - zumindest, wenn es sich nicht um kurze Skripte, sondern um ausgewachsene Programme handelt, die Du schreiben willst.

Viel Erfolg,
Chrisitian
Gast

und auch schon das erste problem:
wie soll ich für sowas nen Testcase schreiben:

Code: Alles auswählen

from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor

class QOTD(Protocol):

    def connectionMade(self):
        self.transport.write("An apple a day keeps the doctor away\r\n") 
        self.transport.loseConnection()


# Next lines are magic:
factory = Factory()
factory.protocol = QOTD

# 8007 is the port you want to run under.
reactor.listenTCP(8007, factory)
reactor.run()
ich will testen, ob wenn am port 8006 connected wird die entsprechende Meldung zurück geben wird.
Ich würde jetzt einen entsprechenden client schreiben, der eben diesen Vorgang ausführt. Aber ich denke nicht, dass das der Idee von Unittest entspricht.
mbierenfeld
User
Beiträge: 39
Registriert: Donnerstag 9. Dezember 2004, 22:02
Wohnort: Muenchen

Bei UnitTests gilt.

_ TestCases haben keine externen Abhängigkeiten !!! _

MockObjecte helfen da weiter siehe :

http://python-mock.sourceforge.net/

Grüße

Michael

PS: Ich bin da auch nicht immer konsequent. _Schwitz_
sonium
User
Beiträge: 66
Registriert: Mittwoch 27. Oktober 2004, 21:04

hab jetzt einfach die zu testende funktion ausgegliedert, denke das ist legitim.


server.py

Code: Alles auswählen

from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor

def write():
    return "An apple a day keeps the doctor away\r\n"

class QOTD(Protocol):

    def connectionMade(self):
        self.transport.write(write()) 
        self.transport.loseConnection()


# Next lines are magic:
factory = Factory()
factory.protocol = QOTD

if __name__ == "__main__":
    # 8007 is the port you want to run under.
    reactor.listenTCP(8007, factory)
    reactor.run()

servertest.py

Code: Alles auswählen

import server
import unittest

class testWrite(unittest.TestCase):
    def testReturnValue(self):
        result = server.write()
        self.assertEqual(result, "An apple a day keeps the doctor away\r\n")

if __name__ == "__main__":
    unittest.main()
- http://bash.org/?400459
Antworten