005: Automatische Tests im Backend
Methoden und Herausforderungen automatischer Tests im Backend
20.04.2023 67 min
Zusammenfassung & Show Notes
Benjamin führt uns durch die Teststrategien, die wir in unserem kotlin-ktor-Backend nutzen. Dabei sprechen wir über Test-Frameworks, -Daten, -Strategien und auch deren Wirtschaftlichkeit.
Benjamin führt uns durch die Teststrategien, die wir in unserem kotlin-ktor-Backend nutzen. Dabei sprechen wir unter anderem über folgende Themen:
Transkript
Heute reden wir über automatische Tests im Backend.
Da sind wir wieder. War diesmal eine etwas längere Pause, weil wir letzte Woche
unser Unternehmens-Offsite hatten.
War auch mal wieder spannend. Drei Tage mit allen Kollegen. So richtig physisch
vor Ort ist man ja gar nicht mehr gewöhnt, aber war ein Supererlebnis.
Aber dadurch sind wir nicht zum Podcast produzieren gekommen.
Man muss Prioritäten setzen. Mal wieder eine so live zu sehen.
Hat auch seine Vorteile.
Ja, definitiv. Genau. Und heute soll es um das Thema Testing im Backend gehen?
Ja, da wollen wir einfach mal sehen, was wir da für Erfahrungen gemacht haben.
Du hast ja auch schon in anderen Stacks gearbeitet als den, den wir jetzt gerade
haben und von daher bin ich da gespannt auf deine Erkenntnisse.
Weil da stecke ich tatsächlich überhaupt nicht mehr so im Detail drin und freue
mich schon auf all die Sachen, die ich dann jetzt erfahren werde.
Für mich ist der Podcast ja auch mal eine Hilfe, um mal wieder tiefer einzutauchen
bei den Entwicklerthemen.
Du meinst dann mal wieder mitzukriegen, was wir da eigentlich so einen ganzen Tag machen?
Genau und die Hände über dem Kopf zusammenzuschlagen. Was für ein Unsinn.
Gut. Ja. Na, steigt doch mal ein.
Ja, also erst mal vorweg wir verwenden als Testframework Kotest und nicht
JUnit, was man ja auch machen könnte.
Gibt es ja bei bei allem, was ja VM basiert ist, überhaupt keine Hindernisse.
Das hat so ein bisschen für mich persönlich einfach auch historische Gründe.
Ich bin da jetzt zum haben wir ja mit Scala gearbeitet und damit Scala Test gearbeitet.
Woran ich mich dann auch sehr gewöhnt habe und was ich an vielen Stellen einfach
auch sehr elegant finde, was die Art und Weise angeht, wie man Text schreiben kann.
Und bei für Kotlin gibt es dann halt Kotest.
Und wenn man sich mal anguckt, was der Entwickler von Kotest vorher so gemacht
hat, der hat auch einiges mit Scala zu tun gehabt und ich vermute,
dass er da auch als er dann bei ich glaube nämlich in die Android Entwicklung
eingestiegen ist, dass er dann Scala Testfall vermisst hat,
und sich deshalb daran gemacht hat, was ähnliches für Kotlin zu programmieren.
Das heißt, das ist gar nicht von Jet B1 Kotest. Also es ist gar nicht das,
was Sie offiziell empfehlen für Kotlin, sondern das ist eines von vielen Testframeworks quasi.
Inzwischen gibt es da auch was von Checkpoints direkt selber.
Wobei ich jetzt auch nicht weiß, in welchem Status das ist, also ob das überhaupt
schon so der Peter Stadion verlassen hat oder so.. Keine Ahnung,
habe ich mich nie mit beschäftigt, weil ganz einfach bei uns Kotest schon gesetzt
war, bevor da überhaupt was kam.
Und deswegen hat es sich einfach nicht nicht wirklich gelohnt.
Wir hatten nie den Anlass noch mal zu sagen Na, vielleicht verwenden wir doch das.
Ja. Aber hat es eine gewisse Verbreitung, oder.
Wir hatten halt Kotest schon im Einsatz.
Doch hat es schon. Was man schon sagen muss, dass bei Kotest ist es so,
das besteht aus mehreren Teilen, die man auch unabhängig voneinander verwenden kann.
Ja, das eine ist erst mal das Testframework selber, also der Punkt,
wie schreibe ich Tests in Kotest?
Und dann gibt es noch zwei andere Blöcke, nämlich das Thema Ressourcen.
Und etwas zum Thema Property Property based Testing. Beides kann man halt auch
in Verbindung mit 100 oder irgendwas anderem einsetzen.
Und was ich halt durchaus weiß, dass es relativ viele gibt, die dann im Prinzip
als Testframework drei Unit verwenden, dann aber durchaus die Essenz von Kotest und Ähnliches.
Ja, aber es wird verwendet und soweit ich weiß auch relativ viel.
Ja, aber erst mal noch mal zurück zum Thema Testframework. Was mir da sehr gut
gefällt ist es bietet halt verschiedene Stile an, wie ich Tests schreiben kann.
Also bei June ist es einfach mal so Du hast schreibst eine Funktion,
machst du eine Test Annotation dran und dann ist das ein Testfall.
Ja, genau. Und Annotations.
Die Java Annotation ist alles.
Also ich weiß nicht, das ist vielleicht schon mal ein bisschen angeklungen.
Haben wir noch nicht drüber geredet.
Dass ich nicht so ein großer Freund von Annotations bin.
Bei Kotest ist es so, wie gesagt, es gibt verschiedene Stile und es läuft eigentlich
immer darauf hinaus, dass man eine Testbeschreibung in irgendeiner Form als String hat.
Also es ist nicht wie bei June, dass es die Funktion ist, der man dann einen
Namen gibt, die irgendwie sagt was macht dieser Test? Sondern du hast einen.
Stimmt.
String und da schreibst du was.
Das ist das, was aus der Scala Welt kommt, weil da war das ja auch so gewesen.
Ich schreib quasi einen langen String und der ist dann mein Testname.
Genau. Für mich hat es den Vorteil. Erfahrungsgemäß schreibt man da einfach,
beschreibt man viel detaillierter, was dieser Test eigentlich macht,
als man das macht, wenn man Funktionsnamen verwendet.
Ja, was es dann auch noch gibt, ist immer die Möglichkeit, dass irgendwie so
ein bisschen zusammen zu gruppieren auf verschiedene Arten.
Das hängt dann vom gewählten Stil ab. Also wir verwenden da Funsbeck,
da ist es letztendlich so, wenn man wirklich einen Test schreibt,
dann ist das im Grunde ein Funktionsaufruf Test.
Man übergibt als einen Parameter den Namen des Tests, also die Beschreibung,
und als zweiter Parameter die Funktion, also das, was den eigentlichen Test ausführt.
Und du kannst verschiedene solcher Testfälle dann immer noch in so einem Kontext
Block schreiben, wo du dann halt auch noch mal was zusammenfasst.
Ja, also das bietet sich sehr, sehr oft in Situationen, wo du halt sagst,
okay, ich habe jetzt eine Funktion, die im Erfolgsfall macht,
die das und das, im Idealfall macht sie das und das und dann kann man halt schon
mal diese zwei Sachen Erfolg.
Fehler durch den Kontext abgrenzen und hat dann da drin seine Testfälle ein bisschen gruppiert.
Also es gibt einfach noch mal zusätzliche Struktur, was ich sehr,
sehr angenehm finde und was es für mich auch sehr viel leichter macht,
da dann am Ende auch irgendwie schön dokumentierte Testfälle drin zu haben,
also mit einer ausführlichen Beschreibung.
Ich war. Wir sind unaufmerksam. Auf welcher Ebene findet diese Gliederung statt?
Ich habe einen String, der beschreibt meinen Text.
Dann gebe ich die Funktion rein und da drin verschachtelt ich noch mal, oder?
Das kannst du so machen. Das ist dann halt eine andere Funktion.
Wie gesagt, bei dem Test, den wir haben, der eigentliche Test,
das ist nur ein Aufruf einer Funktion, die Test heißt. Das ist nur ein Konstrukt
von diesem Teststil, also von der Basisklasse, die man da verwendet.
Und genauso gibt es eine Funktion Kontext und da gebe ich halt auch einen String
rein und dann habe ich, ja, übergebe ich halt als zweites auch wieder eine Funktion rein.
Also man hat dann natürlich nicht einen Parameter so mit zwei Aufrufen,
sondern nicht man hat nur diesen einen Parameter und dann runde geschweifte
Klammer auf und darunter den restlichen Code.
Und unterhalb von Context kann
ich halt weitere Kontextblöcke setzen oder Testfunktionen reinschreiben.
Ja, es hat einfach nur so ein bisschen zusätzliche Struktur.
Kann man in der Jugend auch machen, indem man nämlich in die Testklasse noch
weitere Testklassen reinpackt, weitere Klassen, um dann darüber die Struktur zu kriegen.
Wenn mich nicht alles täuscht, war es da in der Kombination für Kotlin dann
immer noch notwendig, dass noch eine zusätzliche Annotation an den inneren Klassen war?
Und ja, zum einen habe ich Annotations nicht sonderlich, zum anderen ich, ich.
Für mich hat sich immer sperriger angefühlt, als dass dieses Konstrukt mit Kontext
und Test und Ähnliches spielt natürlich auch eine Rolle.
Genau das heißt von Scala Test gewöhnt bin und ja, was man gewöhnt ist und lange
Zeit gerne genutzt hat, das will man dann natürlich weiter benutzen.
Wenn sich bewährt hat. Zumindest. Genau. Okay.
Und warum will man überhaupt? Klar, du hast jetzt ja schon ein bisschen die
Vorteile beschrieben, wie die Teststruktur ist. Das spricht natürlich schon
dafür, für Kotlin was anderes zu nehmen, als einfach das zeichnet,
dass es am Anfang auch gesprochen über die es war schon so und so.
Dann kann man wahrscheinlich weiter hinten noch zu.
Also was ist überhaupt der Auslöser was anderes zu nehmen als Zeit Unit?
Einfach nur, weil man es schöner schreiben kann, sag ich mal?
Hm, also für mich war der Auslöser einfach in dem Fall wirklich das,
was ich vorher bei Scala Tests gekannt habe.
Dass ich dann halt in der Java Welt zurück war. Habe gesehen,
wie es mit Religion aussah und dachte immer, das war aber schöner mit Scala Test.
Und dann bin ich halt über Kotest gestolpert und habe das ja auch in dem anderen
Team vorher dann mal vorgestellt. Und da hatten wir ja auch gesagt,
wir verwenden das in Zukunft.
Also der Auslöser bei mir war wirklich ganz massiv, einfach ich. Ich bin daran gewöhnt.
Und dann muss man dazu sagen Es ist natürlich immer schöner,
eine Library zu nutzen, die nativ für diese Sprache entwickelt wurde,
mit der ich arbeite, auch wenn andere Sachen gehen mit der Kompatibilität von
der Kompatibilität her.
Aber es macht halt einfach nicht so einen Spaß, wie wenn eine Library wirklich
nativ für eine Programmiersprache entwickelt ist und dann auch die Möglichkeiten
dieser Programmiersprache entsprechend nutzt. Wenn ich mich richtig erinnere bei Scala.
Da konnte ich doch, glaube ich, direkt mit dem Stream anfangen.
Da war das nicht, dass ich den Stream eine Funktion. Da gibt es ja bestimmt
ne Extension Funktion bei Kotest, die genau das gleiche.
Genau. Genau das ist auch so und das ist halt auch ein bestimmter Stil.
Und da kannst du halt auch genau das machen. Du schreibst String mit deiner
Testbeschreibung und dann hast du irgendwie. Weiß ich nicht. Punkt.
Punkt. Test? Keine Ahnung. Ich weiß es nicht.
Darf es nicht verwenden. Kenne ich es nicht. Aber das ist halt genau einer dieser
Tests. Die viele, viele andere sind dann halt auch einfach inspiriert von dem,
was bei anderen Sprachen passiert, was in anderen Programmiersprachen üblich ist.
Es gibt dann halt auch so einen Test Stil, der ist so vom Behavioral Driven Testing inspiriert.
Da hast du dann so was wie ein wenn um, um das beschreiben zu können.
Ich erinnere mich noch in der letzten Firma, die mit Scala Test angefangen hatten,
da hatten wir sogar ursprünglich mal gesagt, diesen Stil verwenden wir für Integration
Tests und den anderen für Unittests.
Das hat sich da nicht wirklich bewährt und wir haben dann am Ende die ich glaube,
wir Scala Test hieß sie tatsächlich auch Fansbeck, was wir jetzt hier verwenden,
auch generell verwendet für alles.
Die andere ist wahrscheinlich einfach zu dogmatisch. Das klingt erst mal gut.
Mit dieser klaren Struktur, die man da hat. Aber im Praxisalltag passt es halt
einfach nicht immer. Aber.
Ja genau, es passt nicht immer. Du hast dann öfter mal Situationen,
wo dir im Grunde ein Teil davon wurde, nicht sinnvoll angeben kannst.
Und dann, wenn er dann plötzlich anfängt irgendwie was leer zu lassen oder irgendwas
reinzuschreiben, weil man es machen muss, dann wird es auch einfach absurd.
Aber es heißt, am Ende ist es eigentlich egal, welche man nimmt.
Das ist ein bisschen sind Taktik sogar, wie man so schön sagt.
Das heißt, es geht einfach nur darum, wie sieht das aus, wie schreibe ich das Ding runter?
Okay. Ja.
Zur zu dem was man schreibt als Test, Namen und ähnlichem. Auch noch eine Anmerkung.
Ich sagte ja vorhin schon, ich weiß, dass es auch einige gibt,
die dann 200 als Testframework verwenden und dann aber von Kotest die Slogans zum Beispiel.
Und was ich dann auch schon viel gesehen habe, ist, dass dann Leute sagen Naja,
was das Schreiben von Text angeht,
da kann ich dann ja auch in Kotlin sagen, okay, den Funktionsnamen schreibe
ich und dann kann ich da halt auch einfach Text schreiben, also auch mit Leerzeichen drin.
Achso, okay, weil ich Funktionsnamen immer packen kann bei Kotlin.
Genau. Genau. Genau.
Um Sonderzeichen unterzubringen. Ja.
Wer? Wer? Auch eine Option finde ich auch durchaus valide. Also wenn.
Wenn jemand da so sehr an Jay gewöhnt ist wie ich, halt umgekehrt an diesen
anderen Stil, dann kann man das auf jeden Fall auch machen. Damit kriegt man
dann halt auch bessere Textbeschreibung Testbeschreibungen hin.
Wenn sich BTX nicht so schlecht schreiben lassen würden auf einer deutschen.
Genau. Genau. Ich.
Tastatur. Aber da habe ich ein Makro für.
Ich muss auch gestehen, ich habe mich da auch sonst nicht so wirklich mit anfreunden können.
Es ist für mich. Fühlt sich irgendwie immer komisch an und man muss auch bedenken,
man kann nicht jedes beliebige Sonderzeichen in diesem Funktionsnamen verwenden.
Das ist in der Regel kein Problem, aber ich weiß noch, dass ich irgendwo mal
was hatte, wo ich dann eben genau in der Beschreibung eigentlich ein bestimmtes
Sonderzeichen drin haben wollte, was dann nicht ging.
Ich glaube, es ist ein Slash oder ein Wechsel steht nicht oder so.
Und wenn er da nun Testfall hat,
der genau darauf geht und man ihm in der Beschreibung das schreiben will.
Ja, man kann dann besser noch ausschreiben, kriegt man schon hin.
Aber das Problem habe ich halt in dem String nicht.
Probleme, die die Welt bewegen.
Ja, ja, ganz, ganz, ganz gravierend.
Was für mich dabei auch immer so ein Punkt ist, der dazu führt,
dass ich ja da auch nicht so ganz begeistert davon bin, ist,
dass es dann in der Regel so ist, wenn Leute es machen und deswegen gleich dazu
sagen Ja, das würde ich in Produktivcode nie machen. In Testcode finde ich es okay.
Und den Ansatz, den kann ich durchaus verstehen. Und ich mach auch öfter mal
einen Testcode Sachen, die ich in Produktivcode so nicht machen würde.
Aber so ganz grundsätzlich habe ich erst mal einen Test Code,
den gleichen Qualitätsanspruch wie ein Produktivcode.
Hintergrund ist ganz einfach Testcode hat sich in der Regel mindestens genauso
oft an wie Produktivcode, oft sogar öfter.
Und wenn dann der Testcode nicht wahrnehmbar ist, weil man zum Beispiel ganz
viel immer dupliziert, statt es in Funktionen auszulagern, dann ist man irgendwann
in der Situation, dass man sagt ich kann jetzt hier eigentlich den Produktiv
Code nicht anpassen, weil ich dazu die Tests anpassen müsste und das ist zu aufwendig.
Und deswegen finde ich halt immer so, diesen Ansatz zu sagen,
das und das ist ein Testcode okay, aber ein Produktivcode nicht,
den finde ich fragwürdig.
Ich möchte nicht sagen, dass es falsch ist, das wäre zu dogmatisch.
Es hängt immer auch vom Anwendungsfall ab.
Ich finde es generell fühlt sich für mich immer ein bisschen komisch an.
Genau. Ja, kann ich bestätigen. Ich habe das früher auch mal so probiert.
Also ich habe ja nie so viel Text geschrieben wie du.
Weil mit der zu der Zeit, wo ich nicht mehr hauptberuflich entwickelt habe,
da waren Tests noch gar nicht so populär.
Und der größte Teil, den ich dann noch gemacht habe, war Freizeit Projekte.
Aber ja, ich kenne es auch, dass ich am Anfang auch dachte, na ja,
man schreibt ja quasi den Test einfach so runter und im Zweifelsfall dupliziert man den Code auch.
Aber wie du sagst, das skaliert einfach nicht gut. Also hat man irgendwann keinen
Bock noch mal das gleiche runter zu schreiben.
Für Copy und Paste bin ich zu faul, weil da muss man immer viel hin und her
scrollen und irgendwann lohnt sich dann einfach bestimmte Sachen wiederum in Funktion auszulagern.
Was ich immer noch gut fand, war, wenn sich ein Testcase gut runterlesen lässt,
also man gut versteht, okay, jetzt wird das getan, es wird das getan,
es wird das getan und jetzt erwarte ich, dass das und das gegeben ist.
Da finde ich, kann man auch Testcode schreiben, wo das nicht mehr so gut gegeben
ist und dadurch schwer nachvollziehbar ist, was da eigentlich getestet wird.
Stimmt. Wobei das dann meiner Erfahrung nach meistens daran liegt,
dass schon der Produktivcode nicht gut ist.
Denn unübersichtlichen Testest Code vor allem dann, wenn du am Anfang wahnsinnig
viel vorbereiten muss, damit der Produktivcode das machst, was er machen soll.
Und das spricht dann oft dafür, dass entweder der produktiv Code schon zu komplex
ist und man da vielleicht was aufteilen sollte in mehrere Funktionen,
Klassen, was auch immer.
Oder dass man gerade vielleicht auch im Test den falschen Scope hat und halt
irgendwas testet, wo halt der Komplexitätsgrad viel zu hoch ist.
Aber so was lässt sich nicht immer vermeiden. Grundsätzlich weiß ich, was du meinst.
Ich finde es auch immer ganz gut, wenn man auch wirklich ganz klar erkennt hier
wird vorbereitet, jetzt wird der eigentliche Test ausgeführt und da unten kommt
das, was das Ergebnis sein soll. Also meine, meine Erwartungen, meine Versagens.
Ich hatte gelesen, bei Kotest gibt es auch das Konzept der Extensions.
Was verbirgt sich da dahinter?
Ja, das ist in gewisser Weise so eine kleine Plug in Schnittstelle,
dass man Sachen, also gerade wenn dann Sachen irgendwie sehr,
sehr oft verwendet in verschiedenen Tests,
kann man sich halt im Zweifelsfall seine eigene Extension dafür schreiben,
um sagen zu können okay, ich ich häng jetzt nur an einer Stelle eine Klasse
rein und dann passieren so ein paar Sachen einfach automatisch im Hintergrund.
Worum geht es also im Set Up und Clean up oder.
Ja, also ja, zum Beispiel, dass das kann eine Sache sein.
Also es gibt auch einige fertige Extensions, die man nutzen kann,
zum Beispiel für Testcontainer, wo man dann halt auch Hilfscode hat, um sagen zu können.
Okay, ich starte jetzt irgendwie meine Datenbank in einem Docker Container,
weil ich sie für den Test brauche.
Also wir haben, das heißt wir haben unsere eigenen Extensions auch für Integration
Tests geschrieben, wo wir dann halt auch dafür sorgen, dass bevor der allererste
Integrationtest läuft auf jeden Fall alle Container die wir dafür brauchen, oben sind,
und dass am Ende, wenn alle Tests durchgelaufen sind, halt auch alle Container
gestoppt werden und dass im Zweifelsfall halt auf jeden Fall nach jeder Testklasse,
also mindestens das die Datenbank geleert wird, so dass,
jeder einzelne Test Klasse einen sauberen Stand hat.
Und so was kann man ganz gut über Extensions lösen.
Wenn schon mal beim Thema Integration Test automatisch reingerutscht.
Da wird man glaube ich später noch mal drauf kommen.
Dann stelle ich mal meine Frage zur Performance noch zurück und denk hoffentlich noch genau dran.
Ja, ich kann ja versuchen, daran zu denken, dich zu erinnern.
Es ist ansonsten generell so. Ich kann dir nur empfehlen mal auf die Dokumentation
zu lesen, was was Kotest alles kann. Da sind halt noch eine ganze Menge Sachen mit dabei.
Eine Sache, die ich immer ganz schön finde. Sie haben auch bei den Asiaten so
ein Konstrukt, wo du halt sagen kannst,
also du kannst in der Klasse selber sagen, in dem Test so Software und da verschiedene
Sachen rein zu reinpacken und das führt dann dazu, dass so wenn mehrere davon
fehlschlagen, alle ausgegeben ist und nicht immer nur die erste wie das wie.
Na okay.
Das heißt ganz klassisch ist.
Das kannst du auch konfigurieren, dass das generell überall gehen soll.
Dann sollte es in der Theorie so sein, dass man dieses als solche gar nicht braucht.
Klappt in der Praxis nicht ganz. Da habe ich immer mal wieder Situationen,
wo er dann doch nach der ersten Diskussion rausspringt.
Okay, so leicht ein Test so zu schreiben, dass der dann überhaupt weiter funktioniert.
Weil wir sind ja schon darauf ausgelegt, die Testcases, dass wenn ich an der
Stelle eine Session habe, also eine Bedingung nicht gegeben ist,
dass dann die Bedingung danach gar nicht erfüllt sein können oder der Code nicht
fortgeführt werden kann. Aber wie auch immer.
Das ist völlig richtig. Es kann trotzdem zusätzliche Informationen noch raus
geben, wenn man alles kriegt.
Weiß ich nicht. Konkretes Beispiel Ich schreibe einen Test, wo ich dann sage
okay, der der Endpoint liefert mir jetzt ein Ergebnis zurück und der Status
Code muss ein 200 sein und als Body muss der und der Text zurückkommen.
Wenn ich da jetzt entsprechende sowas habe und ich habe eine Software und es
kommen 400 zurück, dann kriege ich halt beide Sorgen und sehe dann am Ende auch
der Body ist jetzt nicht das, was ich erwartet habe.
Das ist ein wenig verwunderlich. Das würde mich dann sogar eher wundern,
wenn trotzdem der erwartete Body kommt.
Aber ich sehe vielleicht, dass da eine bestimmte Fehlermeldung zurückgekommen ist.
Guter Hinweis.
Ja, ähm, was da auch so eine Kleinigkeit auf den ersten Blick,
die aber sehr nützlich sein kann.
Du kannst bei uns immer noch ein uns darüber schreiben, wo du einen Text angibst
und dann kommt halt die eigentliche Ressource dann noch in geschweifte Klammern dahinter.
Das ist immer dann sinnvoll, wenn du irgendwelche Zahlen vergleichst oder du vergleichst den Wert.
Und wenn man zum Beispiel als Rückgabewert true erwartet und es kommt sofort
zurück, dann ist die Fehlermeldung, die du von dem Test kriegst,
des true nicht gleich. Falls ist ja, wo ich halt sage Ja, stimmt.
Should have been true pathos falls.
Aber worum ging es hier eigentlich gerade?
Und das heißt, der Clou wird dann mit ausgegeben. Oder der Clou heißt ja.
Genau. Ja, ja, genau. Ganz genau. Und das muss sein.
Der wird damit ausgegeben, quasi als Hinweis, worum es hier gerade ging. Okay.
Darum muss man sich dann natürlich selber kümmern. Aber man kann es eben auch.
Also, das sind so. So sehr, sehr viel Kleinkram, was einem dann an verschiedenen
Stellen noch die Arbeit erleichtern kann.
Bei dem bei den Associates, was du gerade als Beispiel gebracht habe irgendwas,
bicht ist auch wieder eine Sache.
Ich kenne es halt von Scala tests, wo es dann allerdings zusätzlich die Möglichkeit
gab zu sagen Nee, ich möchte nicht schreiben, ich möchte Mastschreiben.
Ja, ich erinnere mich. Das war ein bisschen übertrieben, aber.
Ja, genau so im Rückblick betrachtet schon.
Für mich führt es einfach auch da wieder dazu, dass der Testcode lesbarer ist.
Zumal ich auch irgendwie. Ich habe so vage in Erinnerung, dass bei den Associates
die dabei June Tests verwendet werden, wo man dann ja oft so was hat wie Escort
Equills und dann halt zwei Objekte.
Das ist für mein Gefühl immer das Set und aktuell vertauscht waren.
Also ich weiß noch, dass ich fast jedes Mal davor saß und dachte Ach so,
nee. Ja, ja, genau. Ach nee, muss andersrum sein, anders als ich es erwartet hätte.
Das finde ich bei dieser Formulierung mit diesem Schutt, was auch immer,
finde ich das irgendwie klarer.
Ja, ich habe halt links das, was ich jetzt als tatsächliches Ergebnis habe.
Genau. Und dann sage ich, das sollte so und so aussehen.
Ja, und da gibt es dann auch eine große Bandbreite an Metaphern.
Also man kann halt jetzt erst mal einfach auf Gleichheit machen.
Man kann eine Kollektion darauf machen, dass sie eine bestimmte Zeit,
eine bestimmte Größe haben, dass bestimmte Elemente drin sind.
Man kann ja dann sogar so was sagen, wie darf nur die und die Elemente enthalten?
Oder wenn man sagt okay, die und die müssen drin sein, ansonsten ist es mir
egal, dann kann man auch das machen.
Man kann sich auch auf die Reihenfolge festlegen. Also dass man sagt,
das muss die Elemente in der Reihenfolge enthalten, wie ich das hier gerade angebe und Ähnliches.
Und man hat natürlich auch da die Möglichkeit, seiner eigenen Natur zu schreiben.
Was gerade wenn sich bestimmte Vergleiche in mehreren Testklassen immer wiederholen,
sehr, sehr angenehm ist.
Und auch da wieder zu sehr lesbaren Code führen kann.
Und ich sehe hier in deinen Notizen, dass man auch ohne Punkte schreiben kann.
Das ist dann ja wahrscheinlich einfach Kotlin Syntax.
Resultat 42 ohne Punkte. Dann hätte ich auch noch wie damals bei Scala damit
auch herumhantiert haben, wo es dann ja so bestimmte Konstellationen gibt.
Wenn eine DSL Botnet Domains language, dass man dann zwischen bestimmten Aufrufen
doch wieder Punkte haben muss.
Frage mich im Nachhinein auch, ob man da nicht manchmal mehr Zeit vergeudet,
damit es irgendwie ein bisschen hübscher im Code aussieht, als es der Realität was bringt.
Also in dem Fall ist es bei Kotlin ist es da auch noch ein bisschen einfacher.
Man kann es nicht unter bestimmten Bedingungen machen.
Letztendlich ist es relativ klar, Die Funktion, die man da aufruft,
muss als Fixfunktion definiert sein.
Bedarf sind natürlich nur einen Parameter haben, sonst klappt es auch wieder nicht. Man.
Na? Aber könnte ich dahinter noch eine Funktion jetzt stecken?
Also, wenn du das machen will.
Also res, also die Partitur weiß nicht end.
Nee, nee, geht an der Stelle nicht. Was man dazu auch sagen muss ich persönlich
bin irgendwie gerade bei diesen Tests bin ich enorm daran gewöhnt,
das ohne Punkt und ohne die Klammern zu haben.
Ich finde es einfach viel lesbarer. Ist aber natürlich auch Gewohnheitssache.
In der Entwicklungsumgebung für die Entwicklungsumgebung ist es tatsächlich
so, dass die damit besser klarkommt, wenn man die Punkte schreibt und die Klammern setzt.
Also das führt jetzt nicht dazu, dass man plötzlich Fehler angezeigt bekommt,
aber es belastet die CPU ein bisschen mehr.
Wenn ich jetzt auf mal merke, ich jetzt auf meinem Rechner auch nicht.
Ja, das habe ich mal in einem Vortrag erzählt, dass mal einer.
Ich hatte es dann mal ausprobiert und dachte okay, gut möglich.
Das war allerdings noch mit meinem alten Mac. Ich habe da jetzt bei dem neuen
nie was gemerkt, aber es hat durchaus was, wenn einem da die Performance enorm
wichtig ist und man hat das Gefühl, das Ganze wird sehr langsam,
dann kann sich in den Tests einfach mal lohnen zu sagen, ich schreibe jetzt
über all die Punkte und setze die runden Klammern dann, dann ist es besser.
Wahrscheinlich brauchen Sie ein bisschen mehr Kontext an der Stelle,
um das sinnvoll auswerten zu können.
Keine Ahnung. Ich kann es mir schon vorstellen, dass das ein bisschen aufwendiger
ist, diese ganzen möglichen Variationen. Aber.
Und du sprachst eben schon von Erweiterung. Das gibt es auch für Sessions.
Auch da ist was, was wir da ganz explizit nutzen. Sind halt Erweiterungen für,
Kater, weil es halt unser Hauptframework ist,
wo dann halt so Sachen machen kannst wie Also du hast ein Request get,
das getestet ist, dann sagst du, es ist schon etwas Status,
2:00 null und dann guckt er eben wirklich in das Ergebnis rein,
wo dann was was hat ja irgendwie ein komplexeres Objekt ist.
Holt sich den Status raus, vergleich den und Ähnliches. Ja, aber.
Was vielleicht noch interessanter für den Inhalt, weil.
Ja, ja, ja, da kannst du durchaus auch was machen. Da wird es dann schon potenziell
ein bisschen komplizierter, weil er dann ja im Zweifelsfall wissen müsste,
was ist das jetzt eigentlich? Ist das ein Jason oder ist das einfach nur ein String?
Ja, aber es gibt halt eine ganze Menge, was man da machen kann.
Und ja, es ist wie gesagt auch wirklich kein Problem, seiner eigenen Natur zu schreiben.
Ja, habe ich auch schon mehr als einmal gemacht ist.
Gibt es da auch was für Asynchronität? Das ist ja auch so ein Problem,
was man in der realen Welt manchmal hat, dass man halt Sachen testet,
die einen Gott, wie ist es denn bei Kotlin? Ich bin voll in TypeScript Welt
unterwegs dienen Promise zurückgeben oder wie auch immer das da heißt.
Also das Problem haben wir so ja nicht, weil das ja alles über Korothins läuft
und die Tests auch in einem Core-Team Kontext laufen. Von daher hat man das nicht.
Okay.
Aber es gibt da durchaus auch so Sachen. Das gehört jetzt gar nicht so sehr
zu den Ressourcen, sondern eher zum Testframework, wo du auch so Aktionen machen kannst wie,
also bei machen dann eventuell die und dann wird halt auch mit einem bestimmten
Timeout, was du auch angeben kannst, auf irgendwas gewartet und wenn es dann
nicht passiert, dann gibt es aber auch einen Fehler und wenn es bis dahin passiert.
Also habe ich mir jetzt, um ehrlich zu sein, auch noch nicht im Detail angeguckt.
Weil wir es einfach nicht brauchen.
Es für uns nicht so weit, nicht so relevant ist. Aber da geht schon auch einiges.
Was ja immer spannend ist, ist das Thema Testdaten.
Wie man damit umgeht. Wo kommen die her?
Das ist ja gefühlt irgendwie das, was bei den Tests auch am meisten Aufwand
macht, den Kram zu entwickeln. Überhaupt das misst fand ich immer das, was lästig war.
Aber bei mir war mal so richtig ein Aufatmen, wenn dann dann die Testdaten gebaut
hat. Jetzt kann ich endlich den Test schreiben, den ich haben will.
Also erst mal dann noch ein Schritt davor. Was bei Kotest auch sehr gut geht,
dass man ein und denselben Test für verschiedene Testdaten ausführt.
Ist jetzt auch sonst keine große Sache. Im Zweifelsfall hat man halt eine Funktion,
die man dann halt mehrfach aufruft in einer Schleife.
Bei Kotest ist es dann immer so, dass man zu einem Kontextblock dann eine Funktion,
zum Beispiel über Data, da gibt es auch noch ein paar Variationen,
da schreibt es als Parameter einen Testdaten rein und dann dahinter der Test, der ausgeführt wird.
Kotest versucht dann immer, aus den Testdaten noch einen Namen zu generieren,
so dass es dann in der Ausführung am Ende so aussieht, als hättest du wirklich,
für jedes Datenobjekt, was du da reingibst, einen Test selber geschrieben,
also manuell eine Testfunktion geschrieben, die dann immer das gleiche macht.
Das heißt der Testname setzt sich dann aus den Daten und wie gut klappt das so?
Wenn es eine Data Class ist, ganz gut. Ansonsten ist es immer sinnvoll,
sich selber was zu schreiben, was man aber eben auch kann.
Also ich kann dann in Numbers Data Blog als erstes eine Funktion angeben,
die mir aus dem aktuellen Datenobjekten Testnamen generiert.
Wie macht er das auch bei Big Data? Klar ist das holt sich dann einfach die.
Am besten, er ruft einfach zu String auf, würde ich mal vermuten.
Property und den Wert, auf den sie gesetzt ist und bildet daraus was.
Naja, okay, gut. Okay. Also ist jetzt kein sprachliches Wunderwerk. Dann an der Stelle. Gut.
Nein, nein, nein. Ja und ansonsten zum Generieren von Testdaten.
Da haben wir halt auch als getrennt verwendbares Artefakt das Property React-testing.
Da gibt es jede Menge Klassen, um sich zufällig Testdaten zu generieren.
Also da kann man halt so Sachen machen. Jetzt ganz simpel und primitiv.
Ich brauche ein bisschen Wert, also gib mir mal einen. Da kann man sich noch
vorstellen, dass das relativ einfach ist, seit er drei oder vier ist.
Man kann dann aber auch zu sagen ich brauche jetzt eine Zahl zwischen eins und 512,
oder ich brauche einen String, der soll zwischen zehn und 500 Zeichen lang sein
und aus den und den Zeichen bestehen.
Ja, es gibt da dann auch noch die Möglichkeit, man kann über so ein bestimmtes
Interface sich dann noch selber Generatoren für eigene Testdaten schreiben,
wenn man halt komplexere Objekte hat, wo dann halt auch letztendlich irgendwie
mit zufalls generierten Daten Felder befüllt werden.
Und was ganz nett ist, dieses Interface bietet dann immer noch eine Funktion
Case, wo man halt, wenn das sinnvoll möglich ist, für dieses Objekt
praktisch sagen kann okay, das das ist so ein Fall, so ein Sonderfall,
der könnte eventuell Probleme bereiten. Von daher.
Den nimmt er dann immer rein, oder?
Naja, nicht unbedingt. Es kommt ja dann darauf an, was du mit diesem Generator machst.
Im Zweifelsfall ist so ein Generator Objekt und dann soweit okay,
ich brauche jetzt noch einen Wert und dann kriegst du einen.
Okay. Okay, gut.
Und das kann dann dieser okay sein. Der muss es aber nicht sein.
Das heißt, wenn ich wirklich den Test mit vielen unterschiedlichen Daten laufen
lasse, dann muss ich mich immer noch selber darum kümmern, dass ich da eine
Schleife aufmache und sage das, was ich jetzt 100 Mal mit 100 zufälligen Werten.
Warum ist das so? Sich nicht selber kümmern. Da gibt es dann auch noch zu den
Generatoren in dem zugehörigen Kompendien Objekt eine ganze Menge Hilfsmethoden,
unter anderem eine List, wo du dann Generator eingibst und sagst Ich möchte jetzt.
100 bis 1000 Objekte davon haben und dann generierte die entsprechende Liste,
die du dann in deiner Funktion mit rein nimmst.
Es gibt dann da auch zusätzlich noch die Möglichkeit. Das kann man natürlich
nicht mit allem machen, dass du zum einen sagen kannst okay,
ich möchte jetzt hier was machen mit einigen der möglichen Werte oder mit allen der möglichen Werte.
Also bei Berlin kannst du was machen. Wenn es jetzt geht um eine ganze Zahl
zwischen eins und 100 kannst du auch noch mit allen machen.
Beim Thema Western.
Beim Integer wird es schwer, oder auch wenn nur ein String von 1 bis 100 Zeichen
hast. Ja, das kriegt man schon auch noch hin.
Abhängig von der verwendeten Zeichenzahl wird es dann schon auch echt heftig.
Ja, aber es ist schon enorm gut, was man da alles machen kann,
um sich einfach Testdaten zu generieren. Und zwar vor allem auch einfach Daten zu generieren.
Die, die dann irgendwie sind. Wenn man selber sich Daten schreibt,
dann hat man in der Regel die Situation, dass man immer wieder die gleichen Namen verwendet usw.
Und da sind dann vielleicht bestimmte problematische Konstellationen gar nicht
drin und man findet vielleicht irgendwelche Fehler nicht.
Hmm. Muss ich mir für Data Classes immer eigene Generatoren schreiben oder gibt
es auch so Mechanismus, dass ich sage hier für die Klasse generiere mal was?
Weil eigentlich enthält die Klasse ja alle Informationen, da ist dann String
drin, der ist optional, das heißt da weiß er, da kann er mal,
ist nicht gesetzt rein setzen, kann aber auch Strings durchprobieren.
Dann gibt es hier noch was weiß ich, Alter als Zahl, um jetzt mal eine Person
abzubilden, dass es eben verschiedene Permutationen durchrechnet.
Oder muss ich mir da für den eigenen Generator, wo ich dann jedes dieser Felder quasi enttäuschend.
Schon selber machen. Ich. Ich meine, ich würde an der Stelle auch sagen,
ganz so einfach wie du das gerade geschildert hast, ist es nicht.
Wahrscheinlich nicht. Ich habe es nicht durchdacht.
Naja, letztendlich, man könnte das schon machen. Die Frage ist,
ob es fachlich sinnvoll ist, denn du kannst ja nicht unbedingt am Feldnamen
erkennen, dass die Zahl jetzt ein Alter ist und dass es deshalb nicht sinnvoll
ist, da eine 500 rein zu generieren.
Passiert in der Realität vielleicht auch von daher. Es kann ja bei zufällig.
Ja.
Generierten Daten genau der spannende Fall sein.
Ja, also es ist halt.
Ich denke, es ist einfach zu schwierig. Ist es dann schon sinnvoller,
selber raufzugucken und auch zu sehen, Was brauche ich hier konkret für Testdaten?
Aber es ist auch so bei dem, was Kotest am mitbringt, dass da eine ganze Menge
Spezialitäten auch noch mit drin sind.
Du kannst jetzt zum Beispiel Vor und Nachnamen generieren lassen.
Ja, dahinter steckt dann irgendeine Liste. Also das ist dann da.
Da merkt man auch, dass es aus den USA kommt. Das sind glaube ich nur englische und spanische Namen.
Okay.
Aber im Zweifelsfall kann man die kannst du da auch sagen, Nimm bitte diese
Liste und kannst deine eigenen Listen generieren.
Domäne werden dann zufällig generiert.
Also ich sage jetzt mal Sabbat um eins. Also, okay.
Ja, genau. Genau. Ja. Dann hast du so Sachen wie die Flughafencodes.
Also bar kriegst du dann raus. Und das sind auch alles real Existierende.
Dann gibt es auch einen Haufen Sachen aus der Kategorie. Ich weiß nicht,
wofür man das braucht. So Eissorten.
Londoner U Bahn Stationen?
Ist auch Schlumpfeis bei.
Keine Ahnung. Ich habe es nicht ausprobiert. Wie gesagt, Londoner U Bahn Stationen.
Und ich glaube, da gab es dann sogar eins, wo man sich halt Wege von Station.
Aber.
Zu Station zu anderen Stationen ausgeben lassen konnte.
Ja, Verdächtige aus Cluedo. Cluedo, Mordwaffen.
Es klingt irgendwie, als wenn da ein paar Leute Langeweile hatten.
Ja, ich. Ich denke, das war dann auch was, als dieses Grundkonzept da war Und
so ein paar Harry Potter Charaktere sehe ich hier gerade.
Na gut, das macht wieder Sinn.
Ähm, ja. Was ich auch interessant fand, so Schachfiguren, Schachfelder und dann
als logische Konsequenz daraus Schachzüge.
Sachzwänge? Nein.
Allerdings ohne Validierung, ob die gültig sind.
Aber trotzdem ist schon einfach eine sehr, sehr schöne Sache.
Ich glaube, das sind im Zweifelsfall Sachen, die guckst du dir mal an,
wenn du vielleicht selber irgendeinen speziellen Fall hast und denkst Ja,
wir haben ihnen das gemacht.
Ja, aber es ist so. Da geht echt wahnsinnig viel. Und.
Ja. Ich fand es extrem hilfreich. Bei uns schon.
Das hat uns das Generieren von Testdaten sehr, sehr einfach gemacht,
weil wir an vielen Stellen uns einfach überhaupt keine Gedanken machen,
sondern dann irgendwo sagen Ja, wir haben hier ein Feld, das enthält ein String
und wir wissen, der muss mindestens ein Zeichen, maximal 255 lang sein.
Also generieren wir uns dafür einen und machen uns auch keinen großen Kopf,
ob das, was dabei rauskommt, wirklich sinnvoll ist.
Nicht. Also bei Vorname macht es eigentlich nicht wirklich Sinn,
wenn man so viele Specials, Slash, geschweifte Klammern und so was mit getestet werden.
Aber es schadet auch nicht. Wer weiß, was die Leute da eingeben.
Genau der Punkt. Es geht ja gerade genau auch darum, die Fälle abzudecken,
die irgendwann mal irgendjemand eingeben könnte,
weil das sind genau die Dinge, die man nicht auf dem Schirm hat.
Und sag mal, wie ist es mit der Bei jedem Test Durchlauf werden dann andere
Daten generiert. Das heißt im positiven Fall heißt es, ich teste viel ab.
Im negativen Fall heißt es aber auch, dass der Test noch durchgelaufen beim
nächsten Durchlauf ist. Schlägt viel.
Also hängt davon ab, was man macht. Im Endeffekt werden die Testdaten halt zufällig
generiert, das heißt irgendwo hat man random mit drin und das wird mit generiert
und das kannst du auch selber setzen.
Wir hatten es bei uns ursprünglich mal so, dass wenn wir ein festgelegtes,
festgelegten Set Wert hatten, was bedeutet.
Das heißt dann generiert er reproduzierbar zwar zufällig, aber reproduzierbar
immer die gleiche Zufallsfolge.
Genau, genau. Was allerdings auch nicht ganz so prickelnd war,
weil wir dann zum Teil die Situation hatten, dass wenn ich ein Test einzeln
ausgeführt habe, ist er durchgelaufen. Wenn ich alle Tests zusammen ausgeführt
habe, ist er nicht durchgelaufen, weil dann andere Daten generiert wurden.
Weil weit mehr generiert wurde und dadurch.
Genau. Genau. Und dann hast du halt sofort auch die Situation,
dass das eben nicht mehr wirklich reproduzierbar ist.
Inzwischen ist es so, dass wir als sieht das das gleiche Problem.
Ich will da auch gerne noch mal was ändern, dass wir jetzt einfach die aktuelle
Zeit nehmen, wo mit Zeit schon noch mal zufälliger wird, weil halt bei jedem
Test wirklich was anderes verwendet wird.
Was ich da schon mal gelernt hatte, ist das Kotest da eigentlich.
Wenn man dann noch die Tests anders schreibt, als wir das aktuell machen,
von sich aus die Möglichkeit sofort mitbringt zu sagen okay,
wenn ein Test fehlschlägt, dann schreibe ich für diesen Test,
Das geht auf die Festplatte.
Also wird eine Datei geschrieben, auch mit dem Testnamen. Und da steht dann
drin, was für ein Set wurde verwendet für diesen Test.
Und wenn er dann den Test noch mal ausführt, wird das aus der Datei verwendet.
Und damit kriegt man in dem Moment dann auch genau die Test,
also die generierten Testdaten, die zu dem Fehlschlag geführt haben.
Das heißt, gerade wenn ein Test fehlschlägt und das wegen Testdaten sehr,
sehr hilfreich, weil man dann kann sich das dann genau angucken und dann versteht
hoffentlich irgendwann, warum der Test fehlgeschlagen ist.
Kann man es fixen, kann es dann noch mal ausführen und weiß dann okay,
das Problem, was jetzt diese Testdaten gebracht haben, das gefixt, das habe ich nicht mehr.
Und das macht dann automatisch, wenn man es entsprechend konfiguriert hat,
in den Fällen, wenn ein Test fehlschlägt. Hm, okay.
Und sag mal, wie ist so deine Erfahrung damit? Ich fand zwar das Schreiben der
Testdaten immer anstrengend, aber dafür haben sie irgendwie den Vorteil gehabt.
Wenn ich dann, wenn da mal ein Test fehlgeschlagen ist, dass ich schon anhand
der Daten häufig wusste, worum es geht, weil die Testdaten quasi von Hand erstellt
waren und dann war halt mein Martin Schulz und dann hat er halt nicht den richtigen User gefunden.
Das ist ja hier dann ein bisschen schwieriger, weil man keinen persönlichen
Bezug zu den Testdaten hat, sondern die sind halt einfach irgendwas Abstraktes.
Das ist auf jeden Fall schwieriger. Ich finde es aber auch nicht so wild.
Also es hat mich bisher noch nie wirklich gestört. Im Zweifelsfall sind es dann
manchmal Situationen, wo es sich halt auch einfach lohnt, noch irgendwo einen
Club oder so was einzubauen, dass man halt selber noch mehr Informationen kriegt.
Den Kontext besser hat, wo was schief gelaufen ist.
Und genau und dann eher versteht, Aha, dass es an der und der Stelle.
Richtig schwierig finde ich es immer, wenn man dann Kollektion vergleicht und
ich dann halt irgendwo eine Liste mit 20 Elementen habe und davon ist eins falsch.
Da wird es dann einfach unübersichtlich. Aber da ist es auch einfach völlig
egal, in welchem Kontext das passiert. Ob ich da mit generierten Testdaten oder
selbst erstellten arbeite, spielt keine Rolle.
Und stell mir gar nicht mehr selber. Also läuft das alles über diesen Mechanismus
oder gibt es da bestimmte Anwendungsfälle, wo man sagt da stehe ich doch von Hand?
Wir erstellen doch von Hand an einigen Stellen. Also konkretes Beispiel Wir
hatten an irgendeiner Stelle einen Test, da haben wir Daten in die Datenbank
geschrieben und dann haben wir geguckt, dass die in der erwarteten Reihenfolge zurückkommen.
Klar.
Ja erwartet. Reihenfolge mit zufällig Testdaten läuft dann darauf hinaus,
dass man da dann am Ende für die Testdaten im Code noch Kotlin sortieren lässt.
Das Dumme ist nur, dass Kotlin anders sortiert als die Datenbank und wir damit
keinen zuverlässigen Test hatten.
In solchen Situationen ist es dann definitiv besser, dass ich sage,
ich schreibe mir selbst meine Testdaten, damit ich halt auch persönlich sagen
kann, das ist die Reihenfolge, die ich erwarte und die teste ich dann.
Kann ich auch so was machen, wie um mir diesen lästigen ich schreib die händisch
selber Fall zu entgehen, dass ich sage okay, ich lass mir die generieren übernehmen.
Das generierte dann in Code, das heißt ab da sind es feste Daten.
Aber ich muss mir nicht diese initiale Überlegung, in den ich den Nutzer jetzt
was hatte für eine Emailadresse, bei welcher Firma arbeitet er,
um mir diesen diesen Kram zu ersparen?
Wobei man da bestimmt auch was generieren kann inzwischen, was man rein testen kann.
Habe ich, um ehrlich zu sein, noch gar nicht passiert. Ich wüsste aber nicht,
er probiert. Ich wüsste nicht, warum es nicht funktionieren sollte.
Im Zweifelsfall müsste man sich ja ein kleines Kotlin Skript dafür schreiben,
was dann die Testdaten generiert und irgendwie ausgibt, dass man dann gut damit arbeiten kann.
Also von daher.
Na siehste, ist sein Freund. Habe ihn gerade mal gefragt. Generiere Testdaten
als Jason für eine Person.
Und dann hat er mir einen Jason rausgehauen, was ich direkt rüberkopieren könnte.
Jetzt für drei Personen.
Ja okay, macht er natürlich auch anstandslos und dann kann man ihm bestimmt
noch vorher eine Deklaration der Klasse reingeben. Und dann hätte man das Problem.
Und dann sich den ganzen Text selber schreiben lassen.
Und dann sich den Tesla schreiben lassen. Ja, genau. Ja, genau.
Also bzw. ihn schreiben lassen.
Also eigentlich die Anweisung des CPT. Teste verdammt noch mal diesen Code. Ja.
Ich weiß nicht, aber gut.
Okay, gut, das passt zum Thema Testdaten. Genau. Finde ich auch immer spannend.
Und jetzt gibt es natürlich noch die spannende Frage, wo es ja auch religiöse,
Ungereimtheiten oder religiöse Meinungen zu gibt. Wie geht man eigentlich mit Macken um?
Hm,
also dazu zuerst mal zwei Ansichten, die ich schon in der Vergangenheit gehört bzw. gelesen habe.
Das eine ist, da war ich mal bei den Scala Days in einem Vortrag von dem Autor von Scala Test.
Und da kam von irgendjemandem eine Frage zum Thema Morgen relativ zum Ende.
Und als ich rausging, hörte ich, wie ein
Entwickler zu einem anderen Thema wahrscheinlich zusammen da war, sagte.
Ich sage ja immer, wer mobbt, ist nur zu faul seine Testdaten aufzusetzen.
Finde ich eine ziemlich radikale Bemerkung. Ich persönlich würde ja sagen,
wer nicht mobbt, testet seine Logik nicht richtig.
Das ist mit Sicherheit genauso radikal und in der Allgemeinheit auch genauso
falsch wie die andere Aussage.
Eigentlich geht es ja auch gar nicht um Faulheit. Ich meine,
bei mir geht es ja einfach darum, gerade bei Tests Sachen raus zu halten,
die ich gerade gar nicht testen will.
Zum Beispiel eine Datenbank, wenn ich ein DAO teste. Das hat ja nichts mit Faulheit zu tun, denn.
Damit kommen wir zu dem zweiten Zitat, was ich bringen wollte.
Ich hatte kürzlich irgendwo auch was.
Da habe ich, glaube ich auch noch irgendwas zum Thema Mobbing gesucht.
Und da bin ich auf einen Artikel gestoßen, wo der Autor dann meinte,
in Unittests sollte man gar nicht merken, wenn überhaupt. In ausgewählten Fällen
in Integration Tests, wo ich davor saß und dachte nee, sehe ich genau umgekehrt.
Also wenn wir es genau andersrum sehen.
Ja, also erst mal als Technologie. Wir verwenden MOOC, dass es da auch wieder,
im Grunde der Punkt, den ich vorhin schon brachte es ist halt in Kotlin geschrieben,
ist es für Kotlin gedacht und da gehen einfach auch Sachen, die man mit Mojito
oder so nicht hinkriegt, vielleicht inzwischen schon.
Da die Kotlin ja relativ weitverbreitet ist, gibt es da natürlich auch von anderen
Frameworks. Dann immer noch Nacharbeiten, aber.
Also ich persönlich bin da auch sehr glücklich. Da geht eigentlich immer alles,
was ich machen will und das auch sehr gut.
Und was machen wir ohne Tests und Integrationtests? Gar nicht.
Und bei Tests ist es halt auch so In Unit Tests merken wir halt quasi die darunterliegende
Ebene, also das, was du gerade schon sagtest, Wenn ich einen Service teste und
der verwendeten DAO, dann ist das Thema Datenbank Zugriff.
Und so ist für mich in dem Moment gar nicht im Scope, sondern ich.
Ich möchte ja eigentlich genau testen Macht der Service das,
was ich erwarte, wenn vom DAO ein bestimmtes Ergebnis kommt?
Und klar, da kann ich mich natürlich auch hinstellen und sagen,
ich schreib jetzt die Testdaten, die ich dafür brauche, in die Datenbank und,
dann habe ich das Ergebnis auch.
Definitiv kein Unittest mehr.
Dann ist es für mich auch kein Unittest, dann ist es ein Integration Test.
Ich brauche die Datenbank dazu. Ich teste das DAO mit, was ich eigentlich eher getrennt testen will.
Außerdem muss man halt sagen, ist es erfahrungsgemäß sehr sehr schwer alle theoretisch
möglichen Fehler Situationen nachzustellen, Denn im Zweifelsfall macht man sich
dann beim Code schreiben plötzlich auch Gedanken.
Ja, was ist denn, wenn jetzt hier mit einem Request die Datenbank wegfliegt?
Vielleicht unrealistisch, unwahrscheinlich, aber auch nicht ausgeschlossen.
Und dann baut man vielleicht irgendwas dafür ein.
Ich erinnere mich noch in der letzten Firma, wo wir uns dann auch noch darum
gekümmert haben, Code zu schreiben, der dafür sorgt, dass genau wenn die Datenbank
wegfliegt, das eben auch ohne Neustart der Anwendung auf jeden Fall die Verbindung
wiederhergestellt wird, wenn die Datenbank da ist.
Da hatten wir ursprünglich mal Tests, dann zwei Datenbanken und ich habe versucht,
dieses, dieses Szenario, sie fällt aus und er verbindet. Sich Danach neu nachzustellen
ist mir einfach nicht gelungen. Und.
Und hätte dann nichts zu tun mit dem realen Datenbankserver.
Genau und sowas sind halt einfach Situationen, wo ich sage, da kann ich in June
Tests. Wenn ich halt die Ebene da drunter gemobbt habe, kann ich alle Fehler,
die ich da irgendwie testen will, kann ich problemlos einfach durch das Mock nachstellen.
Ja, wenn ich da wirklich dann gleich den Integrationstest mache,
in dem ich halt wirklich das darauf folgende und die Datenbank dahinter,
ist das viel, viel schwieriger bis hin zu unmöglich.
Das heißt, da werde ich dann andere Sachen testen als beim als beim Unittest
beim Unittest funktioniert, teste ich die Funktionalität des Services.
Die Fachlichkeit sage ich mal und beim Integrationtest teste ich dann noch ein,
zwei spezifische Fälle, um mal zu prüfen, ob der ganze SDK in sich funktioniert.
Also es ist aktuell bei uns auch so, dass wir für DAOS tatsächlich nur Integration
Tests haben, weil wir da keine Logik drin haben, sondern nur Datenbankabfragen.
Es wäre auch Quatsch, da zu fragen Ist jetzt das und das SQL Statement rausgekommen?
Ja, es ist auch irgendwie spannend, aber meistens ist es da auch so dumm,
dass da nicht so furchtbar viel Logik drin ist.
Und dann macht es nur Sinn, das auch wirklich mit einer Datenbank zu testen.
Ja eben. Und da haben wir halt auch von der Version die gleiche,
die wir in der Produktion einsetzen.
Nein, stimmt gerade aktuell nicht. Da müssen wir mal updaten.
Aber das ist eigentlich das Ziel. So ist man halt. Da testen wir gegen das,
was wir auch in der Produktion verwenden.
Und ja, damit haben wir da auch eine gewisse Sicherheit, dass es so läuft, wie wir es haben wollen.
Ja, aber auf DAO Ebene haben wir wirklich nur Integration Tests darüber.
Also sowohl für die Services die wir haben, als auch für die die End Points,
also die die Controller da in gewisser Weise.
Da haben wir auch Integration, Unittests. Das geht ja auch ganz gut,
dass man dann halt wirklich sagen kann, ich habe.
Ja keinen echten Server, der ja hochgefahren ist, aber halt schon so ein bisschen
was, das auch wirklich die Requests simuliert werden und dann halt entsprechend
weiterverarbeitet werden.
Wie das in der Realität auch passiert. Und dann kann ich halt schön abtesten,
dass ich halt auch das erwartete Ergebnis zurückbekomme.
Ja, und dann haben wir halt zusätzlich auch auf der Controller Ebene noch mal
Integration Tests, wo wir dann halt auch noch mal wirklich die komplette Kette
durchgehen, also vom Requests bis zur Datenbank und wieder zurück.
Abhängig vom Request prüfen wir dann auch durchaus noch mal,
dass auch in der Datenbank das passiert ist, was wir erwartet haben.
Und ja, da ist es dann aber so, dass wir jetzt nicht mehr versuchen,
jeden Fehler nachzutesten.
Sagen wir halt also, für das, was der Service da Spezielles macht,
haben wir die Unittest vom Service.
Für das, was ihm da so passieren kann, haben wir die Integration Tests vom DAO,
sondern da haben wir so die Philosophie, Happy Pas und vielleicht noch so ein,
zwei zusätzliche Sachen, aber das war's dann auch.
Aber das heißt bei Integration Tests haben wir durchaus auch mehrere Ebenen.
Also du sagst, ihr testet sowohl den DAO als auch vom Controller aus,
also vom REST-Endpoints aus. Das haben wir schon. Beides.
Das haben wir schon ein weiteres Jahr. Denn wie gesagt, in den da wo ich die
die Endpoints teste, da möchte ich dann nicht mehr irgendwelche Spezialitäten,
die im DAO auftreten können, testen. Das mache ich halt in einem Integrationtest für DAO.
Könnte man natürlich auch zusammenfassen. Ich finde es so ein bisschen besser,
weil ich dann halt auch bei einem Fehler im Zweifelsfall genauso.
Ja, das ist jetzt kein Problem da so und nicht an einer anderen Stelle.
Wie sieht es bisher mit der Performance bei den Integrationtests aus?
Man darf sich da keine Illusionen machen. Integrationtests sind immer ein bisschen
langsamer als die Tests, wobei wir da ein paar Sachen auch gerade noch ungünstig
machen. Da sind wir noch auch selber so ein bisschen in der Lernphase.
Aktuell haben wir viele Stellen, gerade wenn wir größere Datenmengen abrufen, anlegen.
Das dann weiß ich nicht. Wir wollen jetzt für den Test 100 Teams haben.
Dann läuft es gerade darauf hinaus, dass jedes Team einzeln angelegt wird statt
in einem Batch alle 100 zusammen.
Und dass es dann rein von der Vorbereitung des Tests ist. Dass es dann schon
relativ langsam ist, werden wir auch mit Sicherheit umstellen.
In der Anfangsphase hatten wir es tatsächlich mal so, dass wirklich alle Tests
da komplett unabhängig voneinander waren.
Also für jeden Test wurde ein Postgres gestartet und ein CIC log,
und das haben wir dann irgendwann mal so umgestellt, dass das halt,
wenn die Tests laufen, alles genau einmal passiert und dann für alle Tests das
gleiche verwendet wird, die aber mit verschiedenen Daten arbeiten.
Also jeder Test hat einen anderen Kunden, den er praktisch verwendet,
sowohl bei anderen RAM als auch bei uns in der Form Vorgangs Management in der
Datenbank. Es ist auch was anderes.
Und seit dem sind die halt auch ein ganzes Stück schneller geworden.
Aber das, was wirklich die meiste Zeit frisst, ist das Anlegen der Testdaten,
und zum Teil auch das Überprüfen.
Also ich habe jetzt zum Beispiel gerade zum Thema Löschen einen Test geschrieben.
Also das betrifft jetzt wirklich nur DAO, wo ich jetzt sage,
okay, ich will gerne noch mal überprüfen, dass wenn ich den einen Kunden lösche,
dass sich bei anderen Kunden, die auch da sind, nichts ändert.
Guter, guter Test.
Ja, und in den Testdaten werden halt wirklich zufällig mehrere Kunden angelegt.
Zehn Stück hatte ich glaube ich genommen mit verschiedenen Teams,
mit vielen Usern, das heißt alles zufällig generiert und dann.
Was ich mache ist, dass ich einmal am Anfang, bevor ich das Löschen mache,
zähle ich alle Tabellen durch und zwar für jeden Kunden einzeln,
um nachher sagen zu können, für diesen Kunden waren so und so viele Nutzer in
der Datenbank, für diesen so und so viele usw.
Dann wird halt das Löschen aufgerufen und danach zähle ich noch mal alles durch,
um halt dann vergleichen zu können, okay, bei dem Kunden, den ich löschen wollte,
da ist jetzt wirklich nichts mehr da.
Bei allen anderen ist es unverändert und allein dieses Zählen dauert erschreckend lange.
Aber die anderen sind gleich geblieben.
Das ist natürlich ein klassischer Testfall, wo manuelle Testfahrten auch wieder
interessant wären, weil da natürlich gleich ein Use Case interessant ist,
dass dann noch irgendein User beim anderen Kunden haargenau so heißt oder die
gleiche ID hat oder wie auch immer.
Gleichzeitig wird sich aber der gleiche primäre Merkmale irgendwie.
Ja, prinzipiell ja. Praktisch hat das für mich bei dem Test nicht so die Relevanz,
weil wir unser Datenmodell so angelegt haben, dass alle Tabellen,
die die hat, irgendwie kundenspezifisch sind.
Da haben wir ja unsere eigenen Tabelle und dann haben wir haben die anderen
Tabellen, haben alle von uns die Beziehung dahin und das ist immer mit Calling Glied eingerichtet.
Und der große Vorteil ist halt, dass ich beim Delete ich lösche wirklich nur
den Eintrag in der Tabelle.
Alles andere passiert automatisch und da vertraue ich dann halt schon auch ein
Stück weit der Datenbank, dass sie das richtig macht.
Und natürlich unseren Queries und der Art, wie wir die Anfragen machen.
Ja, Ja, ja.
Dass wir die richtig machen, dass es nicht zu einer Löschung an einer anderen Stelle führt.
Naja, die Löschung kann eigentlich nicht an anderer Stelle passieren,
weil ich wie gesagt, ich lösche ja nur den Eintrag in der Tabelle.
Alles andere passiert ja automatisch.
Die anderen Tabellen fasse ich manuell überhaupt nicht an. Das macht nur Postgres.
Aber da ich halt nicht quasi jetzt noch in der Usertabelle irgendwas lösche,
wo ich irgendwelche Bedingungen habe, wo ich halt sage okay.
Okay.
Da können nicht. Wenn jetzt der Nutzer bei dem Kunden gleich heißt,
könnte es Probleme geben.
Situation habe ich nicht und damit halte ich es auch jetzt nicht unbedingt für
nötig, das unbedingt zu testen. Aber ansonsten hättest du recht.
Also manuelle Testdaten hätte da natürlich den großen Vorteil,
dass ich wüsste, wie viel nachher übrig sein müsste. Ich müsste nicht so viel
zählen in der Datenbank, aber gut.
Es ist ja auch ein zweischneidiges Schwert. Also es ist natürlich super cool,
die ganze Sicherheit zu haben und ich glaube, das ist heutzutage eigentlich auch fast unstrittig.
Aber natürlich bin ich schon manchmal in der Situation, dass irgendjemand kommt.
Ach Mensch Sven, ich war da gerade auf einer Messe gewesen und da ist ein anderer
Anbieter und der hat nur fünf Entwickler.
Und wer macht den dreifachen Umsatz von uns?
Und der Gründer hat ja auch selber mitentwickelt und die kriegen es auch hin.
Und manchmal fragt man sich auch warum dauert das bei uns so lange?
Und? Was würdest du dazu sagen? Weil ich glaube, einer der großen Unterschiede
wird sicherlich sein. Zum Beispiel das Thema Testabdeckung.
Und was ich bei euch auch schon häufiger gehört habe oder was ich auch selber
kenne, ist, da hat man dann mal eine Änderung, die man vornehmen will,
gerade in so einer frühen Phase des Produkts oder Projekts, wo alles noch so
ein bisschen im Fluss ist.
Und dann sagt man ja die Änderung, die hätte eigentlich in zehn Minuten erledigt.
Aber die Tests habe ich bestimmt einen halben Tag, einen Tag mit beschäftigt,
bis ich das dann zurechtgebogen habe, dass das wieder funktioniert.
Was sind so deiner Meinung dazu?
Also die die Erfahrung so extreme hatte ich noch nicht.
Es ist schon tendenziell so, dass ich auch sagen würde also ich habe so das
Gefühl, Produktiv Kotest Code, das ist nicht so Hype Hype, sondern eher so 1/3, 2/3 vielleicht.
Also keine Ahnung, ist jetzt einfach nur ein großes Gefühl.
Allerdings. Also es ist schon ein zweischneidiges Schwert. Es kostet auf jeden
Fall Zeit. Da darf man sich keine Illusionen machen.
Ich kann halt jetzt schon sagen, gerade am Anfang, wo man, wo auch so viel noch
nicht fest steht und so viel im Fluss ist, sind Tests auch wieder sehr wertvoll.
Denn was ich jetzt noch gar nicht hatte, war die Situation, dass ich praktisch
sagen konnte okay, ich habe jetzt, ich will jetzt hier was umbauen.
Und die Tests, die es bisher gab, die sind, die kann ich dann auch alle neu
schreiben, die sind wertlos, weil ich halt einfach alles so massiv umstelle,
alles so massiv anders wird, dass die bestehenden Tests gar nicht mehr bringen.
Es ist schon oft so, gerade bei diesen Integrationtests auf Controler Ebene,
da da dann halt auch ein Request auf irgendeinen Endpoint kommt.
Solange die API stabil ist, also solange wir nicht URLs anpassen und zwar im
größeren Umfang anpassen, liefern die mir immer noch ein Ergebnis, was mir sagt okay.
Zumindest der Happy Pastewka getestet ist. Der funktioniert immer noch.
Der sieht von außen immer noch gleich aus.
Und ansonsten hast du im Zweifelsfall oft auch Situationen, dass du irgendwas
umbaus und dann anhand der Tests erkennst.
Ah, okay, okay, in Tests wird noch irgendein Spezialfall behandelt.
Den habe ich jetzt aber so gar nicht mehr. Also der Test funktioniert.
Also selbst wenn ich ihn jetzt so weit anpasse, dass es wieder zu den Änderungen
passt, die ich gemacht habe, dann habe ich hier einen Spezialfall getestet,
den es gar nicht mehr gibt.
Dann habe ich halt sofort auch noch mal den Rahmen da.
Stimmt das, dass der keinen Sinn mehr gibt oder bräuchte ich ihn eigentlich
immer noch? Also fehlt mir jetzt irgendwas? Habe ich was unterschlagen oder
gegebenenfalls war das ja auch der Grund für den Umbau, den ich gemacht hatte,
es da irgendwo ganz viele Spezialfälle drin waren, die ganz komisch waren.
Dann kann ich sagen, den kann ich jetzt löschen, den Test brauche ich nicht mehr.
Ist dann auch eine schöne Sache. Ich Ich weiß nicht, ob man so so ohne Weiteres
klar sagen kann, es bringt in Summe was oder es bringt nichts. Ich denke schon.
Es gibt ganz viele Umbauten, die würde ich mich ohne Tests nicht trauen.
Da würde ich sagen Ja, ich habe keine Ahnung, was ich danach manuell alles testen
muss, damit ich weiß, es funktioniert noch alles so, wie es ist.
Da verlasse ich mich an vielen Stellen dann schon einfach auf die Tests und
mache danach nur noch irgendwie so einen Smoke Test und da bringt es dann schon auch definitiv was.
Also bei mir ist es auch so Wenn ich über die Produktlebenszeit gucke,
also die den gesamten Zyklus eines Produkts, dann bin ich zu 100 % davon überzeugt,
dass es bombastisch viel Zeit spart,
weil was man alles manuell testen müsste, wenn er diese Sachen nicht hätte und
wie unsicher es wäre, Refactorings durchzuführen oder technische Umbauten,
die einfach notwendig sind.
Das könnte man alles überhaupt nicht tun, wenn man diese Tests nicht hat.
Wenn man natürlich so diesen MVP Minimal variable Produktpad vor Augen hat,
fragt man sich manchmal auch Boah, vielleicht sollten wir doch erst mal zusammen,
dass man ein Produkt haben und dann anfangen, die Tests einzuziehen.
Dann hat sich auch alles ein bisschen gesattelt und alles ist zurechtgerückt.
Auf der anderen Seite ist natürlich gleich das Problem, Ja, dann habe ich die
Software auch nicht entwickelt und weiß gar nicht, ob ich hinterher noch die Testschreiben kann.
Und auf der anderen Seite wird natürlich auch kein Unternehmen hingehen und
sagen Ja, super, jetzt haben wir nach einem Jahr Entwicklungszeit den P rausgehauen,
dann setzen wir uns jetzt mal ein Jahr hin und schreiben die Tests.
Und wahrscheinlich wird es dann
sogar ein Jahr dauern, wenn er die gleiche Abdeckung haben wollen würde.
Also von daher stellt sich für mich für ein qualitativ hochwertiges Produkt,
was dann auch lange im Markt ist und viele Kunden haben soll.
Stellt sich die Frage einfach in 2023 nicht mehr?
Sind Tests sinnvoll? Oder sind sie nicht?
Was ich auch ganz spannend finde, ist die Frage Gibt es irgendwo ein Mittelweg,
wo man vielleicht sagen kann, gibt es irgendwelche Sachen, die besonders viel,
Aufwand in der Erstellung und in der Pflege erzeugen.
Die natürlich auch nützlich sind?
Aber wo man zum Beispiel sagen könnte, wenn man das weglassen würde,
dann könnte man es ein bisschen beschleunigen und hätte nur ein bisschen Sicherheit eingebüßt, quasi.
Genau das ist für mich. Sind für mich diese Zufalls generierten Testdaten etwas,
was sehr, sehr viel Performance bringt?
Also bei der Testentwicklung dann, wie du schon sagtest, dieses Testdaten schreiben.
Das ist enorm aufwendig. Da macht man sich dann auch oft wahnsinnig viele Gedanken.
Furchtbar. Ja.
Auch viel mehr als notwendig wären.
Ja, dann fängt man plötzlich darüber an, darüber nachzudenken,
wie geht es einem Teammitglieder hin zu.
Oh, jetzt habe ich acht Männer und zwei Frauen. Wie sieht denn das aus?
Was sagt das über mich aus?
Also es ist jetzt ein relativ billiges Beispiel, aber.
Ja, finde ich gut.
Auch auch an ganz anderen Stellen, denn dann fängt man dann an,
Zeit damit zu verschwenden, dass man Teams anlegt und dabei Teamnamen wählt,
die irgendwie sinnvoll sind, obwohl das für den Test völlig egal ist. Es spielt keine Rolle.
Vollkomiker. Ich. Ich kenne das.
Was für Zwängen man da unterliegt, wenn man sich einfach nur Testdaten ausdenken
soll. Das ist schockierend. Aber.
Und so wie wir es jetzt haben, auch mit dem Framework sage ich halt okay,
ich brauch jetzt für diesen Test 20 Teams, legt mir die mal an,
Punkt, und dann sind sie da und das geht dann halt alles relativ fix.
Auch da muss man sagen, da hatten wir durchaus eine gewisse Lernkurve.
Und ich habe auch jetzt bei der Vorbereitung auf diese Episode wieder so ein
paar Sachen gelernt, wo ich dachte ah, okay, das hätten wir uns einfacher machen
können, wenn ich das gewusst hätte.
Und es gibt da noch so ein paar Sachen, die wir anpassen wollen.
Aber so im Großen und Ganzen ist es halt so, dass wir da inzwischen Framework
haben, was einfach ganz gut funktioniert und was uns da auch echt Zeit bringt.
Also dann Testdaten in der letzten Firma. Ich glaube, wir hatten am Ende zwei
oder drei verschiedene DSL zum Test Daten anzulegen, weil wir immer mit irgendwas
angefangen haben und dann irgendwann feststellen ach Mist, das greift jetzt
hier nicht mehr. Wir bräuchten jetzt hier eigentlich irgendwas anderes und.
Stimmt. Dann verbringst du Zeit damit DSL zu schreiben, denn das die den Code
wollen, weil du mußt die Testdaten ja irgendwo rumzuliegen haben,
dann versuchst du die bestehenden Testdaten so zu erweitern,
dass sie für möglichst möglichst viele User, also für möglichst viele Testfälle, gültig sind.
Womit du denn bei einem Testfall Testdaten hast, die vollkommen okay sind.
Also sind alles bekannte Probleme, die dadurch adressiert werden.
Das wäre wirklich sehr spannend.
Ja genau. Und wie gesagt, es hat uns enorm beschleunigt, das zu machen.
Ansonsten ja, man, man muss sich da einfach auch mal selber bremsen und dann
irgendwann überlegen, was was lohnt sich jetzt hier wirklich noch abzudecken.
Ja, aber auch da ist es so, dass dieses Arbeiten mit also nicht nur das Arbeiten
mit automatisch generierten Testdaten, sondern auch solche Blöcke,
wo ich halt ein und denselben Test mit verschiedenen Daten ausführe.
Das macht es auch zum Teil sehr, sehr einfach, halt ganz, ganz viele Konstellationen
ab zu testen mit sehr wenig Aufwand.
Ja, also nehmen wir mal an, jetzt mal ganz, ganz primitiv gedacht.
Ich habe mir irgendwie meinen HTTP Client geschrieben und will jetzt am Ende
gucken, dass da irgendwie der, der den aufruft, mit allen Fehlerquellen,
die auftreten können, umgehen kann.
Ja, dann gibt es irgendwo in irgendeiner Bibliothek bestimmt mal alle möglichen
HTTPstatuscodes, also alle offiziellen, also alle Standardcodes als Namen kann
ich mir mal alle Werte holen,
daraus die Erfolgswerte rausfiltern und dann halt sagen, Ich hoffe jetzt diese
Testfunktion mit denen auf und kann so testen, dass egal was da für einen Statuscode
kommt, man nicht irgendwie eine Explosion wirft, sondern immer das macht, was sie erwarten würde.
Ja, und das macht schon vieles sehr viel einfacher und damit auch sehr viel schneller.
Wobei man da natürlich aufpassen muss. Klar ist einfach dann möglichst viele
Varianten durchzutesten. Aber über die Zeit hinweg wird es natürlich auch die Tests machen.
Auch wenn man jetzt eine Schleife mit 100 Statuscodes, die wird jetzt irgendwie.
Da kommt.
Für ein Unit Test nicht ewig dauern, aber.
Ja. Ich wollte gerade sagen, es kommt drauf an, wo man das macht.
Also bei Integration Tests muss man auf jeden Fall vorsichtig sein.
Da tut es richtig weh.
Da kann es schon in der Performance einen relevanten Unterschied machen,
ob ich sage, ich arbeite jetzt hier mit zehn Teams oder ich arbeite mit 100.
Meine bisherigen Erfahrungen aus den Unittests ist das jetzt praktisch keine Rolle.
Also da kannst du auch mal sagen ach was soll's, ich habe 1000 Teams und arbeite
mit denen. Das geht immer noch ratzfatz.
Na gut, dann ist es definitiv Zeit für.
Es ist nicht wirklich die Erkenntnis der Woche, hat aber mit der Episode zu tun in dieser Woche.
Unser Offside war einfach zu wenig, als dass ich da eine besondere Erkenntnis hätte treffen können.
Du darfst auch die Wochen bis zur letzten Episode nehmen.
Nee, es geht generell auch noch um diese automatisch generierten Testdaten.
Prinzipiell bin ich davon überzeugt, ist super. Man muss allerdings auch immer
damit rechnen, dass man damit total auf die Nase fällt und ganz komische Sachen
passieren und nicht reproduzierbare Sachen.
Eine wichtige Sache ist bei Sachen, die eindeutig in der Datenbank sein müssen,
darauf zu achten, dass die Feldlänge lang genug gewählt wird,
Nicht Also als Beispiel bei uns. Der Teamke kann von theoretisch von 1 bis 8 Zeichen lang sein.
Wenn ich das jetzt generieren lasse und dabei genau dieses Peter nehme 1 bis
8 Zeichen und ich lasse mir dann 100 Teams generieren, dann ist leider die Wahrscheinlichkeit
schon relativ hoch, dass ich einen Konflikt kriege, weil er mir halt zweimal
ein Team mit Namen mit CIA generiert oder ähnliches.
Ja, also da gab es ein paarmal Situationen auch gerade.
Abhängig davon, was für einem sieht man dann arbeitet. Wo wir wirklich davor
saßen und dachten verdammte Scheiße, warum läuft der Test bei mir localhost
durch und auf dem Server nicht aufgeht?
Oder warum läuft er durch, wenn ich ihn einzeln ausführe, aber nicht,
wenn ich alle zusammen ausführe und umgekehrt.
Und irgendwann, das war halt so bei den Teamcis, das war auch bei den Usern
so, dass wir dann irgendwann angefangen haben, so die Mindestlänge für die generierten
Daten immer größer zu wählen.
Also wenn man es einmal verstanden hat, dann weiß man irgendwann auch,
worauf man achten muss. Aber am Anfang saßen wir davor und haben wie immer so
schön geguckt wie das Schwein ins uhrwerk, weil es halt echt überhaupt nicht verständlich war.
Warum, Warum? Wie kommt das aber?
Und nichts hasst man mehr als Entwickler, wenn dieser Kram das hier eigentlich
durchläuft. Aber lokal, das ist dann wieder so, diese Willkürlichkeit ist jetzt
in der Umgebung irgendwas anders. Ja, spannend.
Ja, ja. Also im Ganzen war es auch für uns erst mal völlig willkürlich,
aber irgendwann dann mal verstanden.
Achso, okay. Und ich glaube, ich habe auch in zwei Schritten,
da die Mindestlängen inzwischen ein ganzes Stück angehoben.
Der Benutzername muss jetzt, glaube ich, mindestens zehn Zeichen lang sein,
dann ist man schon auf der sicheren Seite. Aber auf die Idee muss man halt auch erst mal kommen.
Hmmm. Und gibt es da irgendwie die Möglichkeit, dem Generator zu sagen,
dass es keine doppelten Werte generieren?
Interessante Frage, habe ich noch gar nicht geguckt, aber ich glaube erst mal nicht bzw.
Was man schon machen kann. Da müsste man dann halt aber auch selber eingreifen,
dass ich praktisch sage, ich hol mir erstmal eine Liste, die viel,
viel größer ist als das, was ich brauche und hol mir dann die raus, die ich haben will.
Also die, also dass ich dann selber über Filter dafür sorge,
dass keine Doppelten drin sind und Ähnliches.
Für uns war es in dem Fall einfacher zu sagen, wir erhöhen einfach die Mindestlänge,
um auf die Art und Weise in eine sichere Situation zu geraten.
Es ist eine spannende Frage. Ich muss mal nachgucken, ob das nicht vielleicht
sogar noch einfacher wäre.
Gut. Ja. Dann haben wir es geschafft. Dieses Mal ein bisschen über der Zeit.
Aber ist ja auch ein spannendes Thema.
Und dann werden wir sicherlich noch mal eine Episode machen zum Thema Frontend
Testing. Ansonsten Feedback auf der Website.
Oder ein schöner Satz schon. Tschüss.
Benjamin
00:00:42
Sven
00:00:46
Benjamin
00:01:19
Sven
00:01:22
Benjamin
00:01:30
Sven
00:02:27
Benjamin
00:02:37
Sven
00:03:02
Benjamin
00:03:03
Sven
00:04:11
Benjamin
00:04:15
Sven
00:04:20
Benjamin
00:04:20
Sven
00:04:39
Benjamin
00:04:41
Sven
00:04:43
Benjamin
00:04:50
Sven
00:06:10
Benjamin
00:06:20
Sven
00:07:51
Benjamin
00:08:18
Sven
00:08:46
Benjamin
00:09:20
Sven
00:10:23
Benjamin
00:10:32
Sven
00:10:47
Benjamin
00:11:01
Sven
00:11:36
Benjamin
00:11:39
Sven
00:11:41
Benjamin
00:11:45
Sven
00:11:58
Benjamin
00:12:02
Sven
00:12:02
Benjamin
00:12:05
Sven
00:12:45
Benjamin
00:12:46
Sven
00:14:02
Benjamin
00:15:07
Sven
00:16:02
Benjamin
00:16:08
Sven
00:16:29
Benjamin
00:16:29
Sven
00:17:26
Benjamin
00:17:38
Sven
00:18:13
Benjamin
00:18:14
Sven
00:18:31
Benjamin
00:18:48
Sven
00:19:24
Benjamin
00:19:25
Sven
00:19:58
Benjamin
00:20:03
Sven
00:20:04
Benjamin
00:20:07
Sven
00:20:08
Benjamin
00:20:14
Sven
00:20:43
Benjamin
00:20:46
Sven
00:22:33
Benjamin
00:23:05
Sven
00:23:22
Benjamin
00:23:26
Sven
00:23:27
Benjamin
00:23:32
Sven
00:24:33
Benjamin
00:24:38
Sven
00:24:45
Benjamin
00:24:52
Sven
00:25:21
Benjamin
00:25:24
Sven
00:25:48
Benjamin
00:26:02
Sven
00:26:07
Benjamin
00:26:13
Sven
00:26:38
Benjamin
00:26:38
Sven
00:26:45
Benjamin
00:27:09
Sven
00:27:57
Benjamin
00:28:03
Sven
00:28:15
Benjamin
00:28:18
Sven
00:28:19
Benjamin
00:28:27
Sven
00:29:47
Benjamin
00:29:50
Sven
00:30:00
Benjamin
00:30:01
Sven
00:30:04
Benjamin
00:30:15
Sven
00:30:57
Benjamin
00:30:58
Sven
00:31:40
Benjamin
00:32:10
Sven
00:32:17
Benjamin
00:32:18
Sven
00:32:33
Benjamin
00:32:35
Sven
00:32:36
Benjamin
00:32:38
Sven
00:33:08
Benjamin
00:33:08
Sven
00:33:18
Benjamin
00:33:22
Sven
00:33:41
Benjamin
00:33:43
Sven
00:33:47
Benjamin
00:33:52
Sven
00:34:01
Benjamin
00:34:04
Sven
00:34:11
Benjamin
00:34:12
Sven
00:34:19
Benjamin
00:34:21
Sven
00:35:22
Benjamin
00:35:45
Sven
00:36:06
Benjamin
00:36:09
Sven
00:36:23
Benjamin
00:36:25
Sven
00:37:45
Benjamin
00:38:22
Sven
00:38:36
Benjamin
00:38:38
Sven
00:39:03
Benjamin
00:39:10
Sven
00:39:24
Benjamin
00:39:24
Sven
00:39:54
Benjamin
00:40:24
Sven
00:40:41
Benjamin
00:41:04
Sven
00:41:07
Benjamin
00:41:08
Sven
00:41:11
Benjamin
00:41:17
Sven
00:41:21
Benjamin
00:41:40
Sven
00:42:27
Benjamin
00:42:38
Sven
00:43:00
Benjamin
00:43:02
Sven
00:44:19
Benjamin
00:44:20
Sven
00:45:21
Benjamin
00:45:23
Sven
00:45:47
Benjamin
00:46:07
Sven
00:46:16
Benjamin
00:46:29
Sven
00:48:08
Benjamin
00:48:20
Sven
00:48:45
Benjamin
00:48:52
Sven
00:50:31
Benjamin
00:50:32
Sven
00:51:09
Benjamin
00:51:36
Sven
00:52:13
Benjamin
00:52:17
Sven
00:52:17
Benjamin
00:52:20
Sven
00:52:41
Benjamin
00:52:41
Sven
00:53:08
Benjamin
00:54:18
Sven
00:56:57
Benjamin
00:58:40
Sven
00:58:52
Benjamin
00:58:55
Sven
00:59:12
Benjamin
00:59:13
Sven
00:59:24
Benjamin
00:59:32
Sven
01:00:24
Benjamin
01:00:49
Sven
01:02:12
Benjamin
01:02:22
Sven
01:02:25
Benjamin
01:02:27
Sven
01:02:31
Benjamin
01:02:34
Sven
01:02:54
Benjamin
01:03:12
Sven
01:03:23
Benjamin
01:03:26
Sven
01:05:02
Benjamin
01:05:12
Sven
01:05:36
Benjamin
01:05:44
Sven
01:06:23
Feedback geben
Wir freuen uns über Dein Feedback – sowohl zu unseren technischen Erlebnissen und Entscheidungen als auch zu unserem Podcast. Gibt es vielleicht ein Thema, dass Du gerne behandelt haben möchtest? Dann kontaktiere uns hier gerne.