Ja, hallo und herzlich willkommen zum Python-Podcast in der 24. Episode.
Heute geht es bei uns um Tests und wir haben wieder einen Gast, der Ronny ist da.
Hi, Ronny, hallo.
Und der Jochen natürlich auch.
Ja, ich bin auch da.
Ja, schön, dass ihr alle wieder eingeschaltet habt.
Und Ronny, erzähl doch mal von was sind die? Möchte ich einmal kurz vorstellen.
Ja, ich heiße Ronny Vidrilia, ich arbeite in Köln bei AIM Innovation.
Bin da jetzt seit einem Jahr ganz offiziell Tech-Evangelist für Django.
und habe jetzt meine acht Jahre, die ich da bin,
auch Großteils mit Backend-Arbeiten
und Django verbracht,
habe in Köln
Wirtschaftsinformatik studiert, also eigentlich
eher so ein Beraterstudiengang, aber ich hatte immer mehr
Spaß eigentlich am entwickelnden
Beraten, beziehungsweise
Beratung mit Entwicklung zusammen.
Kann ich ja gar nicht verstehen.
Und
genau,
habe dann,
wir haben uns eigentlich kennengelernt, du warst Pai Cologne
oder Düsseldorfer?
und du hast dann dieses Meetup ausgerichtet, das Django-Meetup in Köln.
Kannten wir uns nicht vorher schon?
Ja, wir haben uns auf irgendeinem der
Pycolons mal gefragt.
Pycolon bestimmt, haben wir uns bestimmt schon mal gesehen.
Genau, und wie Dominik
gerade schon gesagt hat,
seit, ja, jetzt glaube ich
im knappen Jahr
richten wir bei uns im Büro, bei Ambient
das Django-Meetup Köln aus
und
genau,
da sind die beiden auch immer
regelmäßige Gäste
Ja, also bis Corona all das verunmöglicht hat sozusagen.
Also na gut, es gibt halt das virtuelle Meetup und ja, genau.
Das ist ganz das Gleiche. Ich fand es auch immer schön, die Leute live zu sehen.
Apropos live sehen, wir haben heute tatsächlich eine Testvorhörer, die einen Test macht.
Und zwar sind wir zum ersten Mal nicht im Wintergarten, sondern diesmal draußen und sitzen in einem Restaurantgarten.
Wir waren auch schon mal woanders, aber wir waren noch nie draußen.
Ja, genau. Und das ist jetzt quasi das erste Mal live vor Ort draußen.
also entschuldige mir so ein bisschen die Hintergrundgeräusche das ist ein bisschen urbanes Leben
genau
schreibt da gerne mal Feedback zu
klingt das ganz schrecklich furchtbar oder kann man damit halbwegs leben
ich meine das ist natürlich angenehm, also gerade wenn es warm ist
irgendwie eher draußen zu sitzen
ein bisschen was kühleres zu trinken
das ist natürlich schon sehr viel angenehmer als jetzt
Dankeschön
naja
die Werte sind zu voll
ja aber
eben wenn man in so einem kleinen Raum sitzt
das ist ja immer das Problem mit der Akustik, man braucht entweder einen kleinen Raum
und Jochen unterhalten sich über die Programmiersprache Python
Ja, aber du kannst gerne noch mal ein bisschen
über die Gerätschaften erzählen, du machst ja schon letztes Mal
irgendwie... Naja, das ist jetzt einfach
so ein Zoom H6, das ist halt so ein
ja, Field Recorder,
das wird es beworben, das hat halt auch
so XLR-Eingänge für Mikrofone, macht
Phantomspeisung und
dann ist da noch so ein
Kopfhörerverstärker dran,
wo dann halt die Ausgänge, die alle das gleiche
Line-Out-Signal von dem H6 kriegen,
nochmal dranhängen, damit man sich auch selber und die anderen hören kann.
Und genau, also
Was wirklich eine tolle Kombination ist, ist halt sozusagen die Standard-Podcaster-Konfiguration zur Zeit, glaube ich, die die meisten Audioqualität bietet für Geld, ist halt so ein Zoom H6 plus irgendwie diese HMC 660X oder C, keine Ahnung, Headsets, weil man kann an dem Zoom H6 nämlich auch 12 Volt Phantomspeisung einstellen.
Ja, muss nicht löten.
Und braucht keinen Adapter oder so und die Dinger funktionieren einfach an dem Ding direkt, was halt bei den meisten professionellen Audiointerfaces nicht geht.
und Jochen unterhalten sich über die Programmiersprache Python
Ja, weil der erste Artikel war von ihm.
Ich habe es auch gesehen.
Ich hatte ja schon intern vorher mitbekommen, dass du einen Artikel geschrieben hast.
Nicht schlecht.
Ja, was mich...
Also tatsächlich hat das...
Jochen will gerade von einer Wespe bearbeiten.
Die kriegt gerade über seinen Brillenglas.
Jochen mag Insekten sehr gerne, wie ich schon mitbekommen durfte.
Aber er bleibt relativ entspannt.
Also ehrlich gesagt, die Insekten mögen mich mehr als sie, finde ich.
die Ohren gehauen, das ist unglaublich.
Er meinte, das geht gar nicht und hat dann 15 oder 16 Seiten
drangehängt, wie man es richtig macht.
Danke, Jochen.
Ja, aber ich wollte das eigentlich alles gar nicht.
Aber manchmal braucht man halt auch
einen Anstoß, um das dann zu machen und
Handwände damit und ja gut, jetzt ist es draußen
und gut. Also insofern,
ja, also viel Arbeit und irgendwas
stecken hilft, wenn das
irgendwie mal weiterhilft.
Ja, genau.
Ach, es gab noch eine neue
ein Release-Kandidat
für Python 3.9.
Den ersten gibt es jetzt.
Und Leute, die das
verwenden, haben schon gesagt,
das funktioniert eigentlich alles ganz fluffig.
Was sind denn die Neueren von Python 3.9?
Wir haben das bestimmt schon mal besprochen.
Wir haben jetzt auch kein Recht an den...
Wir können das nicht einfach
online
recherchieren.
Das geht gerade eben nicht.
Aber ansonsten, weiß nicht, sonst irgendwelche Neuigkeiten?
Ist dir was eingefallen?
Nein, außer Django 3.1
was ich jetzt auch schon nutze
funktioniert gut, Jason's Feeds sind super
Mir fällt noch was ein und zwar ist
von Daniel Roy Fieldroy das Buch
Two Scopes of Django in der Version 3
hat er gestern Abend sein Twitch-Kanal
hochgefahren, weil es jetzt offiziell
Release-Zone ist. Ah, okay, ich hatte es schon
gekauft, aber immer die Updates nur gesehen
nur die dann nie, weil ich dachte, ach ich warte auf die
fertige Release, wenn ich jetzt weiß, dass es Release ist, super
dann hole ich mir mal den. Ganz genau, das war
gestern Abend.
Ah, sehr schön.
Ja, nö, ansonsten, genau,
können wir dann vielleicht direkt mit dem echten
Thema einsteigen.
Ja, wollen wir vielleicht einen kurzen Überblick geben? Also ich glaube, wir reden einfach
los, wie immer, über Tests und so ein bisschen
mehr Tests und Tests und Tests und Tests
und der Test funktioniert mit den Tests.
Mögt ihr Tests?
Jochen?
Ja, also ich habe lange
Zeit, ich habe früher
die Leute, die so anfingen mit TDD oder so.
Ich finde Tests total furchtbar.
Das hat dann irgendwie, als ich noch keinen Test geschrieben habe, oder noch nicht so viele,
da habe ich so ein bisschen über diese Leute immer gelächelt.
Ah ja, die mit ihrem komischen statischen Dings da, Java und so, und Testschreiben, höhö.
Das mache ich alles einfach mal so eben aus der Hand.
Mein Code ist so perfekt, den braucht man gar nicht.
Einfach keine Fehler machen, sei es das.
Genau, das ist alles kein Problem.
Und dann irgendwann dachte ich so, okay, ich bin vielleicht einfach nicht so der Typ für längere Programme.
Ich schreibe gerne so kurze Sachen, die so auf eine Bildschirmseite gehen oder vielleicht ein bisschen länger sind,
aber habe das nie so reflektiert, woran das eigentlich liegt.
Und dann, als ich irgendwann angefangen habe, Tests zu schreiben, weil das halt in irgendeinem Projekt dann erforderlich wurde,
merkte ich so, oh, ach, ich kann ja vielleicht doch leckere Programme schreiben.
Mit Tests geht das plötzlich.
Das ist halt, man kann sich quasi ausruhen.
Entweder man hält halt den kompletten State im Kopf und weiß dann halt, dass man wahrscheinlich keine Fehler gemacht haben wird,
weil man das halt weiß, wie jeder einzelne Teil funktioniert.
und miteinander interagiert oder wenn man das halt nicht mehr wissen kann, weil es einfach zu viel wird,
dann braucht man halt Tests, ansonsten passieren schreckliche Dinge.
Das ist halt einfach so.
Oder halt auch für Refactoring.
Das ist halt auch immer ein Riesenargument für Tests.
Okay.
Magst du Tests, Jonny?
Ja.
Ich muss gestehen, wenn ich unter Zeitdruck viel entwickeln muss,
dann ärgere ich mich manchmal nachher, dass da noch so viele Tests übrig bleiben,
die man schreiben muss.
Aber generell finde ich es eine super Sache.
und wie gesagt, allein schon wegen Refactoring. Ich arbeite an mehreren
Django-Projekten, die jetzt schon Jahre laufen und ich weiß,
wie mühsam das früher war, als wir noch keine Tests da drin hatten
und wie unmöglich es war, irgendwelche Sachen anzufassen,
ohne dass man nachher Stunden, am besten tagelang...
Genau, vor allem dann so zerbrechliche Sachen, wie
man hat dann zum Beispiel eine Überstundenerfassung oder sowas gebaut und da dann
und Jochen unterhalten sich über die Programmiersprache Python
und die Programmiersprache Python.
Also ich meine, es gibt ja das berühmte Pareto-Prinzip, 80-20-Regel und ich glaube, wenn man versucht, 100% der Sachen abzudecken, ich glaube, es gibt einfach Dinge, da ist einfach der Overhead so viel größer, dafür irgendwie Tests zu bauen, dass man da, glaube ich, einfach riskieren kann, dass gewisse Dinge vielleicht einfach mal in die Hose gehen dürfen.
Es wird auch so starr, also wenn du halt ganz, ganz, ganz viel testest, dann kannst du eigentlich ja nichts mehr ändern, ohne dass irgendein Test fehlschlägt. Ich meine, du merkst dann zwar, was dann fehlgeschlagen ist vielleicht, aber das macht einen doch sehr unbeweglich und du hast halt tatsächlich auch, wenn du refactoren willst, wie du eben sagtest, Ronny, das Problem, dass du ganz, ganz viele Sachen und die Tests anfassen musst, weil vielleicht auch die Tests dann refactored werden müssen.
an. Ja, also ich würde auch
denken, es kommt halt auf den Anwendungsfall an, also wenn du halt
irgendwie eine kleine Webseite hast, die
irgendwas, keine Ahnung, für dich
und ein paar Freunde irgendwie macht,
dann braucht man vielleicht keine Tests, weil wenn irgendwas schief geht, dann
fixt man das halt und es hat ja keinen gestört,
dass es irgendwie schief gegangen ist.
Steuerprogramm vom AKW,
bräuchte vielleicht ein paar mehr Tests. Genau,
da würde man sich dann vielleicht freuen, wenn die
bemerken, dass etwas schief läuft, bevor es irgendwie
die ganze Region mit in den Abgrund reißt,
aber genau, und da braucht man halt
vielleicht viele und gute Tests und
und ja, also
ich meine, nur ein paar
Integrationstests zu haben, ist ja auch schon mal
auf jeden Fall besser als keine Tests zu haben, auch die fangen
natürlich dann schon Sachen, auf der anderen Seite
ja, es ist schwierig, das mit den Metriken
ist immer so eine Sache, ich meine, es ist
auf jeden Fall immer auch besser, irgendwas zu messen als nichts zu messen
und dass man irgendwas hat, worauf man optimieren
kann, aber gerade wenn man jetzt so
schlechte Tests schreibt, dann
kriegt man mit denen oft eine gute Testabdeckung
hin und hoch, weil man macht
so viele Integrationstests, die ganz viel
Code aufrufen
und, aber eigentlich
sind die halt eher nicht so toll, weil
die sind halt langsam und
dann, die
sind auch schwer zu ändern, wenn man
dann Code ändert und
was heißt das eigentlich 100% Test
Coverage, ich meine die Brand Coverage ist
ja auch nochmal vielleicht so eine Geschichte, das geht jetzt übrigens mit der
neuesten,
Version 5 von Coverage, geht das
auch, dass man halt dem sagen kann,
sag mir doch mal, wie viel von den
If-Verzweigungen, also es reicht
nicht, dass das einmal drüber gelaufen ist, sondern
um auch ob die
tatsächlich beide Pfade genommen haben
ob irgendein Test getestet hat, ob beide Pfade genommen werden
und dann
sieht es halt schon anders aus und ich weiß
dass es Leute gibt, die dann sowas sagen wie
naja, das geht auch mit CubbyTree das auch
dass man sagt, man kann auch zu jedem
Pfeil angeben, welches
andere Pfeil für die Abdeckung
verantwortlich sein soll, also wenn man jetzt zum Beispiel
im Django-Projekt Models
py-Pfeil hat, dann
sagt man, okay, da
soll die Abdeckung
gewährleistet werden von Testmodels
QI und die
Abdeckung, die daher kommt, dass das aus irgendwelchen
anderen Integrationstests
heraus auch aufgerufen wird,
das zählt nicht. Weil ansonsten
kannst du halt mit fetten Integrationstests deine
Coverage hochbringen, aber
eigentlich ist das überhaupt nicht das, was du haben willst, sondern was du
eigentlich haben willst, ist, dass du sicher sein kannst, wenn du
jetzt was änderst, dass du
tatsächlich nichts damit kaputt gemacht hast
und das kriegst du gerade bei diesen
dicken Tests ja gar nicht so richtig mit.
Also außer du hast das wirklich gravierendes kaputt gemacht.
Ja, okay, wir sind durch mit Tests.
Nee, nee.
Ja, keine Ahnung, aber wie ist das denn praktisch?
Wann habt ihr denn mit Testen angefangen?
Ich glaube, ihr macht ja bei euch ganz viel Django schon lange.
Genau.
Und habt ihr von Anfang an Tests verwendet?
Tatsächlich nein.
Ich meine, die Sinnhaftigkeit von Tests war uns natürlich schon klar,
und Jochen unterhalten sich über die Programmiersprache Python
genau das Gegenteil von TDD, also sprich
du schreibst das bei deinem Code und danach schreibst du die Tests
und das ist ja quasi ein Mehrwert für den Kunden, weil die
Software dann besser funktioniert
und haben dann halt sehr idealistisch versucht dem Kunden das
zu verkaufen
und selbst bei technisch
affineren Kunden war dann halt
relativ schnell immer die Aussage, naja
es soll ja funktionieren und wenn es kaputt
geht ohne Tests, dann müsste es ja trotzdem
ganz machen und sparen wir Geld, weil wir die Tests nicht
bezahlen und
das war dann bei uns so ein
gewisses Learning, bis wir dann einfach
Ich würde das ja den Kunden lernen lassen.
Weil der Kunde auf die Nase fällt
und du kannst ihm das vorher erzählen und er bezahlt es halt nicht.
Dann fällt es halt auf die Nase.
Man steht halt da ein bisschen blöd da.
Das ist schon richtig.
Viele, die ich so mitbekommen habe,
an kleineren Kunden vor allen Dingen,
die dann sagten, jetzt können wir es nicht leisten,
den Test machen wir jetzt nicht.
Die kamen dann irgendwann reumütig zurück.
Ja, wir haben jetzt ein Software gebaut,
es wurde kein Test geschrieben, es funktioniert alles nicht mehr.
Vielleicht haben die selber irgendwas angefasst.
Da konnte irgendjemand von den Menschen aus der Firma
so ein bisschen Dango und hat dann irgendwas umgebaut
und irgendwas kaputt gemacht oder irgendwas anderes,
was ihm jetzt später aufgefallen ist.
Ich muss sagen, also dafür,
dass wir die ersten
Jahre, als wir noch ganz klein waren,
tatsächlich keinen Test geschrieben haben,
haben die Sachen trotzdem überraschend gut funktioniert.
Also es wundert mich rückblickend auch.
Ihr seid alle so gut.
Aber es ist echt überraschend.
Also wenn ich heutzutage, wo ich das mit den
Tests weiß, dann werde ich so schnell nervös, wenn ich
für irgendwas Kritisches keinen Test schreibe.
Naja, auf jeden Fall, wir haben dann halt irgendwann einfach gesagt, komm, das ist einfach Teil der Programmierarbeit, das steht nicht zur Debatte
und seitdem machen wir das und ja, ich glaube, der...
Habt ihr richtig so eine Struktur da drin?
Also wir haben jetzt keinen Coding-Guide in der Firma, also ich meine, jeder kann es im Endeffekt machen, wie er möchte.
Ich meine, natürlich haben wir halt diese typischen QA-Schritte wie Code Review, Content Review und sowas.
Das ist natürlich ganz klar, dass wenn dann jemand irgendwie der Meinung ist, dass irgendwie Tests so und so geschrieben gehören
und dass irgendeine wichtige Funktion nicht hinreichend getestet ist, dann kriegt man natürlich den Ball nochmal zurück.
Aber im Endeffekt gibt es da jetzt keine offizielle Guideline oder sowas, weil ich meine, wie es bei Python so schön heißt,
we are all adults here, also jeder weiß ja, was er macht und die Akzeptanz ist auch da.
und Python-Programmierung.
sodass man dann auch einfach
unterm Strich halt sehr viel Geld sparen kann, wenn Code
einfach maintained ist und vielleicht dann auch
getestet. Wir verkaufen das im Internen
mittlerweile als Security relevant.
Also wenn es keine Tests gibt,
dann ist ganz viel Sicherheitsdrucken da und muss da sicher
sein, dass das nicht...
Also ich bin mir nicht sicher, ob es da nicht inzwischen,
also wir hatten das Thema auch schon mal in der
Projektmanagement-Episode, aber ob da nicht tatsächlich
ein echter Interessenskonflikt
ist, weil es kann sein,
dass ich aus einer Wirtschaftssicht vielleicht
tatsächlich sage, okay,
für die Qualität bin ich nicht bereit zu bezahlen, weil ich hätte gerne lieber mehr Geschwindigkeit.
Die Musik hat sich übrigens gerade eben geändert, ich hoffe, ihr hört das nicht alle.
Es war eben so schön entspannt und jetzt haben sie ein bisschen mehr Beat reingebracht.
Ja, vielleicht treibt es das ja so ein bisschen durch die Nacht.
Ja, also es kann ja sein, dass ich aus einer wirtschaftlichen Sicht sage,
das, was die mir an Qualität liefern, das ist mir ehrlich gesagt zu hoch.
Ich hätte gerne lieber weniger Qualität und dafür schneller.
und das hat
den zusätzlichen Vorteil, dass wenn es dann schief geht,
dann kann ich zu ihnen hingehen und mit ihnen schimpfen und sagen hier so
das hat nicht richtig funktioniert,
jetzt macht man noch schneller.
Voll gut, ja, ich muss ja nur ein bisschen besser sein
als meine Konkurrenz und ein bisschen weniger zahlen
für die Produktivität, die ich da irgendwie rausquetsche
und dann schon
läuft es bei mir besser als bei anderen.
Und dann wäre das Problem bei der Entwicklerseite,
weil dann kein Entwickler dürfte sich darauf einlassen, weil
das ist ihnen sehr schlecht.
Ja, ich glaube, Leute tun das dann trotzdem und geraten dadurch
auch in blöde Situationen und das ist mir auch schon
selber passiert und man muss eigentlich als Entwickler
und dann halt vielleicht auch als Agentur, die
das dann komplett anbietet,
eigentlich sagen, okay, nee, das ist das, was ich
also sozusagen, das ist eigentlich meine einzige
Verantwortung, ist zu sagen, ich übe meine Profession
kompetent aus und wie ich das
mache, ist eigentlich meine Sache und
du kannst halt das nehmen oder nicht, aber
ich werde keine
Einschnitte bei der Qualität
machen, weil hinterher bin ich eh
der Blöde, wenn es schief geht, bin ich der Blöde
und ich bin sowieso der Blöde, weil
weil ich irgendwie damit ja sozusagen auch mich selbst sabotieren ich meine man wird dann ja auch schlechter wenn man irgendwie man lernt das ein Jahr dass man halt rumschlampt und so Das ist eigentlich alles das will man einfach alles gar nicht sondern man m eigentlich
mit weniger Zeit mehr hinbekommen.
Wie die Rumschlammschule. Man lernt rumzuschlammen.
Das finde ich auch.
Und Tests lösen das.
Ja, ich meine, die Frage ist halt auch,
was man für einen Anspruch hat oder was
der Lebenszyklus der Software ist. Also als wir
noch ganz klein waren, da haben wir dann
öfters mal so Marketing-One-Pager gemacht.
keine Ahnung, Kaugummi-Werbung und sowas.
Das ist so ein Ding, da ist ein Gewinnspiel
drin, das läuft genau für einen Monat und
danach wird das Ding eingestampft und es braucht kein Mensch
mehr. Ja gut, klar.
Das sollte natürlich trotzdem funktionieren.
Das merkt man ja beim Angucken schon
fast, wenn man einfach
Localhosts aufmacht.
Aber wenn man halt sagt, hey, das ist irgendwie jetzt
vielleicht was, was firmenstrategisch relevant ist,
da
committet sich die Firma auch ein bisschen
drauf, dass jetzt vielleicht auch über Jahre,
dass sie da halt irgendwie investiert hat und
das muss gut laufen
also ich meine bei den Projekten
die wir jetzt lange betreuen und die wir
damals auch in den Tests angefangen haben, ziehen wir die jetzt auch
einfach nach, weil ich meine das ist halt
einfach sinnvoll und
man kann inzwischen
Macht ihr das dann auf eigene Kosten oder sagt dann der Kunde
ja okay, das ist jetzt hier in unserem Supportaufwand
Wir machen das
eigentlich so, dass wir jetzt halt sagen, die Tests
sind ein elementarer Teil der Programmierung
Also das ist halt so, als ob man sagt
10 Minuten aus einer Stunde
nur für Tests oder so
Ja, ich würde sagen, wie gesagt,
also ich bin jetzt auch keiner, der sagt,
coverage 100%, weil wie gesagt, ich glaube einfach
80-20-Regel, ich glaube in 80% der Zeit,
also 80% des
Notwendigen kriegt man 20% der Zeit hin.
Und keine Ahnung, wenn ich
irgendwelche Django-Views oder sowas habe, die mehr
oder weniger einfach getestete Django-Funktionalität
ausführen, ich schreibe ich keinen Test dafür.
Wenn ich irgendwelche Permissions drin habe,
an denen ich selber rumgebastelt habe, okay,
das ist was anderes, weil das kann echt mal schnell in die Hose gehen.
Aber so Standard-Funktionalität
testlich jetzt auch nicht unbedingt.
Also umso mehr es Richtung Zahlen
und Details und Services geht, also
weiter weg von dem Django-Standard.
Was ist das? Übrigens interessant,
wir reden gerade die ganze Zeit nur von Django,
also Testing kann man ja auch außer von Django tun.
Das stimmt. Aber wir machen halt einfach viel Django,
deswegen reden wir jetzt erstmal weiter über Django-Tests.
Aber ich meine, die meisten Sachen sind ja
universal.
Also es ist ja jetzt nichts Django-spezifisches,
also selbst bei Flask gibt es Views.
Ja, und eigentlich hat man bei jedem Projekt,
also es sei denn, man macht halt irgendwas, was halt
tatsächlich nicht so einen
wichtigen Anwendungsfall hat, aber eigentlich hat man immer
Tests mit dabei. Und auch bei Django
ist genau das, was man halt sonst verwendet, irgendwie
üblich, nämlich entweder das eingebaute
Unit-Tests-Modul aus der
Standardbibliothek oder halt eben
PyTest, wobei
ich sagen würde so, wenn
ich mich so umgucke bei den Projekten,
in denen ich irgendwie beteiligt bin, ist die
Mehrheit inzwischen auf PyTest und
Unit-Test fühlt sich so ein bisschen an, als das sind
immer so die etwas älteren Sachen und die etwas
nicht so ganz gut gepflegt.
Und ich meine, natürlich hat das irgendwie gewissen Charme,
dass das... Erklär mir doch mal kurz, was denn
überhaupt der Unterschied ist zwischen Unit-Testers und was PyTester
Neuerung bringt. Und es gibt auch Nose-Tester oder sowas.
Ja, Nose
war früher ein Test-Runner.
Ich glaube, das ist inzwischen gar nicht
mehr wirklich Main-Tent.
Ich habe gehört, Johannes benutzt noch viel Nose.
Okay. Vielleicht benutzt er auch Unit-Test, ich weiß es nicht.
Er möge mich schlagen, wenn er das hört.
Ja,
keine Ahnung. Also Nose kenne ich auch noch,
aber das ist schon echt lange her.
aus meiner Perspektive ist es
also Unit Test
ist irgendwie eine Portierung von JUnit
und hat halt viele
der Konzepte dort mitgebracht, die ja auch jetzt
vielleicht gar nicht so schlecht sind, aber das passt halt
in vielen Fällen nicht so richtig auf das
wie man in Python normalerweise programmiert
Was heißt das denn? Also was
macht JUnit und warum ist das so anders als das?
Ja, zum Beispiel einfach allein, dass
die Methoden Namen CamelCase sind
dann, dass du halt
Assert
Methoden hast auf dem Test, dass jeder Test
eine Klasse sein muss.
Das ist halt...
Wie testet man überhaupt? Also man macht
eine Testklasse und da setzt man
quasi die Umgebung auf und dann
prüft man, ob bestimmte Bedingungen erfüllt sind
und dann baut man alles wieder auseinander.
Ja,
also wenn man jetzt
zu wie Schreib- und Tests kommt,
da ist es halt,
wie heißt es, Range
oder sowas
und
Assert oder was, das weiß ich nicht.
Man arrangiert die Dinge, die man halt, die Welt sozusagen so hin, dass man testen kann, dann ruft man halt die Funktion, die man testet auf oder halt was auch immer man da testen möchte und dann guckt man hinterher, ist jetzt alles in sozusagen gefälliger Weise wieder drüber zerfallen und es ist so passiert, wie es hätte, wie ist der sozusagen Schornstein in die richtige Richtung, der Baum in die richtige Richtung umgefallen sozusagen.
nach dem...
Und das macht man halt
bei Unit-Tests in der Klasse.
Und...
Die TastX-Testcase, ich glaube, Django-Testcase ist auch
erbarten in Unit-Testcase, oder?
Ja. Also es gibt bei Django
vier Testcase-Klassen,
aber ich glaube,
die erben alle von
Testcase, ja.
Genau, bei PyTest ist es so,
da können auch Tests einfach Funktionen sein
und das ist halt nicht Camel-Case,
sondern Snake-Case oder keine Ahnung,
mit Underscores halt.
Und man verwendet halt nicht
Methoden auf dem Test, um zu testen,
um zu asserten, sondern
man benutzt einfach das Assert-Statement.
Das macht PyTest ja jetzt auch dann.
Das macht PyTest.
Unitest macht das nicht.
Also bei Unitest gibt es immer diese Assert-Equals, das hat mich immer so ein bisschen gewundert.
Ja, genau, genau.
Super Beispiel, genau.
Wisst ihr, was die richtige Methode ist?
Assert-Equals oder Assert-Equal?
Ich glaube ohne S, oder?
Ja siehste, weiß ich jetzt auch gar nicht.
EQUAL. Eins von beiden ist richtig, das andere
ist nicht gut. Python zeigt mir immer an,
dass, glaube ich, das mit S, das ist immer durchgestrichen
wegen Deprecation. Ja.
Assert EQUAL. Eins von beiden
ist Deprecated, genau.
Aber das ist halt so, das ist halt das Problem, das man bekommt, wenn man
halt so Spezialkram macht.
Ja, das versteht man auch nicht. Also warum kann man nicht einfach die Python
implementierte Funktion Assert nehmen
und dann die zwei Dinge direkt vergleichen, anstatt Assert EQUAL hinzuschreiben
und zwei Dinge in diesen Funktionsaufbau zu gehen.
Da passieren irgendwelche magischen Dinge im Hintergrund, wo ich gar nicht
weiß, ob das so stimmt. Ja gut, wenn
eben, wenn du
sozusagen bestimmte Sachen mit einem gefällten Test machen willst
oder so, dann kannst du das ja quasi
gar nicht so richtig gut anders machen,
oder? Ich weiß es nicht, vielleicht ist es auch einfach
nur Geschmacksgeschichte.
Wie ist das denn mit zum Beispiel mit den anderen
Asserts, zum Beispiel Assert Raises?
Kannst du das auch
über das Assert Statement abbilden bei PyTest?
Ja,
aber es kann sein, dass man
Also wenn man jetzt Test 2, except Asserts und Adder Raises
Nein, nein, aber es kann sein,
also das ist ja auch ein
Context Manager, es ist irgendwie with irgendwas
raises, aber ich glaube man importiert
da irgendwas dann aus PyTest
Also Hintergrund ist ja einfach nur, dass falls jemand
falls eine Funktion Fehler werfen soll
und man genau diesen Case testen möchte
Ja, also das gibt es
auf jeden Fall
Ich muss gestehen, ich nutze auch das, was
Django von Haus aus mitbringt
Ich habe
einen Kollegen, der sehr auf PyTest schwertet
meint, dass ja alles viel besser und schneller
Ich habe das auch auf meiner Liste, dass ich mir das nochmal anschaue
und es ist halt sehr convenient, wenn du halt in der Django eigenen Welt bleibst,
dann muss man halt wenig nachdenken.
Von Jochen jetzt PyTest irgendwie gelernt,
Modus hast du mal 4 und da gibt es halt diese Features,
gibt es die auch so bei Google Tests ohne PyTest?
Also ich dachte, das wäre so ein PyTest-exklusives Feature.
Also in Django kannst du es laden.
Also in Django gibt es in dieser Django-Testcase-Klasse
Das hat vielleicht auch viele Vorteile, weil ich halt genau auf die Attribute
und so weiter alles zugreifen kann und ich dann halt Factories
nutzen kann, um die zu erzeugen und halt eben nicht nur
irgendwie Fixtures.
Das macht man in Unitests auch, also so
Factory Boy oder Factories
und halt, aber
ja, aber diese Art, wie man
in PyTest halt, dass man das quasi einfach
magisch, dass man das halt in den Test
Aufruf mit reinschreibt,
halt, dass man das haben möchte und es ist dann halt einfach da,
das ist auch so ein bisschen magisch,
das gibt es in Unitests nicht.
und das ist was explizit noch.
Okay, ja, aber das finde ich eigentlich relativ smart, weil das
gefällt mir. Ich kann einfach meine Features definieren pro
App, die ich dann irgendwie entwickelt habe
und dann kann ich die importieren in anderen Apps
als Confess und habe dann alle Funktionalitäten
die ich da brauche irgendwie. Ich löse das halt über
Vererbung. Also ich habe halt dann einen Basetest,
der dann halt für mein Projekt halt irgendwie die Rollen
der User
vielleicht irgendwie ein wichtiges Projekt oder irgendwas
erstellt und dann halt
pro App, dass ich dann halt
wenn ich das brauche, dann nochmal
eine Ebene dazwischen ziehe und dass
jeder von den richtigen Tests, also die Endtests,
dass die halt dann von dieser Klasse erben
und da ist dann das dementsprechende Setup im Setup drin.
Das heißt, ich nutze diese Django-Fixers auch eher selten.
Ja, genau.
Ich habe auch viel im Projekt mit Unitests,
dass ich dann halt so viele Test-Mix-Ins importiere
oder das habe ich halt früher immer gemacht dann,
die dann halt bestimmte Funktionalität bieten.
und was ich jetzt aber
inzwischen so mache, ist
ich
erbe von Testcase oder halt
Transaction Testcase oder was auch immer
also einem der Grundtesttypen
von Django und
mixe die Sachen dann da schon mal
rein und verwende dann nur noch meine eigenen Testcases
und sozusagen
hab dann die ganzen Importe nicht mehr in den Test stehen,
sondern ich sag dann halt irgendwie, keine Ahnung,
ich nehme halt den App-Testcase von irgendeiner App
und da sind die ganzen Mixins
dann halt drin und
und dann ist es halt deutlich weniger Schreibarbeit.
Ja, das sieht auch hübscher aus, glaube ich.
Also ich habe, glaube ich, eine Sache gemacht, ich weiß nicht, ob man die so macht.
Ich habe dynamische Importe gemacht,
von diesen Factories, die ich dann halt haben wollte,
in der Core-App, weil ich halt nicht genau weiß,
wie viele Apps gibt es denn noch um die Core-App herum.
Ich weiß nicht, ob das so eine gute Idee ist,
aber das funktioniert bisher.
Dynamische Importe klingt ein bisschen...
Ja, naja.
Manchmal muss man auch Sachen ausprobieren,
manchmal sind sie super,
manchmal steht man irgendwann fest,
war nicht so gut, muss man es wieder ändern.
was ja fast schon ein Stichwort wäre
zum Sachen ausprobieren
ich hatte vor einiger Zeit
habe ich eine Django Software gebaut
da ging es um Projektstundenerfassung und Zeiterfassung
und alles was irgendwie mit
Daten, also Datums, also mit Zeit zu tun hat
ist ja schon relativ kompliziert
und da ging es dann darum, dass halt eine Zeiterfassung abgebildet werden soll.
Die Mitarbeiter können sich an- und auschecken und dann gibt es natürlich so Späße wie jemand ist krank,
jemand ist im Urlaub, es gibt einen Feiertag, es gibt halbe Feiertage,
zum Beispiel Weihnachten und Silvester, also Heiligabend und Silvester sind halbe Feiertage,
das heißt man hat, also wird je nach Firma anders ausgelegt, aber in dem Fall war das dann vier Stunden,
das normale Arbeitszeit wäre.
Und
die ganze Logik lief
und hat auch
gut funktioniert. Dann habe ich immer gemerkt,
wenn ich irgendwas refactoren möchte, ich hatte jedes Mal die Hosen
voll und habe mich halt wirklich nicht dran getraut, weil das
halt einfach so unmöglich zu testen ist.
Und habe dann halt erstmal angefangen
ganz normal zu Fuß
Tests zu schreiben, also einfach zu schauen.
Ich setze den und den Case auf, also keine Ahnung,
Mitarbeiter arbeitet normal fünf Tage
die Woche, also diese ganzen Datenbankobjekte
erstellt und habe gemerkt, da komme ich echt irgendwie nicht weit. Das sind so viele Fälle und auch immer diese ganzen Variationen. Was ist denn, wenn jemand zum Beispiel Teilzeit arbeitet und dann kommt ein Feiertag und dann vielleicht noch ein halber Feiertag und ja, ist ausgefallen, da ist die Vertretung und die Vertretung übernimmt dann aber noch anderthalb Tage, weil dann den halben Tag eine andere Vertretung dann reinkommt.
Genau. Und dann habe ich angefangen, eine abstrakte Testklasse zu schreiben, die im Endeffekt alle Testmethoden implementiert und diese Zeitenberechnung habe ich im Endeffekt nochmal abgespeckt nachprogrammiert in dieser abstrakten Testklasse.
und diese abstrakte Klasse wird befüttert durch ein Dictionary von Objekten.
Und diese Objekte, die sind zum Beispiel, der eine Mitarbeiter arbeitet ganz normal acht Stunden und macht so lange Pause.
So, das ist ein Objekt, das da reingehen kann.
Der andere ist zum Beispiel ein anderer Mitarbeiter, der ist nur halbtags da und der arbeitet seine halbtags,
also seine vier Stunden arbeitet der auch voll.
Oder es ist ein Wochenendtag.
und ich konnte dann, wenn ich dann einen aktuellen, also einen tatsächlichen Test schreiben möchte, leite ich davon ab,
da sind gar keine Testmethoden in dieser Kindklasse drin, sondern ich befülle nur dieses Dictionary, diese Klassenvariable
und gebe da eine Liste von Objekten rein.
Ich sage zum Beispiel, okay, ich weiß, der 1.1.2017, 2017 habe ich es gemacht, das war jetzt ein Sonntag,
Das heißt, da gebe ich das Objekt rein, das ist ein normaler Wochenendtag, da hat niemand gearbeitet. Am Montag kommt das Objekt rein, alle arbeiten normal und dann vielleicht die ganze Woche voll und dann schaue ich einfach, ob zu erwarten ist, dass niemand, also alle haben normal gearbeitet, dass es null Überstunden sind. Das macht dann aber die abstrakte Klasse.
und das heißt, für jeden Testfall, den es gibt, also alle komischen Kombinationen,
kann ich einfach diese Objekte befüllen und wenn ich jetzt einen neuen Testfall habe,
muss ich entweder nur diese Liste neu zusammenstellen oder halt ein neues Objekt bauen,
das halt die Sachen so einstellt, dass es funktioniert.
War ziemlich abgefahren, ich habe auch ziemlich lange dafür gebraucht.
Im Endeffekt war es ziemlich cool, weil jedes Mal, wenn ich einen Bug gefunden habe,
konnte ich halt in drei Minuten, also literally drei Minuten,
halt einfach diesen Fall nachstellen mit meinen ganzen Objekten
und konnte sicherstellen, dass es beim nächsten Mal nicht mehr kaputt geht.
und die größte Herausforderung
dabei, und das ist auch so ein bisschen
das große Fragezeichen dahinter ist halt,
wer kontrolliert den Kontrolleur?
Weil ich habe ja den Code nochmal teilweise nachgebaut.
Also ich habe ihn jetzt explizit nicht kopiert, sondern ich habe ihn neu geschrieben
und auch ein bisschen abgespeckt. Aber was ist,
wenn man jetzt einen Bug
im Testcase hat? Und tatsächlich glaube ich,
80% der fehlgeschlagenen Tests
waren, dass ich in der Nachimplementierung
einen Bug hatte. Ich glaube, ich hatte eine richtige Implementierung,
die ich damals noch vor vielen, vielen Jahren
ohne Tests geschrieben habe. Da war tatsächlich
auch kein Fehler mehr drin, weil es halt schon so lange lief
und die alle ausgemerzt waren.
Ich war mir sehr
unsicher, ob das überhaupt eine gute Idee ist, das so
zu machen, wegen der offensichtlichen Nachteile,
die es halt gibt. Also dauert lang und wer
kontrolliert das nachher oder wie kontrolliert man das?
Und habe dann auf dem
PyCologne Meetup, zufällig war da jemand,
der
mehr oder weniger in einer großen Firma genau
sowas macht für sehr komplizierte Fälle.
Ich glaube, das war medizinischer Bereich,
wo es halt wirklich stimmen muss und der meinte,
wenn es wirklich, wirklich kompliziert ist,
dann geht es nicht anders. Also die meinte, es gibt sogar
Software, die so kritisch ist, dass die einfach den Auftrag, das gleiche
Pflichtenheft an zwei verschiedene Teams geben, die sich nicht kennen.
Lass uns beide programmieren und das eine ist halt das Testsystem vom anderen.
Also es ist schon absurd.
Das ist ja auch immer die Frage, wie aufwendig
ist es halt irgendwas zu ändern.
Die Prozessorhersteller machen das ja auch, dass sie halt
wahnsinnig viele Tests machen, dann Stresstests,
irgendwie für neue Designs von ihren Chips und so und versuchen das letzte bisschen, was überhaupt testbar ist,
da rauszukitzeln, einfach deswegen, weil wenn die Maschinen erstmal eingestellt sind und die Wafer irgendwie belichtet,
dann ist halt schlecht, wenn das irgendwie schiefgegangen ist.
Man kann auch nicht mehr ändern, kann man halt hinterher nicht mehr fixen,
während, naja, Code kann man halt noch ändern, das heißt, so furchtbar intensiv muss man es vielleicht auch nicht testen.
Aber natürlich ist es halt immer noch blöd, wenn Sachen schief gehen
Daher, ja, irgendwo ist da ein Sweet Spot
Aber das ist halt nicht so ganz klar
Ja, Testen ist schon ein bisschen
dunkle Magie auch
Ich habe einen Test geschrieben
Dann habe ich die Tests ausgeführt
Dann war kein Problem
Dann habe ich sie nochmal ausgeführt
Einfach ohne irgendwas zu ändern
Dann trug der Test viel
Dann stand ich da natürlich und dachte, was ist denn das jetzt
Habe ich nochmal ausgeführt, dann ging es wieder
Dann habe ich nochmal ausgeführt, dann ging es wieder
Dann habe ich nochmal ausgeführt, dann trug es wieder viel
und hat mir jemand erklärt, ich habe einen non-deterministischen Test geschrieben,
also einen Test, der in Ausgang ungewiss ist.
Und ich habe überhaupt nicht verstanden, von welchen Zeiteffekten,
von welchen Begebenheiten das hätte kommen können.
Das fand ich total schwierig zu begreifen,
warum der gleiche Test in mehrfacher Ausführung mal B-Check, mal nicht.
Ja, das Ganze gibt es dann natürlich auch irgendwie in sozusagen Reihenfolgenabhängigkeiten.
Das ist wahrscheinlich somit das Häufigste, dass man quasi zwei Tests hatte
und da, ohne dass man das jetzt beim Schreiben vielleicht so
gedacht hätte,
aber man macht es halt einfach so, weil das dann halt logisch hinterher
passiert oder so, man macht zuerst das, dann testet man das nächste
und verändert aber den State
jetzt bei einem Django-Modell irgendwie so,
dass der zweite Test halt funktioniert. Und wenn man jetzt
die Tests in umgekehrter Reihenfolge ausführt, dann funktioniert
das nicht mehr. Und das ist halt auch
so ein Ding, man muss halt eigentlich sicherstellen, dass die ganzen Tests
isoliert funktionieren, weil ansonsten
kann man nämlich...
Da gibt es ein sehr schönes Beispiel, das ist auch ganz brandaktuell
zu Django 3.1, die haben da jetzt nämlich
einen Bug gefixt, der schon, glaube ich, seit 2012 drin war, mit dem Order By beim Aggregate.
Ich weiß nicht, ob euch das mal über den Weg gelaufen ist.
Ist mir am Anfang, als ich neu mit Django war, immer wieder mal passiert,
dass ich bin mir nicht mehr so 100% sicher, ich habe es länger nicht mehr selber erlebt,
aber wenn man eine Aggregierung oder ein Annotate macht und dann Order By,
beziehungsweise wenn das Model selbst in der Meta-Option, in Order By,
eine standardmäßige Notierung
ergiefert, dann gab es Bugs.
Dann hat das ORM
teilweise komische oder falsche Sachen zurückgegeben.
Der Bug, das Ticket
ist 3000 Jahre alt
und die haben das jetzt tatsächlich repariert
und das führt dazu,
dass die Lösung war einfach,
das ist halt aus Gründen
funktioniert es nicht und das heißt, wenn du
aggregierst oder annotierst,
dann wird dieses ORDER BY
im Model Meter ignoriert.
Das heißt,
bei meinen Cases, wo ich das gemacht hatte,
habe ich in meinen Test-Cases natürlich erwartet,
dass die Sachen sortiert kommen, weil ich ja wusste,
meine Projektliste oder meine Mitarbeiterliste,
die wird ja
übers Model sortiert. Hatte ich natürlich
kein X-Wise oder bei gemacht.
Plötzlich schlagen irgendwelche Tests für, nachdem ich auf Django 3.1
hochgegangen bin, weil da die Reihenfolge anders ist.
Weil es gibt jetzt kein Order bei mir. Es gibt halt irgendeine
Reihenfolge, die die Datenbank zurückgibt.
Okay, ja, das ist
auch gefallen, ja. Ziemlich abgefahren.
Ich habe auch erst gedacht, das kann doch nicht sein.
also ich hab doch nur, ich hab Django hochgezogen, was ist denn da los?
Bis mir dann
ein lieber Kollege sagte, schau mal
such mal nach Otterbye in den
Also Otterbye ist ja echt rausgeflogen?
Ne, das ist nur für diesen Sonderfall.
Das war ein Bug und den haben die jetzt rausgenommen.
Also den haben die gefixt und die Lösung
dafür ist, dass es halt nicht mehr genommen wird.
Du kannst es manuell dahinter schreiben,
dann funktioniert es, aber du musst es halt manuell machen.
Aber in der Mittagklasse geht es nicht mehr?
Immer, außer du machst
Irritate to Aggregate.
Ah, okay.
Da gibt es auch einen eigenen Eintrag dazu
und das ist auch irgendwo im Ticket nochmal festgehalten und verlinkt
etc. etc.
Ich bin da jetzt auch nicht 100% in Details drin, ich bin halt
nur drüber gestolpert, weil das war auch genau das mit der
Reihenfolge. Plötzlich war mein Element, dass ich an Stelle 1
erwarte, an Stelle 2 und umgekehrt.
Und wenn dann halt die Tests so
gebaut sind, dass der halt die Reihenfolge explizit
erwartet, weil ich ja wusste,
damals noch sortiert war, dann
steht man da plötzlich.
Ja Und das mit der Reihenfolge von Tests ist halt und ist halt auch deswegen so wichtig weil n ein F
auf jeden Fall, und ich weiß auch nicht, das ist bei PyTest und bei Unitest anders, aber man kann halt
mit einer bestimmten Option sagen, so, führ die Tests mal in umgekehrter Reihenfolge aus. Wenn das schief geht,
dann weiß man schon, dass man ein Problem hat. Oder führ die mal in zufälliger Reihenfolge aus, dann muss man es halt wahrscheinlich
ein paar Mal ausführen und wenn es dann funktioniert hat, hat man vielleicht Glück gehabt und
man kann es parallelisieren. Aber genau, wenn die Tests isoliert voneinander
funktionieren, dann kann man halt die halt auch parallel ausführen
und dann halt es halt quasi um den Faktor,
das mit dem Parallelisieren eigentlich fast vergessen, weil das kriegst du halt nicht so einfach umgestellt.
Ja, genau.
Wie ist das? Habt ihr da häufig Probleme mit langlaufenden Tests?
Wie viele Tests habt ihr denn überhaupt? Bei großen Projekten muss das ja in die Zehntausende gehen.
Ja, tatsächlich. Also bei unseren langlaufendsten Projekten bin ich nicht mehr aktiv dabei.
also bin ich nicht im Dev-Team, das heißt
ich habe da jetzt keine Zahlen, aber ich weiß
dass die Pipelines
da teilweise auch Stunden brauchen
also einfach weil
die haben da inzwischen noch Optimierung gemacht
das ist halt mehr gar nicht nach jedem Feature-Release
wenn man da irgendwie Agile irgendwie dran sitzt
tatsächlich haben wir da jetzt auch
Lösungen irgendwie gebaut, dass halt manche
Tests laufen dann irgendwie nicht mehr
pro Commit
oder irgendwie Sachen werden lokal getestet, weil es lokal
doch manchmal ein bisschen schneller geht oder es mehr ist eine Parallelisierung
und die Technik.
und Jochen unterhalten sich über die Programmiersprache Python
eine magische Funktion, das sind die SetupTestData
und
da wird es
in eine Transaction gerappt,
das heißt, die Daten
werden nur einmal ausgeführt, es ist auch eine ClassMethod,
also es ist nur einmal pro Klasse, aber die
kann man quasi recyceln, also bei jedem
Testaufbau, das heißt,
man hat so ein bisschen das Beste von beiden Welten.
Ich habe das dann gelesen, fand das cool und dachte,
ach, mal gucken, was das bringt, habe gedacht, ah,
1000 Tests, das dauert bestimmt ewig, aber tatsächlich
ging es relativ fix, nach 2-3 Stunden war ich fertig
und
ja, hab die Python von
25 Minuten auf 5 Minuten gedrückt
für die Tests und das hat mich halt
echt richtig, richtig, richtig überrascht, dass das
so viel bringt tatsächlich. Ich meine, klar,
wenn man überlegt, dass jede Testklasse
vielleicht 20 Tests hat, dann
ja,
5 Tests schneller. Da gab es doch jetzt auch genau
dieses Buch dazu, wie man Django-Tests
Ja, von Adam Johnson, jetzt irgendwann im Mai
rausgekommen, Speed Up Your
Django-Tests heißt das irgendwie.
Genau und
ist PyTest schon normalerweise ein Stück schneller
und bei der reporteten Zeit ist es
relativ ähnlich, aber das liegt halt daran, dass PyTest einfach
mehr Sachen dazu zählt, zudem
das hat jetzt, so lange hat der Test gedauert.
Und
ja, also was er empfiehlt, was man
halt am Anfang machen kann, ist, also man
sollte erstmal gucken, erstmal messen,
also halt zum Beispiel
sich anschauen, was sind denn eigentlich so die langsamsten
Tests, die man so hat, weil normalerweise
hat man da auch so eine Pareto-Verteilung,
dass halt 20% der
der Tests machen halt 80% der Zeit aus
und
mit PyTest geht das einfach so
minus minus Durations und dann
eine Zahl und dann kriegt man halt die
Zahl langsamsten Tests
einfach am Schluss ausgegeben
und bei Unit-Tests muss man halt irgendwie Jungle-Slow-Tests
installieren oder so
aber damit geht das in der Art auch und dann den Test-Runner
ersetzen und dann kriegt man die halt auch ausgegeben
und dann kann man halt bei den
Tests halt dann mit einem Profiler nachgucken
was macht die eigentlich so langsam und dann findet man
wahrscheinlich schon Dinge, die man halt verbessern kann
und
ja, da gibt es dann auch so Dinge
wie, ja man kann halt
es gibt da diverse Tools mit denen man sich
man kann ein C-Profile, kann man Ausgaben
an Zeugen, die man sich dann gucken kann
mit K-Cashbrite oder
naja gut, muss man sich
da gibt es eine Menge Zeugs
dann gab es
so Easy Wins, so einfache
Dinge, die man halt mal tun kann
um halt die Geschwindigkeit von Tests
zu verbessern und da ist glaube ich
das erste, was er schreibt, ist halt
den Passwort-Hasher zu ersetzen.
Das ist halt auch mal so ein Standard,
weil man erzeugt halt viele User
und so und da muss man halt auch...
Und die echten Passwort-Hash-
die echten Passwort-Hash-Algorithmen
sind natürlich extra so designt, dass sie möglichst langsam
sind, damit man halt nicht
viele Hashes durchprobieren kann, weil das
einfach zu teuer wäre. Das will man
jetzt natürlich, wenn man Sachen beschleunigen möchte, möchte man nicht.
Möchte man jetzt halt aber eher schnell haben.
Und wenn man dann den MD5-Hasher nimmt,
der ist halt nicht sicher, aber...
Bei Hes ist es halt egal,
und Jochen unterhalten sich über die Programmiersprache Python
für die Testdatenbank
Serializable.folds
oder so, auch eine Konfiguration und dann wird das halt nicht
gemacht. Man braucht das eigentlich fast nie.
Es gibt ganz selten Testfälle, die sowas benötigen,
aber eigentlich braucht man das nicht
und macht auch Sachen schneller.
Dann
was war da noch drin?
Also solche Dinge, wie man kann,
das kannte ich gar nicht. Das war mir neu.
Ich habe tatsächlich,
oder ich weiß nicht, wie du das machst mit Files, wenn du
halt irgendwelche Bilddaten oder so
Testes oder so, hat eigentlich auch viel mit Files zu tun.
Ich hatte zum Beispiel immer das Problem, dass dann halt viele
Files einfach noch am Schluss rumgelegen
sind und dann habe ich halt irgendwelche
Cleanup-Scripts geschrieben.
Genau, Dinger geschrieben,
nicht Cleanup-Scripts, sondern halt schon das
quasi so mit in die,
ich habe dann das in Dekoratoren
reingeschrieben und dann halt die Testplassen dekoriert
und die haben dann hinterher quasi die
Media, das Media-Root wieder
aufgeräumt oder so.
Ich weiß gar nicht mehr genau, wie ich das
auf jeden Fall habe ich da halt irgendwie
Aufwand reingesteckt und dachte so, oh das war ätzend
und es gibt
DJ in Memory Storage heißt das Paket
glaube ich und da kann man
das Default Storage
ersetzen durch halt in Memory
Storage und dann wird überhaupt nichts gespeichert
und das ist halt viel schneller, weil es ist halt in Memory
es funktioniert halt genauso, aber
es landet hinterher gar nichts auf der Platte und wenn man
viel mit Files macht, dann
ist es halt sofort deutlich schneller
ja, das war auch
so ein Ding, das fand ich echt gut
das ist sehr praktisch
dann
gab es noch so Salary-Optimierungen
da kann man auch ein Memory-Backend verwenden
und
naja, man muss halt gucken, dass die
dass man halt Always-Eager auf True setzt
und auch noch irgendwas anderes
weiß ich nicht mehr genau
ja, sowieso diese ganzen
Async-Task-Dinger
da gibt es dann halt Jungle-Queue, das will ich mir mal angucken
Salary, hab ich letztens wieder, ah Salary
Salary!
Ja genau, genau
euch vielleicht auch, mich hat es auf jeden Fall
vor ein paar Tagen gewissen, mal wieder
als ich irgendwie dachte
so irgendwie
seltsam ruhig hier so alles
irgendwie passiert da zu wenig
auf dem Produktionssystem, wie kommt denn das
und ich hatte gerade irgendwie released
und guckte dann halt so in die Logfase
was sind denn die ganzen Satellit-Tasks
wo sind die
was
warum werden da keine Satellit-Tasks mehr aufgeführt
und dann hab ich so ein bisschen gegoogelt
und dann ja, jetzt, ich glaube 4.4.7 war das oder so, hat irgendeine Regression,
eine böse Regression drin gehabt, dass halt die
Salary Broker URL oder so aus den Settings nicht mehr benutzt wird.
Und ja, ich weiß nicht, wie viele Produktionssysteme das weltweit gebrochen hat.
Es dürften viele gewesen sein.
Ja, ein netter Tag, ja.
Und dann habe ich wieder downgradet auf 4.4.6 oder so was und dann war es wieder okay.
Aber so wow, okay, das war schon, naja.
Ich muss mir mal Jungle Q angucken.
Eine Sache
die eigentlich total
selbstverständlich ist, die ich aber
für mich persönlich erst relativ spät erkannt habe
ist, wenn man
also man hat eine Funktion
also man hat einen Service, man hat eine
höher levelige Funktion, die man
testen möchte und darunter laufen noch andere Sachen
zum Beispiel, das können jetzt API-Calls sein
da kam ich jetzt gerade drauf wegen den externen Sachen mit den Files
aber auch andere Sachen, die tendenziell
noch länger laufen und
und wenn man den Aufruf der unterliegenden Funktion einfach mockt,
dann spart man natürlich einen ganzen Haufen Zeit,
weil der halt dann nicht versucht eine API anzusprechen,
weil man irgendwie die API mocken muss oder keine Ahnung was,
sondern man sagt einfach, das Ding gibt 27 zurück und gut ist.
Und auf der anderen Seite werden die Tests natürlich auch deutlich besser,
weil man isoliert nun den Teil testet, den man eigentlich testen möchte.
Du musst jetzt einfach noch kurz neu antreten.
Einmal musst du ganz kurz erklären, was überhaupt Services sind,
vielleicht für alle Menschen, die das noch nicht so benutzt haben.
Okay, also Django bringt da keinen Pattern mit, wo man Logik hinpackt. Es gibt Manager für Datenbank-Querys, es gibt Models, es gibt Views, oder wenn man jetzt einfach Logik bauen möchte, die irgendwas tut, also die irgendwie ein CSV generiert, Daten verarbeitet, dafür gibt es halt offiziell nichts, wo man das hinpacken kann.
Utils, Helpers.
Ne, das ist auch Utils.
Immer wenn du ein Modul hast, das Utils heißt.
Schon so ein...
Tatsächlich auf der
Kopenhagener DjangoCon
letztes Jahr.
Jetzt muss ich meine ganze Applikation
und das weiß ich nicht.
Ich weiß, ich habe selber solche,
aber eigentlich ist es keine gute Idee.
Weil das Problem ist halt,
was sagt dir das, wenn du bei irgendjemandem siehst,
da liegt halt ein Utils-Modul rum.
Was ist da drin?
als möglicher Unsinn.
Ja, weißt du halt nicht.
Das ist gar nicht so gut, wenn du da verkrummlicht und weißt nicht, was das ist.
Tatsächlich gab es da auch
einen Vortrag auf der letzten JungleCon
in Kopenhagen, wo dann auch ein paar Franzosen
glaube ich drüber geredet haben, dass sie halt
das Konzept vermissen, dass das nicht offiziell
in der Doku drin steht, macht das so, weil
es halt sehr viele Leute so machen, dass man einfach eine Klasse
anlegt, die kann man dann einsortieren, die kann man sinnvoll benennen
und dass man
da dann halt seinen Code
irgendwo sinnvoll parken kann
und dann auch, ich meine,
das ist halt so eine Art Best Practice, das hat kein offizielles Django-Pattern
aber ich glaube, das gilt inzwischen als Best Practice
korrigier mich, wenn du es anders siehst
aber
ich weiß, hörst du es nicht
es ist aber nicht diese Geschichte
wo irgendwelche Leute versucht haben, den ORM
so ein bisschen weg zu abstrahieren
da gab es mal, genau, auch auf Django News
die haben auch da Werbung gemacht
die haben das auch irgendwie Services genannt
aber ich glaube, das war was anderes
es ging, das war dieses Projekt, irgendwie
Maintaining a Django Project over 10.000 Commits
oder sowas hieß das
und die Programmiersprache Python.
heute ist, nicht heute, sondern irgendwann anders.
Montag. Genau.
Und man kann
aber auch... Trageproduktiv.
Man kann aber auch einen Mockblock verwenden,
das heißt, man kann einfach dann sagen,
alles, was in diesem Mockblock
passiert, wenn da eine
bestimmte Funktion aufgerufen wird, füllt ihr die nicht aus,
sondern gibt einen
festen Wert zurück. Zum Beispiel, wenn man eine
Funktion hat, LoadData vom API
oder sowas, kann man einfach sagen, das gibt
ein fixes JSON zurück.
Ein Mockblock. Schön.
Ja, sagt man, oder?
Und wie gesagt,
wenn man das Mocking einmal gesehen hat,
ist es eigentlich total offensichtlich, aber ich habe halt
irgendwie nie so realisiert oder lange nicht realisiert,
dass es halt einerseits total viel
Zeit sparen kann und andererseits auch noch
deinen Testcode verbessert,
weil dadurch, dass halt die unterliegende Funktion
einen festen Rückgabewert hat, wenn da jetzt
ein Fehler drin ist, dann
tangiert das halt nicht die
anderen Sachen, sondern die Funktionen, die ja hoffentlich
auch getestet sind, failen dann isoliert
und man hat dann nachher nicht irgendwie 50
gefailte Tests, man muss erstmal anfangen zu suchen,
sondern im Optimalfall, wenn alles isoliert genug ist,
fällt genau der Test ja nicht mehr
das bringt, was er möchte
und
diesen Doppelwin, das fand ich
echt ziemlich neat,
das
nochmal so zu realisieren.
Ja, nee, klingt gut. Also ich
packe meistens meine Logik irgendwie so
in den Model-Layer,
mehr oder weniger.
Oder beziehungsweise
dann halt in Mixins,
die dann halt
Models aufblähen.
Ja, ich dann auch oft, wenn es dann zu lang wird,
stecke ich halt in andere Files und importiere die
dann aus Models.py dann halt da rein.
Genau, aber
ja, ich weiß auch noch nicht so genau.
Ich muss mal in den Vortrag gucken.
Genau.
Es gibt verschiedene Meinungen dazu, glaube ich.
Definitiv. Das ist vielleicht auch der Grund, warum das noch nicht
in der Dango-Doku gelandet ist.
Ja, bei TwoScoops sagt ja auch, dass total katastrophal für Fatmodels,
aber ich finde das eigentlich auch gar nicht so schlecht, weil ich es bei Jochen gesehen habe,
natürlich, dass man da viele gute
Dinge reinpackt, die halt da hingehören irgendwie.
So vom Gefühl her machen die halt Sachen mit der
Datenbank oder so.
Ich mag das auch.
Also ich würde es nicht sagen, ich mache jetzt
da ist alles dran, weil wie gesagt, ich finde das Service-Prinzip
ganz nett und mag das
auch ganz gern, aber
die sind auf jeden Fall nicht dünn, die Models, die ich baue.
Ja.
Ja, aber wir hatten
nochmal ganz kurz über das Mocken geredet und ich glaube
Mocken ist auch was, was noch sehr interessant ist
weil man kann natürlich alles
Mocken und so tun, als gäbe es irgendeine Umgebung
und dann da testen, ob dann das, was man
so geschrieben hat, für diese isolierte Umgebung
dann funktioniert. Ja, und dann funktioniert es in der Realität
nicht mehr, weil der Mock halt anders aussieht als die Realität
Ja, genau, und vielleicht ist das eines der Probleme
also ich habe das schon öfter mal mitbekommen, dass gerade
Menschen, die irgendwie viel Coverage erreichen wollen
und irgendwie sich dann mit vielen Mocks
also es gab sogar Menschen, die haben jetzt dann Screenshots
von den Webseiten irgendwie
besorgt und dann geguckt, ob die dann am Ende
genauso aussieht, weil sie dann irgendwie Templates noch
versucht haben zu generieren und
dann die Bilder miteinander verglichen haben
und solche Sachen, also wirklich abgefahrener
Quart.
Ja,
mockt ihr überhaupt irgendwas oder
findest du das anstrengend oder
dann macht man das.
Ich benutze das
sehr häufig und ja, muss man
auch, denke ich, also gerade wenn man irgendwie APIs
fragt oder so mit externen
sonstigen Systemen redet, dann geht das ja quasi gar nicht anders.
Das heißt, du musst extern Antworten von Dingen, die du nicht im Test eigentlich abbilden kannst, die musst du dann tatsächlich emulieren.
Die muss man immer bocken, das geht gar nicht anders.
Ja gut, das sind Abfragen von extern ab, hier kann man sich tatsächlich vorstellen, dass das sinnhaft sein kann.
Ich mache es tatsächlich bei Daten enorm viel, weil das halt einfach, also das ist nicht schlimmer, als wenn du irgendwie am Freitag einen Test ausführst und plötzlich geht er nicht mehr.
Was sind Daten?
Also Datums.
Ja, ja, okay, das ist ein bisschen schwierig im Deutschen.
Irgendwelche Zeiten,
das ist total super.
Man kann auch mit diesem,
das heißt Freescan, das Tool, mit dem man das
machen kann, und da kann man halt auch
einen Block machen, also sprich alles, was eingerückt
unter diesem with-Tag ist,
kriegt dann einen anderen
Timestamp, was halt sehr praktisch ist. Man kann das als Decorator
verwenden, zum Beispiel sagen, heute ist der 26.6.
Obwohl das, also egal, wann der Test läuft.
Und wenn man jetzt zum Beispiel sagt, ich möchte
Objekte erstellen mit einem bestimmten Timestamp,
dann
kann ich halt das in diesem
WhistHack machen, obwohl der ganze Test sagt
ich bin am 26.06.
kann ich dann trotzdem sagen, dieser Subjekt ist aber schon
zwei Jahre alt, das ist halt ziemlich praktisch
wenn man da so zwei, drei Dinge verstanden hat
dann kann man sich das Leben sehr leicht machen
ansonsten, das Mocken nutze ich
viel weniger als
als man es wahrscheinlich sollte
ich nutze es halt f APIs also f externe Sachen die ich halt mocken muss auf Unit oder Functional und ansonsten wenn ich halt eine Funktion habe die halt sehr lange l wo ich halt wei ich will die nicht jedes Mal durchjubeln auf allen
höheren Ebenen, weil mir das einfach
zu lange dauert.
Aber wahrscheinlich wäre es sinnvoll, das mehr zu machen, obwohl
natürlich du auch vollkommen recht hast,
umso mehr man sich irgendwie da seine
Fantasiewelt aufbaut, umso weiter weg
bist du auch irgendwann natürlich von der Realität.
Mhm.
Ja, also User-Input oder sowas, das kann man ja auch in Frontend weiterdenken, was man halt irgendwie alles dann mocken kann.
Habt ihr viel Frontend vorgetestet? Was gibt es da?
Mocha und...
Nee, nicht wirklich viel, ja.
So Unit-Tests im Frontend, das ist ja, glaube ich, hat sich inzwischen so Jest als der Standard etabliert so ein bisschen.
Reden wir jetzt von JavaScript oder reden wir von normalen Django-Templaten?
JavaScript.
Ich bin bei Frontend da direkt immer schon bei JavaScript.
Ja, ja, eh, aber...
Ja, leider, leider, ja.
Aber vielleicht ist das der selbe Thema.
Ja, meintest du denn
Django-Templates?
Nein, ich meine tatsächlich
JavaScript und Mutter und so, was man da alles so bauen kann.
Ja, also ich würde sagen,
da gibt es halt eben den Unterschied zwischen
End-to-End-Tests, also so was, Hypress,
oder weiß ich nicht, was Leute da noch verwenden, Selenium...
Da ist wohl die neue Version heute rausgekommen, habe ich gelesen.
Ah ja, habe ich gar nicht
bekommen, ja. Cool.
Ja, und ich habe
und Jochen unterhalten sich über die Programmiersprache Python
Ja, man kann halt auch tatsächlich andersrum anfangen
und kann sagen, man baut zuerst seine Tests
Das nennt man dann Test-Driven Development
und wenn man erst die Tests hat
die alle verschiefen gehen und dann den Code baut
Was haltet ihr denn davon?
Also für mich finde das immer sehr verwirrend
sowas zu tun, weil
um das zu tun, also erst Tests zu bauen, dann müsste ich erstmal
wissen, was meine Anwendung überhaupt machen soll
oder macht, um dann Tests bauen zu können
wo die dann diese hypothetische Anwendung bestimmen können
und das alleine ist schon ziemlich herausfordernd
finde ich
Ja
ehrlich gesagt, ich habe das noch nie so wirklich
probiert, weil ich immer dachte
ich muss das vielleicht mal machen
tatsächlich mal versuchen, wie es ist
Test Driven zu entwickeln, aber ja
da ist die Idee ja im Grunde, dass du genau erst
immer den Test schreibst und dann erst den Code
und man hört dann halt auf, wenn der Test
funktioniert, aber
also gerade auch
bei Django, ich fange meistens
wenn ich anfange irgendwas zu
schreiben, schreibe ich erstmal das in einem
Jupyter-Notebook.
Weil, genau, also da gibt es halt
es gibt ja die Django
Shell Plus zum Beispiel, den Django Extensions,
wo man halt die ganzen Modelle schon
drin hat sozusagen. Das gibt es halt auch
in der Jupyter
Frontend.
Und man hat dann quasi so eine Umgebung wie in der
Shell Plus, bloß halt mit dem ganzen anderen
Jupyter-Kram drumherum. Genau, man kann halt die ganzen Teile immer wieder
ausführen. Genau, dann probiere ich halt
so lange rum, bis ich weiß, dass es ungefähr
das tut, was ich gerne hätte.
und
weil man so Funktionen machen möchte, die
die Modell-Sachen machen
oft Sachen muss man halt irgendwie ausprobieren
das geht nicht, dann muss man es irgendwie anders machen
und damit geht das
eigentlich tatsächlich sehr sehr
schön, während man halt
wenn man das jetzt tatsächlich direkt in Code schreiben würde
müsste man das immer irgendwie ausführen
man müsste jetzt erstmal an die Stelle kommen, wo das dann ausgeführt wird
und das ist halt immer ein bisschen
schwieriger
und im Notebook hast du das halt
da änderst du dann mit deinem Code-Fist nochmal die Zelle aus
und weißt dann, okay, jetzt passt's
und dann, also meistens, also da
fange ich an, Sachen zu basteln und wenn das
dann halt so halbwegs passt,
dann überführe ich es halt in
tatsächlich
Django-App-Code irgendwo
und dann fange ich meistens dann auch Tests
zu schreiben. Manchmal stelle ich dann noch was um,
weil es irgendwie
dann einfacher ist zu testen oder so, aber oft
ist es dann auch mehr oder weniger dann schon so fertig.
Das heißt, das Test-Driven ist quasi gar nicht
erst Testschreiben
bei dir, sondern eher so Experimente
machen in so einem Notebook, die
und Jochen unterhalten sich über die Programmiersprache Python
und er weiß, in welche Richtung man möchte.
Ja, also insofern
habe ich das,
wie ich das momentan mache, aber
wäre vielleicht auch mal ganz interessant, Test-Driven
Development mal so wirklich auszuprobieren
oder mal gezeigt zu bekommen von jemandem, der das so wirklich kann.
Aber ja, daher ist das bei mir
eigentlich nie. Das ist das, was quasi dann
im Applikationscode in einer
General App landet, eigentlich meistens schon
relativ fertig und die Tests, die dazu
also meistens weiß ich dann auch schon, welche Tests
ich dann schreiben muss und dann
ja,
Macht ihr Tests, Silvan, die wir da machen sollen?
Es gibt ein paar Leute bei uns, die das machen
Ich persönlich mache es nicht
Ich bin da ähnlich wie Jochen, dass ich denke, ich sollte es eigentlich
mir nochmal im Detail angeschaut haben und nochmal vernünftig zeigen lassen
Mein Jupyter Notebook ist halt, dass ich meistens mit aktivem Debugger arbeite
Also sprich, ich springe mit dem Debugger in den Code, soweit ich bin
Debugger heißt also, welche Entwicklungs-Mitgeben benutzt du?
von IntelliJ.
Und ich habe mir das
irgendwann mal angefangen
anzugewöhnen, weil das Schöne ist, du kannst halt
dann mit diesem Evaluate Expression
im Debugger, kannst du halt direkt Sachen
testen und ausprobieren. Also sprich, wenn du dir nicht ganz sicher bist,
zum Beispiel, ob eine Query das zurückgibt oder
wenn man jetzt irgendein komplizierteres Aggregate
macht, geht das, funktioniert das wirklich?
Und solange man nicht versehentlich auf
Steuerung ist, also Speichern drückt und die Seite
neu lädt und dann der Debugger neu startet,
hat man halt den Debugger,
auch wenn man da ganz viele Änderungen macht und
kann sich dann natürlich irgendwelche Zwischenstates in eine neue Variable
speichern und weitermachen.
Das ist ein sehr interessanter Ansatz, würde ich gerne
tatsächlich mal live sehen. Also weil
ich glaube so ein bisschen macht der Jochen das
und ich mache das auch ein bisschen mit den Notebooks,
weil du da halt auch immer diese Iterationen unterhalten hast
und auch, also ich benutze
VS Code manchmal,
da kann man das ja auch machen mit dem Debugger,
den ich aber selten für sowas benutze, also nur wirklich wenn ich ein Problem
habe, was ich so nicht so einfach verstehe,
dann gucke ich da mal rein und Python macht das.
Für mich persönlich, also
Mir geht es ein bisschen so, wie das verstanden hat bei euch beiden auch. Ich weiß halt am Anfang meistens nicht so genau, was nachher rauskommt. Die meisten Sachen, die man ja so zu testen hat, sind ja dann bei mir jetzt in Services und ich weiß halt einfach nicht, wie der Service Service Service Service Service Service Service Service Service Service Service Service Service Service Service Service Service Service Service Service Service Service Service
Bound Service, also eine Klasse, packt da einen Process rein und überlegt dann, okay, dann schreibe ich ein bisschen Code mit dem Debugger an, merke, okay, das müsste ich kapseln, das ist nicht testbar sonst, weil da sind zu viele Sachen drin, zieh das raus, dann baue ich da wieder Sachen dazu und so wächst das dann halt mehr oder weniger von innen nach außen.
und ich müsste halt sehr meine Denke umstellen,
wenn ich halt erst mir überlege, was möchte ich denn eigentlich so genau alles testen,
also was kommt nachher alles raus, weil teilweise manchmal habe ich auch,
wenn ich anfange, eine ganz andere Idee von dem, was nachher rauskommt,
was ich nachher habe, weil ich nachher eine gute Idee habe und merke,
das könnte man vielleicht alles besser, schneller, effizienter, komplett anders machen.
Also ich denke, TDD ist auf jeden Fall ein sehr hehres Ziel, das zu machen
und ich glaube auch, dass Leute, die, sag ich mal, programmieren lernen,
das auch bestimmt nicht verkehrt ist, wenn die so anfangen?
Ne, ich glaube, das ist für sich ganz anders.
Weil die Leute wissen gar nicht, was sie bauen können.
Und wenn die dann klären, dann wenn die Tests schreiben,
die sind sowas von überfordert.
Okay, ich formuliere um. Für Leute, die schon programmieren können,
aber jetzt sage ich mal so ein bisschen mehr in die, also
die so, sage ich mal so, dass das Grund
Handwerk verstehen und jetzt anfangen
dann wirklich produktiv arbeiten zu wollen.
Weil zum Beispiel bei mir, als ich früher
als ich
angefangen habe zu programmieren und
auch Python gelernt habe,
und da war mein Code, den ich geschrieben habe,
also ich habe damals eh noch keine Unit-Tests geschrieben,
ich meine, das ist auch schon lange her,
aber der Code, den ich produziert habe,
der war nicht gut strukturiert,
der war nicht gut testbar.
Und wenn du halt TDD machst,
dann wirst du halt von Anfang an gezwungen,
dass dein Code die richtige Struktur hat,
weil du merkst halt sofort,
oh, der Code, den kann ich nicht testen,
weil du hast...
Aber du hast jetzt gerade einen Bias drin gehabt,
du hast gesagt, die richtige Struktur.
Du hast gesagt, dass die Struktur,
die man gut testen kann, die richtige wäre.
Ja, okay, eine bessere.
Eine bessere.
Aha.
aber ich glaube auf jeden Fall, dass Code, der
nicht testbar ist, nicht so richtig
guter Code ist.
Das würde ich jetzt einfach mal so posten.
Und das zum Beispiel hat
mir, als ich dann angefangen habe, mich intensiv mit Unit-Tests
zu beschäftigen, halt sehr geholfen, auch noch mal
wirklich beim Code-Schreiben
auch zu überlegen,
wo soll das denn alles hin?
Also wenn ich halt weiß, ich möchte das
irgendwie isoliert und vernünftig, also ich möchte nicht
nachher drei Stunden über Tests nachdenken und irgendwelche wilden Fälle
zusammenbauen, sondern ich möchte es ja einfach, es ist ja
funktioniert, macht ein oder zwei Sachen, genau das möchte ich abchecken,
ob das nachher rauskommt und fertig.
Und wenn man halt das nur baut, dass es
funktioniert und gar nicht über diese Tests nachdenkt,
ja, das ist halt, glaube ich, ein Unterschied.
Von daher glaube ich, kann das, also ich glaube,
für Leute, die schon relativ gut wissen,
was sie tun, kann das natürlich eine Verbesserung sein.
Wir hatten mal
vor vielen, vor zwei Jahren einen,
ich sag mal, einen Python-Guru bei uns
in der Firma, der mal so einen Tag lang
über TDD erzählt hat und im Endeffekt
querbeet alles Mögliche und
und war das auch mein erster intensiverer Kontakt mit TDD.
Und ich habe ihn im Nachgang auch gefragt,
ich arbeite so und so, was sagst du dazu?
Und er meinte im Endeffekt, es gibt halt viele Wege, die nach oben führen.
Er selbst findet das gut, er macht das auch so,
er hat auch irgendwann mal umgelernt.
Aber für ihn zum Beispiel ist es halt wichtig,
dass Testbarer Code rauskommt.
Und wenn man halt selbst durch die Art, wie auch immer man da hinkommt,
wenn Testbarer Code am Ende rauskommt,
dann ist halt ein großer Vorteil von TDD,
und die hat man halt anders erreicht. So what?
Eine Sache,
die ich auch ganz interessant fand, ist,
bei TDD fängst du an und schreibst einen Test, der per se
failen muss, weil es gibt ja noch nichts,
was funktionieren kann, weil du ja mit dem Test anfängst.
Und das fand ich ganz spannend. Er meinte,
er findet das,
das ist für ihn so die Routine,
er fängt irgendwas an zu programmieren
und sieht erst mal, der Test schlägt viel.
Und wenn man
andersrum arbeitet, dann baut man die Tests ja
so, dass sie funktionieren. Also du baust ja nicht
und baut einen Fehler ein, um den Test rot zu haben.
Und er meinte, das ist halt ganz angenehm,
dass du am Anfang siehst, okay, ich habe jetzt acht Tests gebaut,
die schlagen alle acht fehl und nachher mache ich,
dass sie gehen. Weil es kann halt
leicht passieren, dass wenn man halt
das andersrum macht, dass man halt die Tests baut
und dann hat man einen Fehler drin, der Test ist versehentlich grün.
Also voll positiv.
Und tatsächlich ist mir das auch mal
passiert in einem Projekt, da hatte ich
ein Rechnungsmodul gebaut,
also auch zahlungsrelevant und ziemlich heikel
und irgendwie ist dann irgendwann mal,
das sah auch alles immer super aus und grün und so weiter
und dann irgendwann ist halt mal die InitPy
weggekommen aus dem Testordner, wie auch immer
und naja, dann sind die halt
plötzlich mal ausgeführt von das Projekte
damals glaube ich 800 Tests, die 50
Tests für die Rechnungslegung, die sind halt nicht aufgefallen
dass die nicht mehr drin sind
und irgendwann waren dann da halt Fehler in der Rechnung
und ich dann so, irgendwie kann das nicht sein
ich hab das doch getestet und dann war das so
ups, ich meine das trifft jetzt nicht so 100%
deckungsgleich mit dem was ich jetzt gerade meinte
aber solche Sachen, es gibt halt schon echt
Beispiele wo man das haben kann
und ich finde diese Idee echt ganz nett, dass man wirklich mal guckt,
hey, funktioniert das denn wirklich?
Weil es kann ja wirklich sein, dass man testet einfach,
dass der versehentlich funktioniert.
Zu viel gemockt oder so, man weiß es nicht.
Ja, absolut.
Spannendes Thema.
Ich würde jetzt gerne noch ein paar Getränke hier testen.
Was haben wir denn noch?
Eine andere Liste?
Ich glaube, die Liste sind wir ganz gut, oder?
Wir sind durch.
Wir sind voll vorbereitet, weil wir eine Liste haben.
Du kannst ja schon mal die Liste lesen
Ich kann ja vielleicht nochmal grad
Also ich bin immer noch ganz begeistert von dem
SuiteUp für Django Tests Buch und
genau, was man nämlich auch noch
alles machen kann an tollen Sachen ist
Man kann halt auch noch die Datenbank auf ein
In-Memory-Filesystem legen
Es geht zum Beispiel mit Docker
Docker Compose geht das sehr einfach
Das ist eine gute Idee
Und das macht die auch nochmal gleich deutlich schneller
Weil normalerweise kannst du das halt nur machen mit SQLite
Und SQLite will man vielleicht nicht verwenden, weil
ist halt anders als Postgres oder was auch immer.
Ich würde sagen, kann man damit dann Postgres-Fast-Python-Analyse
testen, wenn ich ja zum Beispiel
in Postgres habe ich ja sowas wie Index-Bauen
oder sowas. Ja, ja, ja, das funktioniert alles.
Ist halt das drunterliegende Fallsystem,
was dann halt nur noch im Hauptspeicher ist.
Ich muss ja gestehen,
wir hatten ja erst
geplant, das bei dir daheim zu machen und ich hatte gehofft,
dass da zu viel das Buch herumliegt, nicht an meinen Blick
rein darf. Achso, ich habe es nur elektronisch.
Ah, okay.
Aber ja.
Lässt sich sicher sonst auch machen.
und Jochen unterhalten sich über die Programmiersprache Python
Ja, genau,
lass mal überlegen, was war denn da?
Gab es sonst noch irgendwie interessante Dinge,
die im Buch drin standen?
Ja, es gibt da noch irgendwie auch so
grundsätzliche Dinge, genau,
Testparallelisieren bringt sehr viel,
Migrationen bringen auch viel,
wenn man die squasht.
Das ist auch sowas, das sollte man
vielleicht ab und zu mal machen.
Vor allem auch, wenn man so lustige Sachen hat,
wie RunPython, also dass man wirklich noch Code ausführt,
das kann,
Ich meine, man hat ja meist eine Testdatenbank,
wo nicht so viele Datensätze drin sind, aber
je nachdem, was man da für abgefahrene Dinge tut,
kann das auch schon
ein Downer sein.
Ja.
Ja, aber ansonsten glaube ich,
muss man selber mal gucken.
Ich meine, wenn man sich das Blog von Adam Johnson anguckt,
da sind auch die meisten, also ich meine, das Buch ist
viele von den Sachen, die darin stehen,
hat er auch schon mal irgendwie als Blogartikel
an seinem Blog gehabt.
Der hat einfach gewagt, dann sein Blogartikel zu einem Buch zu verwurschen
Das ist ja der Wahnsinn
Könnte man von lernen
Ja, genau
Ansonsten
Ich weiß nicht, gibt es noch irgendwelche Dinge
Wir haben jetzt viel über Django geredet
Gibt es irgendwie Testgeschichten
die auch relevant wären, die jetzt nicht so sehr
Django oder Webentwicklung betreffen
Lass mal überlegen, habe ich irgendwas mit
Data Science
Also da ist es auch so, da macht man auch viel Tests
aber das ist auch alles sehr ähnlich
fast alles Unit-Tests
die dann irgendwie die einzelnen Test-Cases
bauen
eine Sache, die ich noch ganz
interessant finde
das geht wieder so ein bisschen
Richtung 100% Test-Coverage
mich auch mit jemandem unterhalten
und da meinte er, er ist gar nicht so ein Fan
von Unit-Tests, natürlich braucht man die
das ist halt
die gehören einfach zum Team
er meinte, da hat das so ein bisschen mit
mit den drei Musketieren verglichen.
Also Athos, der ist so ein bisschen langweilig,
aber der gehört, das hat der Chef.
Die brauchst du halt einfach, kannst nicht ohne.
Und was er halt viel cooler findet, sind halt
eher Functional Tests, also sprich Tests, die halt
die Business-Logik testen. Also dass man halt so ein bisschen mehr
High-Level-Sachen testet, um einfach sicherzustellen,
dass, keine Ahnung, wenn man halt irgendeine Logik
hat, die irgendwas macht, also eine Rechnung erstellen
oder irgendwas berechnen oder
irgendeine Daten aggregieren
oder sowas, dass die halt das tut,
was man von ihr möchte.
Und
Fand ich ganz lustig, weil meistens, wenn halt
über das Testing gesprochen wird, dann werden halt Unit-Tests
rauf und runter exerziert und
dann
wird auch immer wieder gesagt, so ja, dann gibt es natürlich
die End-to-End-Tests, wo man natürlich das Frontend drin hat,
wo man dann wieder in einer ganz Django-Fernenwelt
oder was heißt Django-Fern, das ist halt dann
tangiert Django nicht direkt, sag ich mal.
Das wird natürlich dann irgendwie aufgerufen, genutzt, aber
das ist dann ja auch bei Cypress dann JavaScript-Code
und sowas und
das sind diese Functional-Tests, die kann man halt auch
problemlos im, also selbst wenn man Django
Headless verwendet, also ohne das
und Jochen unterhalten sich über die Programmiersprache Python
Genau, also die Functional Test ist Porthos, der Coole, der Pirat.
Ja.
Und die Integration Test ist dann Aramis, glaube ich, heißt der letzte.
Die anderen beiden waren?
Ja, stimmt, du hast es ja schon.
Also Arthos, Porthos, Aramis und dann D'Artagnan gehört ja nicht so richtig dazu.
Ich muss aber, nicht dass der, der das Beispiel gebracht hat, mich jetzt haut, weil ich es durcheinander bringe,
aber Arthos ist auf jeden Fall der langweilige Unit Test.
dann. Portos, glaube ich, war das Coole. Vielleicht waren das auch die End-to-End-Tests, das weiß ich nicht mehr genau. Also Dathanion oder Portos, weil die sind beide so, ja. Und genau, Aramis ist dann Integration-Test, wo man so externe APIs und sowas mit anspricht und so. Und das ist dann halt immer so ein bisschen, das ist zwar total cool und jeder mag den Charakter auch, aber der ist halt so ein bisschen schwierig. Der ist dann irgendwie ständig verliebt und irgendwie Seelenkrise und so und das ist dann auch so mit den externen APIs. Das ist total cool, das zu haben, aber man hat halt auch irgendwie ziemlich viel Scherrein damit. Und ja.
Der Wind kommt, damit die Tests gerade...
Ich glaube, das war
Porthos ist
die End-to-End-Test, weil die halt
ziemlich cool sind, weil du halt damit wirklich den kompletten Flow
durchtesten kannst und diese Functional-Tests sind
d'Artagnan, der gehört zum Team
und der wird aber oft übersehen,
weil das heißt nur die drei Musketeere und nicht die vier.
Ja.
Ja, ja.
Königin der Kunde oder sowas,
die entscheidet dann tatsächlich, wie es mit dem
weiterläuft, mit den dreieinhalb,
vier.
Ja, fällt euch noch was ein zu testen?
Ich teste glaube ich noch
welchen Wein.
Ja, genau. Ich meine, ich glaube, wir sind eigentlich
so halbwegs durchgekommen und so.
Die erste Folge draußen war gar nicht so verkehrt.
Also ich hoffe, es ist nicht zu schrecklich.
Ich bin mal gespannt, was
auch Vanek draus macht.
Ja, genau.
Ja, vielen Dank auf jeden Fall für die Einladung.
Ja, vielen Dank.
Mein erster Podcast.
und war echt cool, hat Spaß gemacht.
Ja, schön, dass ihr rein geschaltet habt.
Vielen Dank, dass ihr da wart.
Schreibt uns auf hello.pythonpodcast.de und bleibt uns gewogen.
Bis zum nächsten Mal.
Tschüss.
Tschüss, ciao.