Transcript: PyTest
Full episode transcript. Timestamps refer to the audio playback.
Ja, hallo liebe Hörerinnen und Hörer, willkommen beim Python-Podcast, Episode 53 mit PyTest.
Hi Jochen.
Ja, hallo Dominik, willkommen.
Ja, mein Gast dabei, und zwar den Florian. Hey Florian.
Hallo.
Ja, hallo zusammen.
Ja, wir haben gehört, du machst ja öfter mal was mit PyTest und dann haben wir gedacht,
dann fragen wir dich doch einfach mal, ob du mich was darüber erzählen magst.
Genau. Ich weiß nicht, vielleicht magst du ja einfach mal so ein bisschen erzählen,
was du so tust oder irgendwie, warum PyTest da ein ganz gutes Thema wäre.
Was ich so tue, ist schon eine Frage, da kann ich wahrscheinlich fünf Minuten dazu reden.
Geh los.
Ich mache tatsächlich so fast Vollzeit-Open-Source, und zwar kam das nicht von PyTest ursprünglich,
sondern von einem anderen Projekt von mir, von Qt-Browser, da kann ich vielleicht später noch mal mehr dazu sagen.
Über das Projekt bin ich dann auch zu PyTest gekommen, und was ich jetzt eigentlich mache,
ist zum einen...
Ich arbeite an Qt-Browser und PyTest, durch Spenden finanziert,
und zum anderen gebe ich im Herbst jeweils hier an der Fachhochschule Python-Unterricht für Erstsemester-Studierende,
also Bachelor-Informatik-Studierende.
Also ja, ganz viel Open-Source, ganz viel auch Freiheit, sage ich mal, wann ich was mache,
und eben auch viel PyTest.
Ja, genau. Du bist einer der PyTest-Maintainer auch, ne?
Genau. Das hat auch ganz lustig schon angefangen.
Ich habe da halt eben durch Qt-Browser, durch dieses Projekt reingekommen,
weil ich da Tests geschrieben hatte dafür, damals noch mit Unitest-Framework von Python,
was mit Python mitkommt, und da gab es dann so ein Adopt-Pytest-Month, April 15, glaube ich, sowas.
Also doch schon eine Weile her, ja.
Also ein bisschen, ja.
Wo dann Leute hinter PyTest, anderen Open-Source-Maintainern,
anderen Projekten...
anderen Projekten geholfen haben, auf PyTest umzusteigen.
Da habe ich eben mitgemacht mit Qt-Browser und bin dann ziemlich schnell zu PyTest gekommen
und habe angefangen, da Dinge zu verbessern, an Plugins Dinge zu implementieren,
die ich halt haben wollte oder die mir aufgefallen sind.
Und dann hieß es irgendwann, ja, willst du nicht das nächste Release machen?
Und ich fand halt, ja, Moment mal, ich habe ja noch nicht mal irgendwie Commit-Rechte.
Und wie es halt so läuft bei Open-Source, da habe ich sie eben.
Ja, cool.
Ja, das klingt gut.
Über die ganzen Sachen müssen wir gleich nochmal besonders reden, auch über die Plugins und so, das klingt spannend.
Ich würde aber sagen, Jochen, wir fangen wie immer einmal mit den News an.
News, okay, alles klar.
Ja, ist auch ein bisschen was wieder zusammengekommen, weil jetzt die letzte Episode auch schon wieder ein bisschen was her ist.
Und genau, ja, was haben wir denn so?
Django 5.
Django 5 ist jetzt gerade letzte Woche rausgekommen.
Genau, das ist ja immer so, das kriege ich halt immer mit, weil ich muss dann immer alles umstellen.
Ja, Django im Einsatz und ja, war aber diesmal sehr entspanntes Update, hat alles gut funktioniert.
Ging gut, nicht wie Deprecated.
Nee, also was die Verbesserung angeht, es ist auch, also es gibt ein tolles neues Ding, was halt irgendwie,
ein Bug, der seit 18 Jahren offen war, ein Issue, der seit 18 Jahren offen war, der jetzt geschlossen wurde.
Nämlich, da ging es darum, dass er eigentlich blöd ist, wenn man bei einem Model-Field irgendwie Default angibt,
dass das halt nur dann ausgefüllt wird, wenn man irgendwie eine Zeile über, also das Modell tatsächlich über Django,
baut und auch da ist es halt nicht immer so klar, dass das wirklich dann passiert,
weil es gibt ja auch noch Bulk Create und man kann halt auf verschlungenen Wegen irgendwie Dinge erzeugen in der Datenbank.
Bulk Create macht Defaults nicht rein?
Nicht unbedingt, also es kann sein, dass wenn du das jetzt einfach so verwendest, dass es dann klappt.
Das war mir tatsächlich neu.
Aber wenn du das halt irgendwie so ein bisschen avancierter verwendest und wirklich schnell sein willst,
dann kann es gut sein, dass das nicht passiert, weil ja, und das ist natürlich doof.
Das hat wahrscheinlich auch mit der Funktionalität zu tun, dass man jetzt,
dass man jetzt so Felder haben kann, die von anderen Feldern abhängig sind und zwar direkt im Feld
und ohne das halt über die Save-Methode zu machen.
Ja, nee, das weiß ich gar nicht, ob die direkt zusammenhängen, das geht jetzt auch, genau.
Die Sarah hat einen tollen Blog-Antrag zugeschrieben, vielleicht kennst du den auch.
Ja, gibt's auch ein Video, hat sie dazu gemacht.
Genau, die macht ja hier auch die PyCologne-Meetup-Gruppe, organisiert sie mit.
Ja, genau, also was jetzt geht, ist halt, dass man nicht sagt Default in einem Model-Field,
sondern DB, Underscore.
Ja, genau, also was jetzt geht, ist halt, dass man nicht sagt Default in einem Model-Field, sondern DB, Underscore.
Default, und dann wird das halt nicht nur gesetzt, wenn man halt irgendwie über Django das Ding baut,
sondern halt in die Datenbank mit reingeschrieben, dass das so ist.
Und ja, das ist ja schon mal ziemlich großartig.
Man kann es halt auch jetzt sehen, welche Defaults es gibt, wenn man einfach nur sich das Schema anguckt
und nicht irgendwie den Applikationscode dazu hat, was ja auch so ein Ding ist,
dass es halt blöd ist, wenn man ein Datenbankschema hat,
dass man nur verstehen kann, wenn man einen Applikationscode auch dazu legt,
weil Applikationscode halt deutlich volatiler ist oft als Datenbankschema.
Ja, aber also das ist jetzt ziemlich cool.
Und genau, so viele haben, also ich habe immer verwendet sowas wie Timestamp-Model
aus den Django-Extensions oder halt aus Django-Model-Utils,
um zum Beispiel sowas wie Created-Zeitstempel oder Modified-Updated dran zu bauen.
Das kann man ja jetzt halt auf eine deutlich elegantere Art machen.
Ja, dann genau diese...
Generated-Field heißt das, glaube ich, ne? Einfach Models, Generated-Field und dann...
Generated-Field ist jetzt diese andere Geschichte, genau.
Genau, da kann man dann halt auch so Dinge, manchmal möchte man ja auch irgendwas indizieren,
was halt irgendwie...
Ein Suchindex.
Ja, was halt auf irgendwas basiert, was halt berechnet wird aus unterschiedlichen Spalten,
die man halt in der Datenbank hat und nicht direkt irgendwie eine Spalte selber ist.
Und das geht jetzt halt auch relativ einfach.
Ja, dann gab es noch, ich habe jetzt aber ganz ehrlich gesagt vergessen, was es genau war.
Es gab einige Verbesserungen an den Formularen.
Also man kann jetzt irgendwie Help-Text und Label und Dinge irgendwie einfacher benutzen,
dass einzelne Felder als Field-Set einfach verwendet.
Dann sind die automatisch, glaube ich, mit dabei.
Genau, das muss man vorher mal ganz umständlich auseinanderproben.
Ja, und ja, ehrlich gesagt, mehr kann ich mich nicht erinnern.
Aber ja, es ist auf jeden Fall eine coole neue Release.
Ja...
Du wolltest, wenn ich das richtig sehe, über diesen OpenAI...
Ich weiß nicht genau, ob euch das irgendwie tangiert oder ob ihr das davon mitbekommen habt,
ob ich das nur mitbekommen habe, weil ich das halt zufällig irgendwie alle immer verfolge, aber...
Ja, erzähl doch erstmal, von was du da genau erzählst.
Ja, ja, ja.
Was du da sagen möchtest.
Naja, es gab ja so leichte irgendwie Schwankungen im OpenAI-Management.
Im Management, ja.
Ich bin hier, ich bin doch nicht hier, ich bin wieder da, hurra.
Genau, und ja.
Was da so der Hintergrund ist, ich weiß es nicht.
Vielleicht ist es auch etwas, wo man eigentlich gar nichts zu sagen sollte,
weil es ist halt halt einen bestimmten Unterhaltungswert und das kann man...
Ja, dann lass uns doch ein bisschen leichte Unterhaltung vorweg dort machen,
weil man hört ja so ein paar Gerüchte.
Ja, was hast du denn gehört?
Ja, ich erzähl mal, ich bin erstmal gespannt.
Also man hört ja immer...
Ich...
Ich hab ganz viel gehört, ich weiß es aber nicht.
Also ich würde denken, dass die...
Ja, dass der Hauptgrund halt irgendwie daran besteht,
dass es halt diese komische Konstruktion gibt,
dass OpenAI ja eigentlich eine Non-Profit-Organisation ist
und die kontrolliert halt die kommerzielle Entität,
die halt nur deswegen gegründet worden ist,
weil man halt diese JetGPT-Geschichte auch als Produkt irgendwie rausbringen wollte
und dann gesagt hat, okay, das können wir nicht im Rahmen von diesem Non-Profit machen,
weil das wird einfach zu teuer und wir müssen da...
irgendwie auch Fremdkapital haben,
um das halt irgendwie alles brechen zu können und so.
Und ja, im Vorfeld davon ist jetzt...
Ja, der Name fällt mir nicht mehr ein.
Der Gründer von Anthropic,
also der Firma, die jetzt auch Claude irgendwie gebaut hat,
ist also quasi ein ähnliches Ding wie JetGPT,
bloß halt sozusagen von einer anderen Firma.
Der war vorher bei OpenAI
und der hat auch schon mal versucht,
Sam Oldman vom Board feuern zu lassen.
Also der hat zuerst gesagt so,
hey, das ist...
Das ist nicht okay, so geht das nicht.
Und wenn...
Das könnt ihr ja so nicht machen.
Und dann hieß es so, ach doch, geht doch.
Und dann hat er sich ans Board gewendet und gesagt,
feuert den CEO mal,
das ist irgendwie nicht okay.
Und dann hat das Board drüber nachgedacht
und dann haben sie gesagt, nee.
Und dann hat er gesagt, gut, dann gehe ich jetzt halt.
Und hat ein paar Leute mitgenommen
und dann halt eine neue Firma aufgemacht.
Und ja, aber das ist jetzt noch gar nicht so lange her.
Ich meine, da überschlagen sich natürlich so ein bisschen die Ereignisse irgendwie.
Aber das ist jetzt auch erst knapp über ein Jahr her.
Und ja, offenbar...
Der Rest, die neuen Sachen sind alle ziemlich closed,
wenn man so ein bisschen genauer hinguckt.
Ja, das ist natürlich immer so ein bisschen...
Also Open AI, ich meine, der Name ist so ein bisschen...
Ja.
Die Proprietäre, das ist die Proprietäre und so, genau.
Ja, und natürlich ist halt auch die Frage...
Die Papers sind geschlossen, da sind nur noch Zusammenfassungen drin
und keine richtig guten Erkenntnisse mehr und so.
Ja, ja, das sind nur noch so Technical Reports.
Und natürlich, also Open AI macht keine Open-Source-Modelle oder sowas.
Die haben überhaupt nie irgendwas released.
Und eigentlich ist ja die Mission von...
dem Non-Profit sozusagen der Allgemeinheit irgendwie zu nutzen.
Ja, wäre mal schön.
Und dann ist halt die Frage, wie lässt sich das vereinbaren?
Wenn man auf der einen Seite halt irgendwie jede Menge Risikokapital nimmt
und irgendwie dann Produkte baut und dann Geld dafür einnimmt
und sich im Grunde in Konkurrenz sieht mit den großen Tech-Giganten
und halt auch ja von einem von denen halt ja massiv finanziert wird.
Irgendwie, ich weiß nicht, Microsoft hat da irgendwie eine Milliarde reingesteckt oder so.
Und halt auch eine Bewertung hat inzwischen von...
weiß ich nicht, 80 Milliarden oder irgendwie ganz unglaubliche Beträge.
Und ja, und dann halt auch nichts mehr in der Richtung tut,
was halt die Mission eigentlich vorgibt,
dann kann ich mir schon vorstellen, dass das Spannung macht
und dass die Leute dann halt auch irgendwann sagen,
so jetzt reicht's aber und...
Also das, was ich so unter der Hand höre, ist natürlich Bullshit, wissen wir alle.
Aber Q-Star haben sie gefragt und hat gesagt,
vorher, ihn schmeißen raus.
Bitte?
Sie haben Q-Star gefragt und Q-Star hat gesagt,
schmeißen raus.
Das ist die nächste...
Ach so.
Ja, das kann man natürlich, ja.
Ja, ich weiß auch nicht.
Also, ja.
Ja, dann gab's ja auch diese ganzen komischen Lobby-Aktivitäten,
irgendwie jetzt auch was AI-Act, was sich nicht in Europa angeht und so,
wo man ja auch sagen muss,
Wir sind für eine AI-Regulierung, sagte der Minister.
Nein, nein, ich meine, Regulierung ist ja vielleicht gar nicht so schlecht,
aber sozusagen die Konkurrenz von Open AI zu regulieren,
sodass man da die Regulierung um Erlaubnis fragen muss,
bevor man da irgendwas machen darf, ist vielleicht...
Also, ich bin...
Also, Uwe...
Das ist ja schon wieder ein ganz neues Fass.
Das Fass will man vielleicht nicht aufmachen,
aber dass man das regulieren will,
dass Leute da nicht zu Schaden kommen,
das kann ich durchaus nachvollziehen.
Ja, und nein.
Ja, also, ich finde, das ist...
Aber das ist ja...
Da kann man wenig gegen sagen.
Also, man sagt...
Nein, nein, der Wunsch ist richtig, würde ich sagen.
Ja.
Also, aber dass man jetzt die Technik selber reguliert,
das finde ich halt komisch.
Ja, genau.
Weil das ist halt irgendwie...
Und, ja, da gab's halt diverse Lobby-Beschreibungen.
Ja, die Frage ist halt, wie das halt überhaupt geht,
ohne dass man jetzt den Stecker zieht oder so.
Ja.
Naja.
Ja, jedenfalls ist es ja jetzt auch nicht so gekommen.
Es ist jetzt die Richtlinie...
Das ist ja noch nicht unter Dach und Fach.
Es ist ja bloß irgendwie sozusagen...
Es gibt ein Verhaltensergebnis,
auch irgendwie seit letzter Woche oder so was.
Das sagt ja auch im Grunde, ja, im Wesentlichen,
wir regulieren halt die Anwendung,
aber nicht die Technik selber.
Ja, Transparenz regeln wir halt ganz gut, ne?
Nach dem Motto, du musst das Modell halt irgendwie...
Ja, Open Source ist halt explizit ausgenommen.
Das ist halt schon mal großartig.
Was halt bedeutet, okay, wenn ich jetzt hingehen will
und sage, okay, ich mache hier meine eigene Suchmaschine
oder so auf internen Dokumenten,
die halt irgendwie besser funktionieren soll,
dann muss ich nicht OpenAI fragen,
sondern dann kann ich das halt irgendwie selber machen.
Kann ich mir in Lama feintunen oder was auch immer,
Mistral oder was auch immer
und kann das halt einfach machen
und es ist nicht verboten, einfach so.
Ja, also genau.
Also schon mal...
Also im Grunde ist eigentlich alles halbwegs okay.
Und Sam Altman ist ja auch wieder zurück zu OpenAI,
heißt ja auch wieder alles okay.
Und ich glaube, das mit dem...
mit der...
mit dem Nutzen für die Gesellschaft
das kriegen sie bestimmt auch noch hin.
Ich glaube nicht, dass ihnen da das Geld zu Kopf steigt
oder da irgendwie das irgendwas dran machen kann,
wenn da jemand eine Milliarde investiert.
Nein, nein, das ist überhaupt gar keine Gefahr.
Das ist, glaube ich, kein Problem für die.
Nein, niemals.
Warum sollte denn niemals irgendwie sich jemand korrumpieren lassen?
Ja, also, nee, nee.
Ja.
Ja.
Und ich meine, das Board hat ja schon gezeigt,
dass sie da irgendwie absolut in der Lage sind,
auch das zu kontrollieren und durchzusetzen,
wenn sie finden, dass das nicht okay ist.
Daher, ich habe da überhaupt gar keine Bedingungen.
Ja, okay.
Also, das war sozusagen die leichte Unterhaltung zum Thema.
Ja, das war die leichte Unterhaltung zum Thema.
Kurz vor Weihnachten noch mal ein bisschen Advent.
Ja.
Advent of God und was kann man auch wieder spielen?
Ja, genau.
Was hatten wir noch so?
News.
Du hast noch eine wichtige News.
Naja, wichtig.
Für Python.
Ja.
Ja.
Gill Removal.
Genau, Gill Removal ist beschlossene Sache.
Wer sich dafür interessiert,
es gibt da einen schönen...
Es gibt einen neuen Podcast.
Ich weiß auch nicht, ob wir den schon erwähnt hatten.
Core-PY heißt der.
Ist irgendwie von Lukas Langer und Pablo Galindo Salgado.
Irgendwie den Release-Managern für die letzten beiden Versionen.
Die machen den und reden halt über so CPython-interne Geschichten.
Zum Beispiel war das die erste Episode,
war über den CPython-Core-Dev-Sprint oder halt andere Themen,
wie zum Beispiel jetzt, dass es dann...
Ja.
Just-in-Time-Compiler irgendwie für 3.13 wohl geben soll
und solche Dinge.
Und da gab es jetzt auch eine Episode über das Entfernen von Gill,
was halt eine komplizierte Geschichte ist und viel Arbeit wird.
Aber ja, jetzt wird das Ganze wohl angegangen
und bin gespannt.
Ich fand halt die Tagline ganz lustig vom Podcast.
One talks like a Mexican, the other like a Russian.
Both hate the comparison.
Das ist mir gar nicht aufgefallen.
Aber ja, stimmt, das ist gut.
Ja.
Ja.
War das CinderX, das ist die letzte Folge?
Die letzte habe ich, glaube ich, noch nicht gehört, ja.
Da haben sie, ah, da haben sie mit,
haben sie da nicht mit Karl Mayer geredet?
Jep.
Karl Mayer, ganz interessanter Typ.
Von Meta.
Ja, genau.
Der hat, ja, Meta, aber der ist einer der Hauptentwickler
hinter dem Django-Python-Kern von Instagram.
Mhm, klar.
Und er hat, da gab es mal eine sehr interessante Episode,
ich habe jetzt wieder vergessen, wo und wann,
aber...
wo er darüber geredet hat,
das, was man so vor Probleme kriegt,
wenn man halt irgendwie mehr als,
deutlich mehr als eine Million Zeilen Python irgendwie hat,
die, und dann eine Anwendung, die darauf basiert,
dass man halt so...
Ich glaube, den Artikel hatten wir auch schon das eine oder andere Mal
irgendwo in den Shownotes gelinkt, wenn ich mich recht erinnere.
Kann sein, ja.
Also, genau, das kann man, also, ja, ich habe es noch nicht gehört.
Ja, Kopf EYF, das war ein guter Podcast.
Ja, genau.
Und dann erinnere ich mich noch,
letztes Jahr hatten wir darüber geredet,
dass es da so gewisse Sicherheitsstrategien gibt,
dass es da so gewisse Sicherheitsstrategien gibt,
dass es da so gewisse Sicherheitsstrategien bei LastPass gab.
Ja.
Und da dachte ich, okay, muss ich diesmal auch...
Ich kann mich an den Januar und den Februar erinnern,
wo ich 1.000 Passwörter umstellen musste.
War super.
Wo ich dann gesagt habe, ja, okay, so prinzipiell ist OnePassword
jetzt auch nicht so viel besser zum Beispiel.
Aber zum Glück sind sie noch nicht irgendwie hopsgenommen worden.
Ja, das hat sich jetzt geändert.
Jetzt ist auch OnePassword hopsgenommen worden.
Und zwar über Okta.
Also, ich manchmal denke so, okay, Okta ist auch so ein...
Also, ich verstehe nicht genau, warum Unternehmen sowas verwenden,
aber okay.
Ja, ist ja total super, SSO und so.
Muss man alles über so einen Anbieter machen.
Ist Okta nicht auch in Zero aus?
Ja, aus Zero, ja.
Ja, der Dömm.
Ja, also, ich glaube, es war nicht so ganz super schlimm,
aber dazu gab es auch ein Postmortem, was wir veröffentlicht haben.
Und das war einfach nur, wenn man sich das anguckt,
das war einfach nur total schrecklich.
Wie der Markt klingt peinlich.
Oh ja, wir versprechen euch, es ist gar nichts geleakt worden
und es ist auch nichts kaputt gegangen.
Es sind jetzt so ein paar Dokumente verloren gegangen.
Ja, aber, ja.
Also, Zugriff auf die Datenbank oder so.
Ja, ich habe auch keine gute Lösung dafür.
Ich weiß nicht, wenn es das...
Ich finde es schwierig, tatsächlich.
Wir hatten ja letztes Jahr schon mal das Thema.
Ja, das Thema hatten wir schon mal.
Es kommt irgendwie immer wieder.
Verrätst du, wie du das machst, Florian?
Passwörter?
Ja, tatsächlich ganz langweilig lokal bisher.
Mit KeyPassXC ist es, glaube ich, inzwischen.
Ich bin da mal irgendwie gewechselt von einem Volk zum anderen.
Das und dann so ein minimales Frontend darüber,
namens KeepMenu, was dann auf Rofi aufsetzt.
Also so ein Keyboard-Menü.
Und dann, ja, wenn ich mal irgendwie was brauche,
was editieren muss oder so, mache ich halt dieses KeyPassXC auf
und sonst einfach alles mit Tastaturkürzel und Autotype.
Aber du kommst halt auch von dem Rechner nicht runter, ne?
Und wenn der Rechner irgendwie dein Backup-Problem hat,
dann ist es blöd.
Das ist so, ja.
Ich habe tatsächlich dann teilweise das Problem,
dass ich halt irgendwo am Handy mal...
Irgendwo ein Passwort brauche oder so.
Ja.
Aber ich bin eh so der Mensch, der fast immer sein Laptop dabei hat.
Zum einen, und was Backups angeht,
habe ich das tatsächlich dann alles mal ausgedrückt
und in ein Bankschließfach gelegt.
Ja, das glaube ich auch.
Das ist keine so schlechte Idee, ja.
Weil ich halt doch fand, ja, wenn das weg ist,
habe ich echt ein gröberes Problem.
Ja, ja.
Ja, also ich finde auch für mich alleine oder so,
da bin ich auch KeyPassXC oder so.
Das war, das klingt, sah schon gut aus,
aber das Problem für mich ist halt,
auch der Support von irgendwie so
Familie und Verwandten.
Ja, und Sharing.
Das und Sharing und mal irgendwie für jemanden was freischalten und so.
Und das, da habe ich bisher noch keine gute Geschichte gefunden.
Ja, also ich finde 2FA tatsächlich gar nicht so schlecht.
Dann, und dann halt immer irgendwie so ein Key mitnehmen,
wo ich halt auch, dann geht es halt nur zweimal oder sowas.
Einer ist dann halt im Bankschließfach
und den brauchst du halt dann und so.
Das ist auch keine schlechte Idee, finde ich.
Ja, also...
Was ich mir wahrscheinlich anschauen würde,
wenn ich jetzt was wähle, was ein bisschen mehr,
was ein bisschen mehr Cloud dran hat, sage ich mal.
Spitwarden.
Habe ich wieder.
Weil das ist, glaube ich, größtenteils Open Source.
Und es gibt, glaube ich, auch eine alternative Server-Implementation,
die man dann irgendwie selber hosten kann.
Ja, also ich habe es mir angeguckt.
Ich wollte auch erst als Umstände.
Ich habe damit angefangen und ich weiß nicht.
Also ich bin so ein Usability.
Ich möchte das immer einfach und schnell und so haben.
Und irgendwie nervt es mich.
Kann sein, dass das technisch die sauberste Lösung ist.
Aber ich fand es irgendwie total anstrengend.
Ja.
Naja.
Ja, okay.
Also vielleicht müssen wir einfach nächstes Jahr nochmal drüber reden.
Ja, vielleicht ist da irgendwas.
Also mir fällt aber auch nichts ein,
was man irgendwie so architektonisch hat.
Man muss, irgendeinen Tod muss man immer sterben.
Also zum Beispiel, wie teile ich auch,
jetzt hatten wir auch letztes Mal, glaube ich,
irgendwie Geheimnisse durch Entwicklungsteams irgendwie.
Auch nicht so einfach.
Ja.
Ja.
Also ich benutze jetzt tatsächlich so einen Service,
wo halt die Entwickler gar nicht mehr die Geheimnisse kennen müssen,
die halt autogeneriert werden.
Das heißt, ich kenne die selber nicht.
Aber man muss sich halt mit der API dahin verbinden.
Dieser Service kennt die halt alle.
Also, ne?
Ja.
Ist halt auch dann wieder irgendeine Party,
die dann halt Zugriff darauf hat.
Aber gut, dass da jetzt nichts kritisch ist und so.
Und ja, gut.
Aber immerhin läuft der Rest dann so.
Naja.
Ja, das ist schwierig.
Okay, ja.
Ich weiß nicht.
Ansonsten habe ich jetzt keine News mehr, glaube ich.
Vielleicht bräuchte man einfach ordentliche Tests
für diese wundervollen Passwort-Manager.
Tja.
Ja, also die Überleitung war jetzt ein bisschen hakelig.
Vielleicht reden wir ja über das Thema.
Dann haben wir heute noch News.
Fertig?
Ja, genau.
Und dann können wir eigentlich mal hier mit PyTest starten.
Ja, ich glaube, die meisten Menschen wissen, was PyTest ist.
Also das Test-Framework, was man oft benutzt,
wenn man Tests in Python schreiben möchte.
Würde ich auch empfehlen, ehrlicherweise.
Ihr wahrscheinlich auch.
Ich auch.
Alleinig.
Ja.
Keine Überraschung soweit.
Aber dann überlasse ich einfach mal dem Florian vielleicht das Wort
und den Einstieg in das Thema vielleicht auch.
Das erzählst du ja vielleicht auch öfter.
Also ich fand auf jeden Fall den Vortrag,
den auf der letzten EuroPython darüber gehalten,
das war schon ziemlich gut.
Der war spannend.
Ja, erzähl ich tatsächlich öfter,
weil ich ja auch Firmenkurse mache zu PyTest.
Das wären so die Einzelfirma-Schiene,
die ich eben neben den Open-Source-Dingen noch fahre.
Und da mache ich halt auch erstmal ein bisschen Werbung für PyTest.
Gerade früher war das vielleicht noch ein bisschen wichtiger,
weil da gab es oft echt noch Firmen,
die umgestiegen sind von Unitest oder von Nose.
Nose-Test-Framework.
Inzwischen muss man sagen,
dass wirklich so das Default eigentlich PyTest ist.
Also Nose-Test ist sogar deprecated, oder?
Nose, ja, ja.
Ne, ne.
Nose-Test gibt es auch noch.
Ah, Nose-Test.
Ja, Nose-Test.
Jetzt habe ich es falsch verstanden.
Da stand schon seit Jahren, steht in der Dokumentation,
man soll bitte kein Nose verwenden.
Es gibt irgendwie ein Nose 2,
aber ich habe noch kein Projekt gefunden,
was das nutzt so effektiv.
Und wenn man sich halt dann so anschaut,
wie die User zahlen,
es gibt jeweils jährlich so eine Umfrage,
die Python Developer Survey
von der Python Software Foundation und JetBrains.
Und da hat PyTest, ich glaube,
vorletztes Jahr oder so die 50%-Marke geknackt.
Okay.
Ich hätte sogar mehr geschätzt, ehrlicherweise.
Ja, wobei irgendwie 30% halt sagen,
sie nutzen gar kein Test-Framework.
Okay.
Ja.
Ja.
Also würdet ihr denn Tests benutzen
oder wann würdet ihr denn Tests benutzen?
Das ist vielleicht auch eine spannende Frage.
Oder wofür?
Alles 100% Covered.
Jeder Commit, der die Coverage reduziert,
wird automatisch nicht durch die Committung durchgelassen?
Oder gibt es da unterschiedliche Ansichten?
Ich habe tatsächlich ein Projekt jetzt,
wo ich das versuche,
für das Modul,
was ich eben an der Fachhochschule unterrichte.
Da habe ich pro Jahr irgendwo 100 Studierende
und das Modul heißt Automatisierung mit Python.
Und ich habe dann eben halt auch meine Arbeit hinter dem Modul
so ein bisschen automatisiert.
Zumindest so der langweilige Teil.
Also irgendwie Noten dann ausrechnen und E-Mails verschicken
mit der Noten-Aufschlüsselung und so was.
Und da bin ich jetzt dran, das alles ein bisschen zu refacturen
und für den neuen Teil quasi, was refactured ist,
auch wirklich 100% Test-Coverage zu haben.
Weil ich halt finde, ja, ich berechne da irgendwie Zeugnisnoten
und so, das muss halt schon irgendwie
keine Box haben, in irgendeiner Weise.
Also ich finde auch, also so kritische Teile der Infrastruktur
sind ganz gut, wenn man die testet.
Also sowas wie Authentifizierung, Autorisierung oder sowas,
sollte man schon irgendwo mal gucken, dass das stimmt.
So die kritische Business-Logik.
Weiß nicht, also jede Einzeiler-Funktion weiß ich jetzt nicht.
Ja, es gibt ja Leute, die diesen Standpunkt vertreten und sagen:
"Na ja, gut, wenn man anfängt, über solche Zahlen zu diskutieren,
dann macht das eigentlich nur 100% Sinn."
Aber ich weiß auch nicht, ob das jetzt optimal ist für alle,
also ich hab's für ein Projekt, hab ich das auch gemacht,
weil einfach ich das mal machen wollte.
Ob das jetzt nötig wäre, weiß ich nicht.
Ja, und es wird schon anstrengend,
also gerade, wenn man dann externe Komponenten drin hat.
Ja, ja.
Irgendwie eine GUI-Applikation schreibt oder so,
dann wird's schon schwierig irgendwann.
Ja, genau, also welche Enden muss man danach testen, ne?
Also ich finde ja da tatsächlich auch vielleicht jetzt direkt
an dem Zeitpunkt TDD ganz interessant,
also dass man mit den Tests anfängt, die zu schreiben.
Das ist ja auch immer ganz einfach,
weil man muss dann schon relativ genau wissen, was man machen will.
Und wenn man das nicht weiß, dann baut man halt Tests,
die man hinterher wieder wegschmeißen kann,
was dann die doppelt- und dreifache Arbeit macht.
Aber wenn man halt irgendwie schon ein gutes Konzept hat,
dann erst Tests dafür zu schreiben, wie das aussehen sollte,
und dann die Implementierung.
Das führt halt dazu, dass die dann auch tatsächlich funktioniert, ja?
Wenn man sich so Gedanken dazu gemacht hat,
wo so die Haken und Stellen sind, die ineinandergreifen sollen.
Ja.
Macht ihr das auch mal manchmal?
Ich mache das gerne bei Bugs, wenn ich halt irgendeinen Bug-Report kriege,
dass ich erst mal einen Test dafür schreibe.
Zumindest so ab dem Punkt, wo ich das einmal manuell reproduziert habe.
Weil wenn ich den Bug fixe, werde ich das eh schon ein paar Mal reproduzieren müssen.
Und dann mache ich mir halt effektiv das Leben leichter.
Ja, genau. Also ich würde auch sagen, fix ist immer Test, ja.
Genau. So bei einer Library kann ich es mir auch noch vorstellen.
Und wenn es dann eher Richtung Applikation geht,
finde ich, wird es schon schwieriger.
Aber jetzt wieder bei einer GUI-Applikation,
da muss ich das Feature irgendwie erst mal implementieren
und erst mal sehen, wie das aussieht aus User-Sicht, aus Code-Sicht auch,
ja irgendwie sinnvoll Tests dafür schreiben kann,
finde ich.
Klingt sehr vernünftig, würde ich
ganz genau so sehen. Also ich mache auch
TDD manchmal, aber
gerade eben auch so bei Web-Applikationen
entwickle ich
oft, also oft ist es ja so, man fängt mit irgendwas
an oder mir geht das halt so und dann
denkt man sich irgendwann, ah nee, das ist einfach keine gute Idee
und ich mache das auch oft
in Notebooks am Anfang.
Einfach nur, um zu sehen, ob irgendwas geht
oder elegant geht und wenn es dann nicht geht, dann sage ich so
okay, pff, ne, dann mache ich doch
lieber was anderes und
wenn man da zuerst die Tests schreibt,
dann schmeißt man die Tests ja mit weg.
Ich habe dann mal, es gab
auf Twitter irgendwie einen Thread, wo dann
weiß ich nicht, Harry Percival,
der auch dieses
Obey the Testing Go, der
ein Testbuch geschrieben hat für Python,
meinte, dass Leute doch bitte mal
TDD verwenden sollen und sich mal ein Brief reißen
wollen, dann werde ich so, ich mache das mal so.
Ich weiß nicht, ich habe so das Gefühl, wenn ich
zuerst Tests schreibe, dann ist das eine totale Verschwendung, weil
wenn ich schmeiße, dann oft Sachen wieder weg
und warum sollte ich da Tests für Sachen schreiben,
nicht wieder? Nee, nee, das ist ein Spike, das ist auch
TDD, das ist schon okay.
Na gut, ja, aber
oft muss man erstmal sehen, ob irgendwas so
funktioniert, wie man denkt und dann...
Wenn man zum Beispiel die Modelle jetzt noch nicht hat von so einem Problem
oder die einfach definieren muss, also manchmal muss man ja
irgendwie Fixes schreiben dann erstmal, um zu gucken,
was denn überhaupt an Datenmodellen, wie die
aussehen sollen und so. Oft lasse ich die Modelle weg
und schreibe gar keine Modelle, sondern
ich schreibe erstmal so, um
zu sehen, ob das in der UI funktioniert.
Das wäre dann Integration Test?
Nee, ich schreibe da gar keine...
Wie gesagt, an der Stelle kann man noch nicht so gut Text schreiben.
Also wenn ich mit Tests anfangen würde, würde ich ja
mit den Tests vielleicht für das Modell anfangen oder so,
aber wenn ich kein Modell habe, ist es halt ein bisschen...
Ja, okay.
Ich will noch kurz nochmal beim Testing Goat
anknüpfen. Da hat
jemand letztens ganz einen lustigen Thread
aufgemacht, wo er fand, ja, er hat mal
ChatGPT gefragt, wo das PyTest-Logo
herkommt
und ChatGPT meinte dann, ja, ich hätte
das designt.
Ist Quatsch.
Ist völliger.
Ist Quatsch. Das Logo
gibt es nämlich schon irgendwie seit 2014
und ich bin ja erst ein Jahr später zu PyTest
dazugekommen.
Also, ja, GPT lügt bei Python
regelmäßig. Ich denke zum Beispiel auch, dass irgendwelche
anderen Menschen den Python-Podcast machen würden, die ich noch nicht
gehört habe. Aber hey.
Ja, ich habe da tatsächlich
mal rumgegraben in den Mailing-List-
Archiven und rausgefunden,
warum das so eine Pornflöte ist.
Ach, okay. Das ist was.
Ich soll nämlich tatsächlich an diesem Testing Goat
als Maskottchen auf diesem Buch
anknüpfen, weil
Pornflöten eben genutzt wurden
wohl, um
Ziegen zu herden.
Wie sagt man denn noch in Deutsch?
Zu hüten.
Zu hüten, ja, ja.
Hm. Ja.
Ja, ich fand das mit dem ChatGPT
dann ganz witzig. Ich habe danach noch mal so ein bisschen
nachgehakt und finde so, nö, das war nicht ich.
Und dann meint es, ja, nee,
es tut mir leid, es war Armin Ronacher.
Ach so.
Und da fand ich,
da fand ich halt auch, äh, nö.
Und da meinte er irgendwas von einem Daniel
Urstöger, auch bekannt als
Blue-Logo, habe ich gesucht, nichts gefunden
zu der Person und fand immer noch,
nee, kann nicht sein. Und dann fand
er immer noch, ja, tut mir wirklich leid und so.
Es war von Daniel Haller
gemacht, was halt auch nicht stimmt.
Mir, ich habe
gerade auch noch mal gefragt, und mir sagt
es, dass es nicht genau weiß, weil es von einem
Community-Wettbewerb stammen würde.
Ja,
dann hast du wahrscheinlich dieses GPT-4-Modell,
ein nächstes Mal mit dem GPT
das 3.5, okay, interessant.
Ja, also, ja, das ist halt, weil
er sich irgendwie manchmal aus der Fantasie teilt.
Ja, gut.
Sicheres Auftreten bei vollkommener
Ahnungstätigkeit, Jochen. Was fällt dir
dazu ein?
Dass mir auf jeden Fall die Panfurte besser gefällt,
als ein Schäferhund als Logo für Pytas.
Ja, die Panfurte ist super.
Ja, was
haben wir denn, was haben wir denn so an Dingen,
die man da, über die man mal, ja, das wird
mich auch mal interessieren, genau, du machst viele
Pytas-Schulungen, geht das
überhaupt, also ich habe irgendwie so ein bisschen, ich mache
auch manchmal Schulungen, auch so Python-Einführungen,
oder halt auch mal zu speziellen Themen,
und ich habe immer so das Gefühl,
ich weiß nicht so genau, ob ich, ob das,
wie ich da, wie man da am besten
Wert
irgendwie schafft für die Leute, die darin teilnehmen,
weil ich habe manchmal so das Gefühl, die sind
dann halt dann zwei Tage oder drei Tage da,
und dann
machen sie das dann aber doch wieder so, wie sie das kennen,
irgendwie, wenn sie wieder da weg sind, und
gerade bei so Test-Driven Development
ist es halt, habe ich das Gefühl,
oder überhaupt beim Testen, so ein Ding,
wo sich das erst so über die Zeit
irgendwie einstellt,
wo man das schlecht irgendwie so einmal
in, so musst du das halt machen,
und dann, sondern es ist mehr so ein Ding, so ein, so ein,
wegschmeißen, nochmal machen, wegschmeißen, nochmal machen,
wegschmeißen, nochmal machen, ja, oder man muss sich halt da so ein bisschen dran gewöhnen,
und das muss halt über eine längere Zeit irgendwie
passieren, und ich habe da noch nicht so einen Dreh gefunden,
wie man das am besten vermitteln kann.
Ja, ich sage,
ich sage das den Leuten schon auch so,
es ist auch irgendwie viel Erfahrung
dahinter, die kann ich euch nicht abnehmen,
aber ich kann euch halt erstmal die Werkzeuge
in die Hand geben, und euch
einfach mal zeigen, was kann man an sich
vielleicht eher ein bisschen abstrakter mit
PyTest überhaupt machen, was sind so die Möglichkeiten,
wie man die dann
anwendet auf die konkrete Fälle,
die die Leute da haben, steht dann teilweise schon
nochmal ein bisschen auf einem anderen Blatt,
aber ich finde es schon ganz nützlich,
dass die Leute halt sehen, was gibt es denn überhaupt.
Ja.
Da habe ich vielleicht noch eine kurze
Geschichte auch, wie das mit
diesen Trainings angefangen hat.
Das war nämlich auch ganz
witzig, das war, als ich PyTest
erst ein paar Monate gebraucht habe, auch noch
irgendwie im 2015,
und zwar zu Europython
da in Bilbao,
also Spanien,
da wurde ich von Holger
Krekel, also nicht ich, aber Holger
Krekel, also so der Vater
von PyTest, der hat
halt auf der Mailingliste gefragt, ob
jemand dieses Training übernehmen kann an der
Europython, weil er war irgendwie
verhindert kurzfristig
und es hat sich dann niemand gemeldet und ich fand
halt so, ja, hm, das ist
irgendwie Material da, Spanien klingt
auch irgendwie toll, ich war noch nie auf
irgendwie einer Python-Konferenz.
Ja, machen wir.
Dann im gleichen Jahr noch auch
das erste Firmentraining dann von ihm
übernommen, weil er eh langsam aufgehört hat
mit PyTest und zu anderen Projekten
übergegangen ist
und seit da dann basierend auf
seinen Materialien das halt immer weiterentwickelt,
das klingt aber gut.
Das klingt gut. Ja, also da sind auch
viele interessante Sachen und ich würde auch die
einzelnen auch nochmal vielleicht kurz anschneiden, dass man
so ein bisschen drüber erklärt, für die Menschen, die
das noch nicht so kennen.
Wollen wir uns dann eine Struktur geben, wie wir
anfangen, weil sie nochmal reden, wie man vielleicht
Pictures am besten macht oder was das überhaupt ist
oder ob man die braucht oder wie
man die baut oder
und dann irgendwann vielleicht über diese
ganzen Plugins oder so
ein paar
extra Sachen geht. Es gibt ja wunderschöne Sachen,
die ich auch am Anfang nicht kannte.
Das letzte, wo ich erst mich
so ein bisschen gesträubt hatte, war irgendwie Hypothesis.
Das habe ich dann durch deine Veranstaltung
lieber Florian nochmal dann
eingebaut und war überrascht, dass ich, also was
heißt überrascht, aber ich habe noch so ein paar
Bugs angefressen und so, oh,
die habe ich jetzt noch nicht gesehen und ja,
da kommt man so ein bisschen
auch an die Grenzen dessen, was
Python so kann und
ja, ich weiß nicht, wo würdest du denn anfangen
bei PyTest?
Ich würde glaube ich jetzt tatsächlich
nicht generell
bei PyTest, aber ich würde nochmal kurz gerne bei
Coverage einhaken, weil
das Thema schon gehabt haben und
vielleicht nicht alle wissen, was das eigentlich ist.
Da freue ich mich jeweils
auch so rum bei den Firmenkursen und
oft so viele Leute
fanden, ja, nee, das machen sie eigentlich nicht,
dass sie irgendwie Coverage messen.
Da geht's
darum, dass man sich
ganz einfach anschaut, welche
Zeilen von meinem Code wurden von
meinen Tests ausgeführt.
Was einem dann einen Eindruck zumindest
geben kann, was ist getestet
oder was wird zumindest ausgeführt
von den Tests, muss nicht zwingend
dann heißen, dass die Tests auch gut sind oder
wirklich was testen, aber es wird zumindest mal
ausgeführt. Ja, das Blöde ist halt dann,
wenn wir 100% Coverage, also der ganze
Code ist durchgelaufen, aber ist trotzdem irgendwas kaputt.
Genau. Kann einem halt
auch passieren, ja.
Auch schwierig, da Prozent
Coverage gerade in einem Team sich
irgendwie als Ziel zu setzen, weil dann
wird es bestimmt Leute geben, die dann einfach
diese Zahl hochtreiben, ohne wirklich noch
gute Tests zu schreiben. Ja, ja, genau, weil
ja, das würde ich auch sagen, wenn man es halt nur macht, um irgendwie
irgendeinen Ast nochmal zu
durchzuwandern, ohne
dass es halt irgendwas bringt, ist halt blöd.
Aber gibt es da sowas, wo ihr sagen würdet,
so aus euren Eigenprojekten, so Pi mal
Daumen, so eine Coverage ist okay?
Hm, nee, ich würde,
also ich weiß nicht, also meistens, wenn ich nicht
drauf achte, lande ich irgendwo so bei
irgendwie ein bisschen über 80% oder sowas.
Ja. Aber...
70 war jetzt auch so meine erste Reaktion
gewesen. Also ich würde sagen, wenn man schon
zwei Tests schreibt oder so, die so ein bisschen das machen, was man
testen, was man macht, dann sind die ja schon mal über 60,
70 meistens drüber.
Das weiß ich nicht, aber... Ja, je nachdem, wie groß das
Projekt ist natürlich. Ja, ja.
Also klar, am Anfang hast du einfach viel mehr
Gewinn, also so ein paar Tests, die
halt bei der Web-Applikation jetzt die Views
einfach nur durchgehen und gucken, ob ein Okay zurückkommt,
irgendwie in den Standardfällen, da hast du halt
sehr wenig Tests geschrieben und viel Gewinn,
quasi, weil wenn das kaputt geht...
Und das wird dann halt immer weniger irgendwann
und irgendwann ist man natürlich am Punkt erreicht, wo es halt
eigentlich keinen Sinn mehr macht und man aufhören kann,
aber wann der erreicht ist,
keine Ahnung, schwer zu sagen.
Also, ja.
Ja. Ja, am Schluss muss
man sich danach einfach mal so
die Daten dahinter anschauen und
mal schauen, was habe ich denn noch nicht getestet?
Ja, da... Da kann's
eben sein, es wurde einfach vergessen, das ist
irgendwie eine Fehler-Condition, die
vielleicht ganz gut ist, die zu testen.
Oder es kann halt sein, es ist eben
ein Code, der nicht einfach testbar ist und da
muss man sich überlegen, ist es davon wert?
Es gibt halt so zwei, ich würde sagen,
Dinge, die es ein bisschen schwierig machen. Und zwar, klar,
also, man kann jetzt natürlich sehr viel einfacher
Tests schreiben, wenn man ganz klar weiß,
wie jetzt von einer kleinen Funktion, von irgendeiner
Code irgendwie der Contract ist halt. Ja, also,
wenn man weiß, was reingehen, was rausgehen muss,
was halt auch bedeutet, dass man dazu
tendiert, die relativ statisch zum Beispiel zu
typisieren oder zumindest die Type-Annotations dann
nochmal abzufangen oder irgendwie sowas.
Naja, gut, das macht ja jetzt wenig Sinn, würde ich sagen, wenn du die
Type-Annotations dann nochmal testest, das ist irgendwie...
Ja, nein, aber du brauchst halt, dass das, was rein...
reinkommt, dann auch dem entspricht vielleicht, ne?
Oder dass man halt das eng zogert.
Das bedeutet aber halt, dass man auch die Dynamik verliert
oder die Flexibilität. Auch jetzt
irgendwie, wenn man jetzt API schreibt und dann irgendwie
die Daten validieren möchte, klar, kann man jetzt ganz
streng sein und jedes Mal dann, wenn es nicht passt,
einfach zurückgeben, okay, danke,
du darfst nicht oder so.
Ich glaube, ich glaube, ich glaube, das läuft jetzt
quasi darauf hinaus, wie sollte so eine Test...
Es gibt ja diese
Testpyramide, wie sollte die aussehen?
Quasi, ja.
Weil sozusagen, also,
ja, dass man halt viele
Unit-Tests hat, irgendwie dann
weniger irgendwie Tests, die
halt irgendwie größere Sachen testen und dann halt
nur ganz wenige irgendwie
so End-to-End-Tests oder so.
Man kann natürlich jetzt sicher auch mit sowas wie
Playwright oder sowas eine komplette Frontend-
Integrationsstrecke bauen, die jedes Mal dann testet,
ob die Farbe bei dem Button sich geändert
hat und ob weiße Zentimeter links oder
rechts sind, aber wenn halt irgendeine Änderung von irgendeinem
Designer kommt, dann dann die ganze Pipeline sieht jetzt mal auseinanderfliegen,
ist wahrscheinlich eher zu viel.
Genau. So, aber
also ich glaube, man muss
halt irgendwie so sich überlegen, was der Anwendungsfall,
ob der sinnvoll ist halt auch, ne? Also ob es halt
einen Sinn hat, dass man
eine breite Anwendungsfall hat oder ob man das so enger
scopen möchte. Und
das würdet ihr wahrscheinlich am besten wissen, wenn
ihr Anwendungen baut, an welchen Stellen die nicht
auseinanderfliegen sollte. Also wenn ihr irgendwas macht, was
wichtig ist, irgendwie wo Leben dran
hängt oder was teuer ist oder sowas, dann sollte man da
vielleicht ein bisschen mehr Hirnschmalz reinstecken,
das so ein bisschen sauberer
zu programmieren. Und
ich habe immer das Gefühl, also Tests haben mir auch
sehr geholfen, so die Architektur, mit der ich irgendwie
überhaupt Programme schreibe, so ein bisschen zu überdenken,
weil man halt merkt, dass man halt
so große Module oder sowas oder Dinge,
die viel machen, dass die schwierig
halt werden. Also A, zu testen, aber was vielleicht auch
eine doofe Idee ist, wenn in einer Methode
oder in einer Funktion nur super viele Sachen
gleichzeitig passieren und solche Dinge.
Und ja,
und da kommen wir halt auch wieder
zu Coverage, ne? Wenn man halt so viel Zeugs hat,
was passiert, auf einmal passiert,
so ein bisschen sich so von diesem ein Ding für
eine Sache Prinzip verabschiedet,
dann wird das halt auch relativ schwierig
zu testen dann, ja? Oder
überhaupt dann so hinzukommen, dass die Sachen so passieren
oder dass man die Bugs dann findet oder
Ja, aber
ich fürchte, man kann nicht einfach
sagen, man muss das jetzt so machen und dann
ist es halt, weil das sind so widerstreitende
Dinge und so Trade-offs.
Also ich würde ja auch
genau, das ist halt, also das ist auch etwas, was
beim Testen, was ich gut finde,
dass man halt irgendwie so ein bisschen in die Richtung
gedrängt wird, sich darüber Gedanken zu machen, wie man
Sachen halt so hinschreibt, dass man sie
gut testen kann und irgendwann hat man das dann
halt auch so ein bisschen verinnerlicht, dass man, weiß man schon,
wie man am besten Dinge so hinschreibt,
dass hinterher die Tests sehr, sehr, sehr
einfach hinzuschreiben sind und wenn das nicht
geht, dann ist das halt auch einfach nichts, was man
halt so schreiben sollte wahrscheinlich.
Auf der anderen Seite, also
ist es halt auch so, ist es halt,
wäre es halt schön oder elegant
von der Architektur her, wenn man
jetzt halt eher
schmale und tiefe Funktionen hat.
Ja, also
sozusagen, aber die sind halt
schwer zu testen, auch unter Umständen, also
es ist nicht unbedingt, also du kannst natürlich auch
viele Funktionen,
also,
dass es etwas super zu testen ist, muss jetzt nicht unbedingt
bedeuten, dass es halt auch total
elegant ist, zum Beispiel
zu verwenden. Also
es kann sein, dass zum Beispiel, nehmen wir mal ein Beispiel
für eine sehr schlechte API,
die ganze Java-File
irgendwie buffert, reader, irgendwas
sonst was, API, also ich könnte mir
vorstellen, dass es relativ einfach zu testen ist,
aber es ist halt ein Albtraum, das zu benutzen.
Und die, nehmen wir an,
ja, Unix-File-API oder halt auch irgendwie,
keine Ahnung, Requests-API in Python,
die ist halt schön, weil die ist
halt schmal und tief, aber
ich könnte mir vorstellen, dass Request zu testen eventuell
ziemlicher Schmerz ist.
Es hängt halt davon
ab, was sein
Anwendungsfall ist, ob das jetzt, also
wenn du sagst jetzt irgendwie, das ist eine interne Funktion
und da ist es schön,
wenn man die einfach testen kann, dann
macht es halt Sinn, das vielleicht so zu machen, aber wenn
das jetzt was ist, was nach außen geht,
wo User dann halt den Schmerz
haben, dass du es einfach zu testen hast,
dann muss man sagen, naja, nee,
dann muss es halt für User einfach zu verwenden sein und wenn das
halt bedeutet, dass es schmerzhaft ist, das zu
testen, dann ist das halt so, weil
wichtiger ist an der Stelle die User-Experience.
Also es kommt halt drauf an, denke ich.
Ja, um auch vielleicht
nochmal bei dieser Testing-Pyramid einzuhängen,
ich finde da
immer so, ich finde das
ein bisschen zu kurz gedacht. Es kommt halt immer
sehr darauf an, was man testet
und man soll sich halt zu den
Vor- und Nachteilen von diesen
Größen, sage ich mal, von Tests
bewusst sein, aber ich finde zunächst,
man kann immer sagen,
dass die eine Art ist besser wie die andere Art.
Ja.
Wenn ich jetzt ein Command-Line-Tool teste,
bietet es sich vielleicht
an, da eher End-to-End-Tests zu schreiben,
weil ich dann wirklich auch den Output und so
testen kann
und eher sparsam,
so wie für einzelne Funktionen,
die Tests zu schreiben.
Oder auch, ich
bin viel auch jetzt bei Firmen
für die Kurse, die eigentlich gar
keinen Python-Code mit PyTest testen.
Das fand ich auch ganz spannend.
Ja, das ist auch total interessant.
Sondern die beispielsweise Waschmaschinen
mit PyTest testen.
Also da halt eine Waschmaschine
haben, wo dann ein Firmware drauf läuft
und
die wollen sie halt testen.
Und wollen halt dazu
PyTest nutzen, weil es eben
zusammen mit Python ein relativ einfaches
und flexibles Werkzeug darstellt.
Gucken, ob noch alles geht.
Wenn man die richtigen
Knöpfe drückt und das richtige Programm läuft.
Ja, und die Tests sind halt einfach zu schreiben.
Ja, das ist eine gute Idee.
Oder bei einem Kunden von mir,
um vielleicht
dann gleich die Überleitung zu den Fixtures zu machen
an der Stelle, die nutzen
eine PyTest-Fixture, um
eine Klimakammer anzusteuern.
Wir haben so eine Klimakammer
mit Elektronik drin
und sagen dann halt über eine
PyTest-Fixture, heiz mir das
jetzt auf auf 30 Grad und dann
lasse ich da meine System-Tests
für dieses Gerät laufen.
Wo auch wieder halt
alles andere als Python-Code getestet wird.
Ja, spannend, ne?
Wenn man halt wirklich das mit in die Realität überträgt
und quasi auch seine Hardware damit
steuert, um die Testumgebung
außerhalb des Rechners
aufzubauen oder halt aufzuheizen.
Bestimmen die Parameter, machen die das,
was sie sollen.
Das ist, ja.
Und jetzt habe ich das vergessen, was ich eigentlich sagen wollte.
Ja, Fixtures, Überleitung zu Fixtures.
Das auch, aber vorher noch.
Was eigentlich mein Punkt war,
da hat man ja dann gar keine
Wahl, welche Größen von Tests
man schreiben will. Also da schreibt man fast
gezwungenermaßen dann eben System-Tests
oder so End-to-End-Tests
und kann ja nicht mehr wirklich
einzelne Funktionen dieses Geräts
also jetzt im Sinne eines Unitests
testen.
Mhm. Ja, im Grunde ist das ja
auch schon so, wenn man Pi-Tests
zum Schreiben von End-to-End-Tests, was man ja auch machen kann,
verwendet, wie zum Beispiel mit
Pi-Test Playwright oder so, dann da ist ja
auch eigentlich jeder Test im Grunde
weniger. Man muss halt den Browser aufmachen
und dann da überhin und dann...
Ja.
Ja.
Ja, von da finde ich so dieses Testing-Pyramid,
ich meine, die Idee ist ja auch steinalt,
muss man dazu sagen.
Bin ich mit Vorsicht zu genießen.
Dann aber,
vielleicht tatsächlich dazu, zu Figures
und was Figures sind und wie man die baut oder
macht ihr das mit Factories
oder macht ihr das ohne Factories
oder sind Factories doof oder
gibt es da so verschiedene Sachen und
was sind überhaupt Figures und
ja, also vielleicht so fertige
Dinge, die
so tun, als wären sie etwas, was das
Programm normalerweise kann. Das war jetzt ein bisschen
abstrakt. Ich weiß nicht, gibt es da ein einfaches Beispiel?
Also wenn
wir mit einem normalen Web-Client zum Beispiel
arbeiten würden, dann würde halt eine Figur werden, der User und
einen Client und dann guckt man, wie das
interagiert oder
wie baut man das?
Ja, am Schluss ist eine Fixture
im Prinzip einfach eine Funktion, die
als PyTest-Fixture
markiert ist oder
dekoriert ist
und diese Fixture kann
entweder irgendwelche Setup-
Schritte vornehmen für einen Test
und oder
irgendwelche Objekte für den Test bereitstellen.
Das heißt,
das kann jetzt sein, wenn ich
irgendwo eine Config-Klasse habe,
vielleicht in meinem Code,
dann habe ich vielleicht in meinen Tests eben
eine Config-Fixture,
was mir eine sinnvoll
konfigurierte Instanz
gibt von dieser Config-Klasse.
Oder in den Trainings
habe ich das Beispiel von so einem
R-Pan-Calculator, den ich testen will,
der nimmt dann auch eine Config als Argument
und sowas und damit ich
einfach nur die Instanzierung
von diesem R-Pan-Calculator,
also einfach ein Taschenrechner im Prinzip,
in Python geschrieben,
damit ich das nicht copy-pasten muss in jedem
Test, mache ich mir eben so eine Fixture-Funktion,
wo ich das alles aufsetze,
zurückgebe
und Tests können dann diese Fixture
eben nutzen. Mit dem Ziel
eben so diese Setup-Schritte
schön zu isolieren aus
den Testfunktionen. Also man baut sich quasi das Objekt,
das die API bereitstellt, einmal irgendwie
mit den Parametern nach, wie man sie in echt auch gerne
hätte, um die dann in dem Test benutzen
zu können, zu gucken, ob die Ergebnisse, die man erwartet,
dem entsprechen, was man möchte.
Genau.
Ja, schwierig, das jetzt so
in ein paar Sätze zu fassen.
Ja, ich finde das auch sehr abstrakt halt. Also wenn man das nicht gut sieht,
dann wird das relativ klar.
Die Spezialität bei PyTest-Fixers ist halt, dass die so
diese magische
Dependency-Injection gibt, sodass man halt
einfach nur den Namen der Fixer
in die Parameter
vom Test schreibt und dann
das automatisch ausgeführt wird.
Genau, dafür schreibt man die Funktion ja quasi in den Conv-Test einfach rein.
Ja, nö, musst du nicht.
Ja, aber auch das ist schon, ja genau, aber auch gute Frage,
ist das eine gute Idee?
Ja, das ist eine gute Idee und so.
Hängt davon ab.
Aber es ist halt, also
ich weiß auch nicht, ob man das heute nochmal machen würde,
wenn man das nochmal designt, weil das ist schon sehr magisch.
Und ich meine,
ansonsten hat man ja, wenn man jetzt eine Funktion einfach
aufrufen würde oder so, haben ja auch Support in der IDE,
dass man draufklicken kann und landet dann da.
Also bei PyCharm geht das zum Beispiel, dass man halt
auf einfach eine
Fixture in PyTest klickt und dann halt
im richtigen Code landet.
Aber das ist halt natürlich irgendwie nur
dadurch, dass da jemand die Arbeit investiert
hat.
Irgendwie das
parsen zu können und so. Also
das wird wahrscheinlich nicht überall funktionieren.
Es gibt auch eine Extension für andere Editoren.
Ja.
Es ist schon eigenartig, ja.
Also ich sag so, dass
inzwischen habe ich es glaube ich raus, wie ich das den Leuten
erkläre, dass das passt.
Aber gerade am Anfang mit den Trainings
war das so der Punkt, wo ich sagen musste,
ja, ich werde auch jetzt erstmal verwirren
und irgendwann werde ich es verstehen.
Aber nicht gerade vom ersten Satz.
Ja, ich fand das auch sehr, sehr schwierig, also vor allen Dingen
diesen Unterschied zwischen Modulscope,
Class-based Scope und Function-based Scope
Fixtures und sowas. Und erstmal
zu verstehen, dass halt eine Fixture irgendwie eigentlich ein
Generator ist, der irgendwie halt dieses Setup und Teardown
vorher und nachher macht und eigentlich nicht
Returns, sondern eher was Yielded und dann
was da so passiert, das war schwer zu verstehen. Also auch
diese, dass die Fixtures alle immer neu
gebaut werden, dann für jeden Test
atomar und so, das war alles so ein bisschen
ja, das hat ein bisschen gebraucht,
würde ich sagen.
Gut, das sind jetzt ja alles Dinge mit diesem Caching
Scope und Yield und Teardown
und so, das kommt ja dann erstmal obendrauf
auf das Grundkonzept.
Also um Fixtures an sich erstmal
zu verstehen, kann man das, glaube ich, das meiste
davon weglassen. Ja, ich glaube, meistens fällt man halt irgendwie
direkt rüber und die machen halt dann irgendwelche Dinge,
die man nicht erwartet und da kann man sich also schon
ein bisschen mit in den Fuß schießen. Also ich würde
auch empfehlen, also nicht am Anfang zu viel
komplexe Tests darzuschreiben, nur vielleicht erstmal
ein klein oder ein, zwei kleine
und halt einfache Objekte einzugeben,
wo man halt guckt, wie die
zusammenhängen zum Beispiel oder was die tun.
Also was ich halt
hinterher wirklich schwierig finde, ist dann Objekte
zu erzeugen oder viele Objekte oder halt dann
man kann, was halt auch sehr schön ist,
was Florian auch gut gezeigt hat, ist irgendwie
Parametrisierung mit beispielsweise
Data Classes oder sowas, dass man
halt tatsächlich eine Plethora
hundert verschiedene Dinge
erstellt, automatisiert erzeugt an
Tests, die die verschiedenen Edge Cases
seiner Fälle dann halt auch beinhalten
und man halt dann die Logik testen kann,
ob sie da halt dann auch reißt, ohne
jetzt direkt auf Hypotheses zu gehen,
also mit
zufälligen Figures, wenn ich das richtig verstehe, ja?
Oder Zufallswerten für
Dinge in den Figures.
Ja, vielleicht noch kurz zur Parametrisierung.
Wenn ich mir jetzt PyTest
anschauen würde und mal so die erste Testfunktion
geschrieben habe, wäre das
sicherlich so eines der ersten Dinge,
das ich anschauen würde, ist auch eines
der ersten Dinge dann in meinem Training,
weil
das, finde ich, es halt echt einfach macht,
ziemlich viel abzudecken.
Wenn man jetzt irgendeine Funktion testet
um halt eben nicht einen Input und einen
Output nur zu testen,
jetzt mal bei irgendeiner
langweiligen Utility-Funktion,
ich habe bei mir zum Beispiel so ein
Format Seconds, wo ich einfach
Sekunden übergebe und das dann schön
formatiere in halt Stunden, Minuten, Sekunden
beispielsweise.
Oder hast du auch eine Seite übrigens,
kurzer Exkurs, F-String irgendwie
Docs, kann das sein?
F-String.help, genau.
Oh ja, die habe ich auch schon oft
angeguckt.
Eine Webseite von mir,
habe ich mal irgendwo
an der PyCon Germany, ich wollte
schon seit Jahren machen und dann kamen da
die Lightning Talks an der PyCon Germany
und abends vor den Lightning Talks
habe ich die noch kurz gemacht,
um sie dann eben da vorstellen zu können.
Ja, aber die ist echt super, weil sowas hat echt
gefehlt, wenn ich zwischendurch da reingucke, das ist echt gut.
Habe ich gerne.
Ja, Parameterization
macht es einem eben einfach,
um dann aus einer Testfunktion,
die nur einen Wert testet,
den so zu erweitern,
um zum Beispiel 10 oder 20
Werte zu testen,
ohne 10 oder 20 separate Funktionen
dafür schreiben zu müssen.
Und das ist sowas, das vermisse
ich dann sehr schnell in anderen Testframes,
Merks. Meistens geht das schon irgendwie,
aber halt mit einer aufwendigeren Syntax
als in Python oder als mit PyTest.
Ja, genau.
Also PyTest Parameterize ist halt
irgendwie dann der Dekorator, den man da
verwendet. Den benutze ich auch ständig.
Aber es gibt auch noch eine andere Möglichkeit.
Man kann auch irgendwie Fixtures,
die können irgendwie mehrere
Dinge zurückgeben und dann werden auch
quasi
sozusagen wie unterschiedliche Parameter,
also wird der Test auch mehrfach ausgeführt mit den
unterschiedlichen Parameter. Also du meinst, wenn du mehrfach hintereinander yieldest,
weil das beim ersten Aufbruch, beim zweiten Aufbruch
und beim dritten Aufbruch passiert?
Ich weiß es gar nicht mehr genau.
Nee, du kannst im
Fixture Decorator kannst du dann nochmal eine
Liste von Params angeben.
Genau. Und dann wird jeder
Test, der die Fixture nutzt, wird halt mehrmals
ausgeführt. Ja, genau.
Mit der Idee, wenn du irgendwie mehrere
Backends hast oder mehrere Implementationen,
die sich aber eigentlich gleich verhalten
sollen, dass dann halt eine ganze
Batterie von Tests über beide beispielsweise
Eislaufen lassen kannst.
Ja. Genau, mir war das nur
in Erinnerung geblieben, als das auch eine Art, wie man
Parametrisierung machen könnte, aber
tatsächlich sehe ich eigentlich auch immer eher
nur PyTest, Parameterize und den anderen Weg
eigentlich selten. Genau, du kannst halt beide Sachen gehen,
entweder direkt an den Testrandschreiben oder halt an die Fixture.
Genau, aber jetzt sicherlich ein bisschen
exotischer.
Ja, das ist halt ganz nützlich,
gerade für das Teardown. Also die Frage ist halt,
nutzt ihr irgendwie sowas wie Factories oder
sowas? Also, dass man dann
Objekte zusammenbaut, ja, man könnte
ja eine Factory schreiben, um einen User
zu erzeugen, was da alles rein muss, der dann
zum Beispiel Defaults enthält. Da habe ich einen
schönen Blog-Eintrag zugesehen, wie
man das ordentlich machen
soll, irgendwie. Ja, weil es gab
zwischendurch mal so eine Bibliothek, die
hieß Factory Boy, die habe ich dann irgendwann
wieder rausgeschmissen, die dann solche Sachen machte,
aber nicht so wie das,
wie ich das schön fand. Also
mittlerweile glaube ich, man nimmt halt irgendwie
dann einzelne Dinge von Faker vielleicht,
um sich Zufallssachen,
auch erstellen zu lassen und
Ja, denke ich, ist aber ein anderes Problem, also
ja. Und dann baut halt dann
diese Funktion halt dann zufällig Objekte
zusammen und dann könnte man zum Beispiel sagen, parametrisiere
das mal für, keine Ahnung, 10 oder 20
zufällige Nutzer
aus so einer
Factory heraus und benutze die halt einfach mal.
Was die Tests natürlich nicht ganz
so reproduzierbar macht
vielleicht, aber vielleicht dann halt auch doch.
Je nachdem, wie man das halt festgelegt hat.
Wäre halt dann interessant,
wie oft man das laufen lässt,
um zu gucken,
das Ergebnis immer gleich,
ob man einen Spezialfall, wo es nicht passt,
hat man einen Fehler in der Factory gebaut,
nimmt man vielleicht sogar die Factory
später auch für den eigentlichen Programmcode,
um dann wirklich was Neues zu erzeugen?
Ja,
ich weiß jetzt nicht, wie sinnvoll
ich das halte, also
so gezielt sowas zu nutzen, wäre
jetzt auch Hypothesis, was wir sicherlich
noch darauf sprechen werden.
Also Jochen, uns wird auch kurz nicht stören.
Ja, ich habe sowas
so was, Factory-Boys,
sowas früher mal verwendet, aber ich mache das eigentlich
inzwischen nicht mehr.
Ich habe...
Mach doch kurz fertig.
Ja, also einfach deswegen, weil ich
finde, das macht einfach zu viel Magie
mit irgendwelchen, da hast du dann auch wieder so Dekoratoren
für die...
Also, und ich weiß
gar nicht, ob diese Magie so viel bringt.
Also, das ist immer so, das Verhältnis von wie viel Magie
ist da und wie schwer ist das zu verstehen im Verhältnis zu wie viel
Nutzen bringt, das ist für mich jetzt inzwischen
nicht mehr so...
Also diese Relation ist nicht so, dass ich sagen würde,
das ist total sinnvoll, das zu verwenden, sondern ich denke mir
eher so, inzwischen ist
halt auch irgendwie, wenn man
halt ordentliche Funktionen, die solche Daten generieren,
schreibt, halt auch mit entsprechend
benannten, weiß ich nicht, Keyword-Only-
Argumenten oder so, dann ist das eigentlich mal
die bessere Variante. Und ich
habe auch oft jetzt in Projekten inzwischen
sowas wie so ein DevData-
Modul oder so, wo ich mir halt Daten
für bestimmte... Und das brauche
ich halt nicht nur für Tests, sondern halt auch einfach, um
Applikationen gezielt in bestimmte Zustände
versetzen zu können, um halt zum Beispiel,
irgendwas zeigen zu können oder so, dass ich
halt mir für diese Fälle, die ich dann habe,
halt immer irgendwie sowas schreibe, wo
ich dann einfach nur eine Funktion aufrufe,
wo ich sagen kann, okay, versetz meinen Applikationszustand
mal in dieses... Also meine
Applikation mal in diesen Zustand, wenn ich irgendwas
demonstrieren kann. Und das kann ich dann halt auch für
Tests verwenden. Das heißt, sozusagen
dieses Generieren von diesen Daten oder so ist schon
in meiner Applikation drin und das benutze ich dann
in den Tests halt auch. Und ich benutze
eigentlich sowas wie Factory Boy und sowas gar nicht mehr.
Ich habe gerade den Bockartikel gefunden,
den ich meinte. Zu dem von Luke Plant?
Luke Plant, genau. Ja, okay. Ja, der ist gut.
Ja, und so ähnlich habe ich das auch dann, glaube ich,
versucht umzubauen.
Genau, weil der macht dann quasi ja auch so ein...
Das ist halt quasi das, was ich meinte, ne?
Default Keyword Arguments mit vielleicht einem Faker dazu
und dann hast du halt eine parametrisierbare
Art und Weise. Ja, und Faker ist halt noch mal
eine andere Geschichte, wo es einfach darum geht,
dass man halt, wenn man jetzt,
dass man sich nicht als Faker selber ausdenken muss,
dass man plausible Daten hat. Okay, ja.
Du kannst Faker auch den Seed mitgeben
zum Beispiel, ja? Und dann kannst du halt...
Dann ist es immer gleich. Genau.
Ja, genau.
Ja, vielleicht
wäre das jetzt gerade der Punkt, um noch was
zur Hypothesis zu sagen.
Ja, klingt gut.
Das ist ein Projekt, was erstmal nicht viel
mit PyTest zu tun hat, aber sich
halt doch gut im PyTest integriert
zu sogenannten
Property-Based Testing.
Man kann sich das so ein bisschen
wie ein Fuzzer vorstellen,
was also Zufallsdaten generiert.
Ja, man kann mir zum Beispiel sagen,
gib mir irgendeinen Integer, ne? Und dann
nimmt der alle, die er finden kann.
Ja, jetzt nicht alle. Ich glaube, standardmäßig
führt es dann halt 200 Mal oder so
die Testfunktion aus. Also
nicht so viel. Gut.
Und alle Integer wird eh schwierig.
Also,
das kann auch sehr langsam werden.
Wenn man das so findet.
Aber halt mit der Idee, dass man sich
eben so Strategien zusammenbauen kann,
also auch sagen kann, ich will
jetzt gerne irgendwie Dictionaries
und die Keys sollen Strings
sein, aber nur mit ASCII-Zeichen
und die Values sollen
dann irgendwie Listen sein
und die Elemente darin sollen dann irgendwie
das und das sein.
Oder auch passend
beispielsweise auch auf ein Django-Model
und sowas.
Und dann kann man sich mit diesen Strategien
halt ein bisschen gezielter Daten
generieren
und dann halt eben auf seine Funktionen loslassen.
Und gerade bei so
bestimmten Arten von Code,
gerade wenn es darum geht, irgendwo Dinge
aus einem String zu parsen oder so,
ist das relativ einfach,
sich da so eine Strategie
auszudenken oder auch einfach zu sagen,
schmeiß da bitte mal Zufallsdaten hin.
Einfach zufällige Strings.
Und dann, wenn es geht,
noch irgendwelche Invariants
zu testen. Also Dinge, die immer wahr sein
sollen, egal was der Input ist.
Also wenn man irgendwas
Compressed und Decompressed hat,
dann kann man das einmal durchlassen, einmal sagen
Compressed, einmal Decompressed
und es soll das Gleiche wieder rauskommen.
Oder Decrypt, Encrypt,
Encode, Decode, alles so diese
Paare, die sich halt umkehren
sollten.
Ja, dann merkt man ja relativ schnell, ob man irgendwo
eine Case hat, wo, ups.
Genau, dann lässt man das mal laufen und dann
ist die Chance relativ groß,
dass eine Hypothesis halt mit irgendeinem
komischen Corner Case kommt, den man echt
nicht bedacht hatte.
Ja, das ist mir auch schon öfters auf die Füße gefallen.
Hat mir dann die Augen geöffnet,
warum zwischendurch irgendwas Komisches passierte, was man
irgendwie nicht erwartet hätte, ja. Muss man nochmal drüber
nachdenken, was mache ich denn da überhaupt eigentlich?
Irgendwann was kaputt ist,
das ist schon immer so ein bisschen, hm.
Ja, ich glaube, das muss ich mir mal, ich habe das
schon mal ausprobiert, aber ich habe es noch nicht wirklich
häufig irgendwie in den
Dingen so verwendet, die ich so mache.
Ja. Also ich hatte das Gefühl
tatsächlich, dass es so ein bisschen langsam ist, aber
dann kann man das ja auch, glaube ich, aufzeichnen,
glaube ich. Aber, ähm.
Ja, die Idee davon ist
eigentlich, dass es eben nicht langsam ist.
Das ist halt
als Teil seinen normalen Test
laufen lassen kann. Aber also für mich war das
immer so ein Punkt, wo ich dann angefangen
habe, tatsächlich die Sachen einzuschränken, ja. Also wenn ich
halt gemerkt habe, okay, Herr Passus, jetzt langsam halt eine
eine Unit dann laufen lassen mit maximal
möglichen Parametern.
Und dann war es halt natürlich langsam, hat der Test
dann vielleicht auch mal fast eine Minute gedauert oder so.
Aber dann habe ich halt tatsächlich X-Cases gefunden, die ich
rausschmeißen konnte und konnte dann mir sinnvoll
überlegen, okay, der Eingabewert ist jetzt
vielleicht doch nur maximal, weiß nicht, siebenstellig oder
so, ja. Und nicht noch mehr.
Und dann wurde dann der Test natürlich dann viel schneller.
Und dann habe ich halt gesagt, ja, sorry, aber mehr
ist jetzt hier einfach nicht erlaubt.
Und das halt direkt mit abgefangen.
Und so. Das war, glaube ich, ja,
an der Stelle eine gute Strategie, um mal so ein bisschen
so die Grenzen zu gucken, was überhaupt an
I.O. da sinnvoll ist auch.
Oder so eine Sanitization zu machen an zwei Stellen
oder so, was gut ist.
Ja, und am Schluss muss halt auch der Code, der
dann irgendwas testet, genug schnell sein,
dass man den 200 Mal laufen lassen kann
und es dann halt trotzdem nur idealerweise
in Bruchteilen eine Sekunde geht.
Das ist nicht immer der Fall.
Ja.
Ja, das ist auch so ein interessantes
Thema, finde ich. Also ich mag
das sehr gerne, wenn Tests halbwegs schnell
durchlaufen. Ich finde das immer sehr frustrierend,
wenn Projekte so, wenn die
Tests so ewig brauchen, weil das halt auch
macht das Entwickeln irgendwie echt langsam.
Ja, also idealerweise halt ein, zwei Sekunden
nebenbei in der Idee, dann kann man sie dann
parallel laufen lassen und sieht direkt, wenn man irgendwas kaputt
gemacht hat. Ja.
Das ist auch gut. Ja, wäre
schön, aber ist dann halt bei größeren Projekten
schwierig, ja.
Irgendwann nicht mehr realistisch.
Aber dafür gibt es ja Testmarker.
Man könnte jetzt hingehen, könnte alle Tests,
die nicht so schnell gehen, als langsam markieren
oder sowas und die halt nicht immer parallel laufen
lassen, sondern nur dann, wenn man es explizit möchte
oder in der Pipeline oder so und nur
die schnellen standardmäßig nebenbei
von der IDE prüfen lassen.
Ja, kommt halt auch ein bisschen
darauf an, wie viele Tests man da hat.
Ja. Also wenn ich mir jetzt
PyTest selbst anschaue, wenn ich mir Cube Browser
anschaue, dann ist das irgendwas vierstellig
ist. Und
dann wird es zeitlich halt einfach knapp,
auch wenn die Tests selbst relativ schnell sind.
Das ist jetzt bei Cube Browser nicht der Fall.
Da sind es relativ viele End-to-End-Tests
und halt GUI-Applikationen und so.
Aber selbst wenn die Tests
schnell sind, wenn es dann halt ein paar Tausende
sind sogar in einem größeren Projekt,
dann ist das Endergebnis halt nicht mehr so schnell.
Ja.
Ja, irgendwann
kann man halt nichts mehr machen.
Was man ja eventuell machen könnte,
aber meistens, das hat man ja vielleicht auch nicht
immer, was Tests dann letztlich,
gut, ich meine, ich bin jetzt da eher
im Web-Anwendungsumfeld unterwegs,
was da die Tests langsam macht, ist halt immer, wenn man
irgendwie Datenbank-Zugriffe macht oder so,
dann ist halt das halt mal langsam.
Jetzt könnte man natürlich,
das weiß ich nicht, ich habe das ehrlich gesagt noch nie,
ich habe es einmal selber gemacht, auch um es auszuprobieren.
Was man da ja tun könnte, ist
halt so Repository-Pattern oder so verwenden
und dann halt quasi die Datenbank
wegabstrahieren und dann für die Tests halt durch
irgendwie eine Dummy-Datenbank ersetzen, die halt dann schnell ist
und dann sind die nicht mehr langsam.
Hast du schon mal gesehen, dass das jemand
erfolgreich gemacht hat und dass es in einem größeren Projekt
dann wirklich gut funktioniert hat?
Ja, das könnte ja ein Weg sein.
Ja, ich
bin jetzt nicht so
viel im Web-Umfeld unterwegs.
Ich habe ein Projekt, was ich maintaine,
Studentenportal.
So ein Portal für
Lernhilfen und
Zitate von Dozierenden
und sowas, halt von Studierenden für Studierende.
Und das
ist eine Django-Applikation und da hatten wir
das mal diskutiert
und sind dann zum Schluss gekommen, dass wir einfach
zu viele datenbankspezifische
Kleinigkeiten haben.
Also spätestens, wo du
halt irgendeine Volltext-Suche verwendest
und das halt dann so PostgreSQL
Fulltext-Search nutzt,
dann kannst du das nicht mal so auf die
Schnelle ersetzen.
Oder wenn du es kannst, läufst du
also in die Gefahr, dass die Tests dann überhaupt
nicht mehr das testen, was eigentlich in der Realität
läuft. Ja, klar.
Ja, das ist natürlich das Problem dabei.
Ja.
Ja, ich finde es auch schwierig.
Also so Datenbank-Sachen testen,
muss man sich oft darauf verlassen, dass das irgendwie geht.
Und dass das andere Menschen
schon getestet haben.
Und ja, das fällt dann halt auch tatsächlich
oft runter, weil das so ein bisschen
nervig sein kann.
Also, ne, weil das halt so langsam
wird dann im Entwickeln und wenn man das alles
aufsetzen muss, dann muss ja auch die Datenbank laufen.
Also ganz ehrlich, also alleine eine Datenbank laufen zu lassen
auf einem Dev-Rechner ist manchmal schon eine Herausforderung.
Je nachdem, was man alles draufhaben muss.
Ja gut, man muss ja auch den Website
angucken können auf dem Dev-System.
Ja, aber wenn dann halt
Menschen drei oder vier oder fünf verschiedene
Projekte gleichzeitig machen müssen und dann
haben die nur irgendwie einen Rechner mit 80 Gramm
oder sowas, muss dann irgendwie da mal einen Docker draufhaben und dann müssen
die Container aber irgendwie alle gleichzeitig anleihen, weil die schnell wechseln
müssen, dann macht es dann bei fünf verschiedenen
Datenbanken schon bumm. Dann musst du dann irgendwie gucken, dass du vielleicht
eine hast, die dann irgendwie weg abstrahiert ist, wo dann
aber auch die Klientel stimmen und dann musst du, wenn du eine abreißt,
nicht alle abreißen, weil du den Container nicht einfach kaputt machen kannst.
Und ja,
dann rennen wir schnell schon wieder
mit dem Kopf gegen eine Wand.
Da wäre so eine Softwareentwicklung
mit 8 GB RAM
finde ich halt auch so ein bisschen kritisch.
Ja, ist eine Katastrophe, ist das. Also Gott sei Dank muss ich sowas nicht tun.
Also Apple macht das ja,
dass sie ihre neuen MacBook Pros
haben im Standardmodell mit 8 GB
für tausend
noch was Euro. Ja, das ist eine Gemeinheit,
aber ja, so ist es.
Ja. Aber ja,
ich meine, ich mit Qt-Browser,
vielleicht soll ich da ja dann auch mal
nochmal
ein paar Worte dazu sagen.
Da muss ich halt ab und zu auch
Chromium kompilieren, also der Code
hinter Google Chrome.
Und das
braucht so mit einem Developer-Build,
also mit Debug-Symbolen und so
braucht das halt mal so irgendwie um die
30 GB RAM.
Wow, allein das Kompilieren von dem,
okay, das...
Wenn ich es halt parallel machen würde, nur mit so einem
Build-Job würde es mir wahrscheinlich auch weniger reichen.
Aber ja,
wir haben dann 32 GB
tatsächlich nicht mehr ausgereicht.
Ich bin jetzt
auf 48, was halt das Maximale
ist, was in den Laptop passt überhaupt.
Weil 16, glaube ich, fix
eingelötet sind.
Aber das fand ich
schon heftig. Also Chromium
ist ein riesiges Projekt.
Aber wenn es so
weitergeht, das wird dann nur noch komplexer,
wie es bei Software halt oft so ist,
habe ich echt irgendwann ein Problem.
Ja.
Habt ihr schon mal Tests irgendwo auf
anderen Rechnern laufen lassen, einfach nur? Also, das habe ich auch schon mal
gehört, dass Leute das gar nicht bei sich mehr laufen lassen,
sondern irgendwo nur in der Pipeline?
Mache ich
ganz oft, aus Feilheit.
Also, bei mir gehen die
Tests dann halt auch eine Weile und oft
lasse ich die dann lokal
halt gar nicht mehr laufen. Das ist eine gefährliche
Angewohnheit. Ja.
Ich pushe das halt mal,
wenn ich noch vernünftig bin in den Branch
und nicht gleich nach Main
und schaue dann halt mal, was da
zurückkommt von
GitHub-Actions.
Dadum.
Dieser Test ist fehlgeschlagen.
Oh, ja, okay. Meistens nicht.
Manchmal gelingt es einem halt, das durchzukriegen,
aber, ja.
Ja, okay.
Muss das aber halt, ja.
Was auch super ist, wenn man dann gar keine Testumgebung hat,
sondern es halt direkt durchgeht.
Du brauchst halt auch keine Entwicklungsumgebung.
Du machst halt alles bei GitHub. Ist das da Codespaces
oder so? Und dann ist das alles
nur noch in der Cloud.
Wunderbar.
Jemand anderes Problem.
Lass ich dann halt so die Tests für das, was ich
gerade daran arbeite, die lasse ich lokal laufen.
Aber so eine volle Testbatterie
soll woanders laufen.
Ja, aber auch das ist vielleicht ein guter
Punkt für Max.
Also, um Tests zu markieren nach verschiedenen
Themen oder sowas, dann kann man halt nur Tests laufen
lassen für das einzelne Topic oder
das Backend. Ja, aber ich meine, wenn du Entwickler hast,
machst du das ja meistens, dass du einfach sozusagen
entweder nur den einen Test, von dem du weißt,
dass der halt betroffen ist, irgendwie laufen lässt
oder halt eine Gruppe von Tests, die da
außenrum sind. Ja, genau. Aber
die Frage ist halt diese Gruppe, weil wenn du die thematisch
gruppierst und die vielleicht nicht an demselben Ort
liegen irgendwie, wenn man halt da, man kann ja die
Tests, das ist auch eine Frage der Philosophie, ob man
ein Testfahrzeichen schreibt oder an die
Applikationen oder an die ganzen Apps, wo die zugehören
oder so. Ja. Und wenn
die dann halt so distributed sind und dann
willst du aber trotzdem viele verschiedene davon zusammen
laufen lassen, weil die mit der Funktionalität dann doch irgendwie
zusammenhängen. Also, ja, also auch da eine Frage.
Kann man sich über die Architektur
Gedanken machen? Gibt es vielleicht doch Gründe, das dann so zu
machen oder, ne?
Und mit diesen Markern, die man da bei Python
erst rübersetzen kann, dann kann man ja einfach, die gruppieren
recht einfach. Finde ich gar nicht so
schlecht für diese Fälle.
Ja, mache
ich jetzt weniger. Ich habe einen Marker
einfach für alle GUI-Tests.
Sowas halt, weil
das halt wirklich projektübergreifend sind
Tests, die nutzen irgendwelche GUI-Dinge
und die testen einfach nur Python-Code.
Aber ansonsten,
ja,
ich kann mir jetzt vorstellen, so bei einem Enterprise-Projekt
können auch Kunden, die das so machen,
da dann wirklich so eine Use-Case
Nummer oder so noch dranhängen
und dann sagen, alle Tests irgendwie zu diesem
Use-Case laufen lassen.
Aber ansonsten, finde ich,
reicht eigentlich diese Unterteilung in Module.
Ja, also je modularer man
ist oder je modulitischer man so eine Anwendung baut,
dann müsste man vielleicht tatsächlich diese einzelnen
Funktionalitäten so ein bisschen
so ein Multilead voneinander
Ich weiß nicht, also bei mir reicht
auch diese Trennung in Dateien
eigentlich, ehrlich gesagt, aus.
Ich habe dafür den Marker
schon verwendet, aber nicht dafür.
Ja, aber genau, das
ist eine interessante Frage, was ich jetzt auch, also
einfach alles Teste in einem
Tests-Directory drin haben oder halt
neben die Module
im Code legen. Das sind ja auch zwei unterschiedliche Möglichkeiten.
Ich habe beides auch schon gesehen und
ich persönlich mag es lieber, irgendwie das
alles in einem Tests-Verzeichnis zu haben.
Ich mache tatsächlich beides.
Also ich habe einen Tests-Verzeichnis, wo
so die grundlegenden Sachen drin sind, wie
Kernfunktionalität, die Clients für
Authentication, die Nutzer
und sowas. Und
der
Testswanderer und diese ganzen Sachen und
die Haupt-Fictures oder auch
witzig, manchmal auch
meist einen anderen Fixtures schon. Das heißt,
Fixtures für Modelle lege ich mit in das Hauptverzeichnis rein,
aber die Tests selber, also
die einzelnen Units für Routen zum Beispiel,
die sind mit in dem API-Verzeichnis
zum Beispiel oder in der
App von Dango oder so.
Da muss man
die halt importieren, einfach
in den Konftest, die man halt da nutzt und dann kann man
aber direkt da die Tests schreiben, wo
die Anwendung quasi liegt. Man muss nicht die ganze Zeit
durch das ganze Directory so hin und her traversen.
Okay.
Und man kann halt auch modulär
arbeiten und die Leute wissen halt direkt, dass die Tests
da dazugehören und man vergisst dann nicht
welche für welche Module. Man kann halt auch einmal direkt sehen,
sind die Tests für die Module jetzt schon da drin oder welche
Tests für die Module gibt es denn da? Manchmal
finde ich sind Tests auch sehr nützlich sowas als
wie Dokumentation für
den Code. Wenn ich manchmal nicht mehr so
genau weiß, was passiert denn da jetzt eigentlich oder
was sollte da passieren, gucke ich mir den Test an und wenn der gut
geschrieben ist, sagt der Test, testet ja die Logik,
was da passieren sollte. Und dann lese ich den Test,
ah, so war das. Und dann,
das macht viel Sinn.
Das mache ich tatsächlich auch ganz oft.
Oft, wenn ich halt irgendwo einen Bug in einem
Python-Projekt finde, der sich nutzt, dann versuche
ich den halt mal kurz zu beheben.
Und dann schaue ich mir oft auch mal
irgendwie jetzt bei einem fremden
Open-Source-Projekt erstmal die Tests ein bisschen an,
um mehr ein Gefühl zu kriegen,
was da passiert.
Wenn es dann welche gibt.
Ja, gut.
Ja, das ist tatsächlich auch eine der Sachen, die oft runterfällt.
Ich mache das tatsächlich aber auch so,
wie das die PyTest-Dokumentation, glaube ich,
auch empfiehlt, dass ich einfach ein Testverzeichnis
habe und dann da quasi so
eins zu eins das
Python-Package gespiegelt.
PyTest-Dokumentation
ist auch noch so eine, ich fand
PyTest-Dokumentation war eine der schwierigeren Dokumentationen,
die ich lesen durfte.
Im Laufe der,
wenn er so Python kriegt.
Ja gut, ja, es ist halt auch kompliziert.
Ja, aber gerade.
Ich habe da so diesen
Curse of Knowledge halt.
Ich kenne das so unter diesem Begriff,
dass es halt echt schwierig ist, wenn man das alles schon
verinnerlicht hat. Ja, ich verstehe das.
Das nochmal so in den Augen eines Neulings
anzuschauen.
Also, dass man wirklich einfach verstehen kann, was denn da passiert.
Das ist so eine hohe Kunst, glaube ich.
Und das war also bei PyTest,
ich muss auch sagen, mittlerweile ist es einfacher,
also die Doku zu lesen, aber
manchmal ist es, hä, was wollen die denn jetzt und warum?
Und dann waren auch so ganz viele Fragen offen.
Die haben dann irgendwie ganz viel Knowledge halt auch tatsächlich
vorausgesetzt, dass man sich
halt irgendwo an irgendwelchen anderen Stellen so zusammenklauben
musste und wo musste man dann selber
finden und so und das war schon, war steil.
Aber ja, also was
noch vielleicht so eine coole Funktionalitäten
von PyTest, ich glaube, es gibt noch jede Menge Plugins,
die wir noch vielleicht erwähnen können.
Ich würde eins gerne herausfinden, VCR,
also irgendwie so Videorecording auch noch.
Das ist auch sehr cool, das, ja.
Was macht das denn?
VCR stellt quasi,
wenn du jetzt eine API nutzt und zum Beispiel ein Request,
zeichnet das quasi die
echten Antworten auf und
macht halt quasi einen echten API-Call
und schreibt das Ergebnis inklusive
aller Header und allem Content und so weiter
in Jamil-Files rein, automatisch
und beim nächsten
Call nimmt es einfach die und tut halt so,
als wäre die echte API-Antwort quasi
in der File drin und dann hast du quasi
die echte API-Antwort gemockt, quasi genauso
wie sie kommt und du kannst halt
PyTest immer sagen, okay, zieh jetzt mal neu,
also du bist gerade in einer Umgebung, wo du das ausprobieren kannst,
aber du willst ja die APIs auch wegen Quotas und so weiter
halt auch nicht ständig fragen zum Beispiel.
Oder halt auch
nur selten oder halt, wenn sich was aktualisiert
und kannst aber so halt dann schon gucken,
ob die API nach draußen halt auch funktioniert und
halt nicht nur so tun, als hast du die API nachgebaut,
sondern kannst ja tatsächlich direkt
benutzen. Ja, ich weiß nicht, ich mach
sowas ungern, also
da gibt es ja auch immer diesen
Spruch, ich weiß nicht, vielleicht
don't mock what you don't own,
also ich mock lieber meine eigenen Sachen als
das externe Geschichten, weil ich
weiß nicht. Ja, aber es ist ja eben vielleicht nicht gemockt.
Just record it.
Ja, aber das, ja gut, das ist ein bisschen
Convenience, aber du mockst es im Grunde schon.
Ja, ich weiß nicht, aber
Du willst ja nicht, dass
deine Tests wirklich auf die API
zugreifen im Normalfall.
Also gerade wenn du da irgendwie einen API-Key
brauchst, irgendwelche Credits hast oder
die API was ganz Schlimmes macht,
dann musst du die ja irgendwie mocken.
Ja, aber ich würde sie an der Stelle
mocken an der internen, sozusagen
bevor ich das aufrufe.
Die dann gar nicht aufrufen.
Ach so meinst du. An der Stelle, wo ich halt noch weiß,
was das ist, sodass ich halt auch weiß, wenn ich das
ändere, dass ich dann auch den Mock
ändern muss. Aber bei einem externen, wenn ich das einfach
nur automatisch mogge, dann weiß ich ja gar nicht,
wenn sich da jetzt irgendwas geändert hat, okay,
muss ich meine Mocks anpassen irgendwie, das
kriege ich ja nicht sozusagen direkt mit.
Ja. Gut, am Schluss
ist dein Code
ja sowieso kaputt, wenn sich an der API
wirklich was ändert. Ja, das, ja.
Da, was ich
einen schönen Ansatz finde da,
ist, dass man,
um vielleicht auch nochmal bei den Plugins einzuhängen,
es ist sehr einfach
PyTest halt eben irgendwie zu erweitern
und unter anderem auch ein eigenes
Kommandozeilen-Argument zu PyTest
hinzuzufügen.
Und was man dann machen kann,
ist theoretisch zumindest, ich habe jetzt
nicht ein Projekt, wo ich das effektiv mache,
tatsächlich,
eine Kommandozeilen-Option,
Real API oder sowas hinzuzufügen
und dann halt zu sagen, wenn ich das mitgebe,
laufen einmal meine Tests gegen die
richtige API durch,
anstatt gegen meine
recordeten Antworten.
Ja, das könnte man natürlich machen, ja.
Dann je nach API halt sagen,
das können wir nach, auf einer CI irgendwie
wöchentlich oder monatlich oder sowas mal
ausführen. Ja, also ich finde
es super spannend, also das macht halt echt
coole Sachen möglich.
Man kann ja auch seine eigene API quasi mit aufnehmen
oder sowas, wenn man das möchte und dann hat man
auch schnell so Mock-Fictures da, die man halt
nicht selber bauen möchte, selbst wenn du
sagst, okay, du möchtest gerne vorher das Mocken, aber
ich finde das schon ziemlich gut.
Ja gut, nee, kann ich auch gar nicht.
Man kann das sogar abusen,
wenn man sich viele
Zeugs irgendwie abspeichern will von
irgendwelchen Scrapern oder sowas, könnte man das tatsächlich
einfach einsetzen, um sich
die API-Calls einfach mal wegzuschapen
und das relativ easy.
Ja, ich
weiß nicht, also genau,
ich beurteile gerade, was ich
an Plugins normalerweise verwende,
weil X-Test verwende ich
tatsächlich irgendwie, aber
das muss man ja, wenn man irgendwie Tests parallel
ausführen lassen möchte.
Da kommt aber noch viel mehr
Zeug mit dabei, ich will manchmal
nicht so ganz sicher, ob ich das alles
haben will, aber was ich
auch oft benutze, also was ich total super finde,
ist PyTestMock zum Beispiel, finde ich super.
Ich bin mit Unitests, immer wenn ich
Unitests-Geschichten irgendwo mache und dann
türmen sich so die Patch-Dekoratoren
oder ganz viele Context-Manager
und dann ist PyTestMock echt total
also sehr angenehm.
Was macht das? Das übernimmt,
das macht das halt automatisch.
Du kriegst halt einen Mocker
und schreibst als Fixture sozusagen
in deinen Text-Test und dann
rufst du halt Mocker.patch irgendwie
einfach auf, musst aber da nicht
einen Context-Manager drum rum machen oder
irgendwie das Integriator verwenden und kannst das halt
auch mehrfach aufrufen, ohne
dass du da halt irgendwie dann eine Verschachtelung von
Context-Managern hast und
das wird halt hinterher auch wieder alles
entmockt sozusagen,
entgepatcht, wenn der Test vorbei ist und so.
Also ich finde es immer so,
ja, du hast recht, das ist für viele Sachen
ganz nett, aber ich finde es auch irgendwie hässlich, ich weiß nicht mehr genau
warum, was ist da so?
Ja, diese API halt von
unitest.mock, die macht schon irgendwie
ganz viel Magic, also da bin ich
auch nicht so wirklich zufrieden damit irgendwie.
Und ja, das Plugin ist eigentlich nur ein relativ dünner
Layer darum, um das halt
zu einer PyTest-Fixture zu machen, zum einen
und zum anderen,
wenn dann was schief geht, man kann
diese Mock-Objekte ja dann
im Nachhinein fragen, wurdest du jetzt so
und so aufgerufen?
Und wenn was schief geht, nochmal
PyTest einzuhängen, dass man halt
diese, den schöneren
Output von PyTest kriegt, der dann auch
die Werte vergleicht und sowas.
Aber viel
mehr als das macht das Plugin eigentlich nicht.
Apropos schöner Output, PyTest-Witch
natürlich.
Ah, okay, ja.
Ja, das hier überhaupt, das hat man noch gar nicht
so richtig, finde ich, ist eigentlich fast der Haupt,
das Hauptfeature von PyTest
für mich jedenfalls, dass halt die,
dass man einfach so Assertion schreiben kann
und das halt funktioniert und man halt trotzdem
sehr schöne Ausgabe kriegt irgendwie,
dann zeigt, wo ist genau was unterschiedlich
und so. Das ist
halt sehr, sehr angenehm.
Nicht so komisch, dass du sagst, ich will den Camel-Case.
Das ist aber auch übrigens eine
ordentliche Portion Magie.
Ja, ich fürchte auch irgendwie, ja.
Weil an sich dieses Assert-Keyword
von Python, das macht einfach nur
einen Assertion-Error, also ohne
jetzt, dass man irgendwie Zugriff hat
auf Infos, was da passiert ist.
PyTest macht
da eben sein Rewriting,
ja, durch den Dekorator.
Das ist den Abstract-Syntax-Tree,
was Python
aus so einem Modul generiert, intern,
bevor das wirklich dann zu Python-Byte-Code
wird. Das wird, passiert das
beim Import der Test-Module irgendwie, ne?
Da wird der Byte-Code dann
gedruckt. Ja, ja.
Nicht der Byte-Code, sondern halt ein Level vorher,
der Abstract-Syntax-Tree,
da injectet dann PyTest noch seine
eigenen Calls,
um da quasi einmal festzuhalten,
was ist da eigentlich drin in dieser,
in dieser Assertion.
Ja.
Ja, PyTest macht
viele Dinge, wo ich sagen muss,
genau, ist sehr viel Magie,
aber irgendwie so unterm Strich halt auch sehr
angenehm. Ja. Also hat
sich irgendwo bewährt.
Entspricht diesem Pythonic-ästhetischen
Ansatz irgendwie, das in klarer
Sprache hinzuschreiben, was das machen soll, und
das Assert ist da für Tests, glaube ich,
sieht einfach schick aus.
Ja, aber wäre das jetzt nicht auch schick,
wenn man, wenn ein Assert in einen anderen
Stellen genauso funktionieren würde?
Vielleicht denken ja Leute, wenn sie das
in PyTest verwendet haben, ah, das funktioniert ja
immer so, und machen das dann irgendwann anders, und dann
verhält sich das plötzlich ganz anders, als wir gedacht haben.
Ja, aber, also man kann ja zwar
Asserts ausschalten, ne, wenn man das
richtig aufruft, den Interpreter,
aber normalerweise macht man das ja nicht, und normalerweise fährt Assert
dann einfach mit einem Assertion-Error auf die
Nase. Ja, ja.
Aber in PyTest sieht das dann ja anders aus.
Na ja, aber das ist eigentlich
relativ klar, oder, dass halt, wenn ein Test
fehlt, dass der Assertion-Error dann mit mehr
Informationen auch zurückgegeben wird, also
das macht der ja schon, also der im Prinzip
ein fehlender Python-Test heißt, du hast ein Assertion-Error.
Ne, ne, ne,
das, ja, aber, also
Python-Test macht dann halt eine Menge Dinge.
Ja gut, aber das ist ja, dafür ist ja das Framework
ja da, das glaube ich, glaube ich, dass das ist. Ja.
Da wollte Ronny Pfandschmid, auch
einer der Maintainer, wollte da auch mal
irgendeinen Pip schreiben, oder sowas, dass man
sich eben bei Python grad
schöner reinhängen kann in diese Assertions.
Ja, das wäre, also,
das wäre schon ganz nützlich,
für irgendwie so eine Assertion-Lib, oder sowas,
die man einfach importiert, und dann hat man schönere Assertions,
oder so, das wäre doch cool, aber, ja,
wahrscheinlich ist es nicht so einfach. Genau, aber ich glaube, da ist es leider
nie was geworden.
Was es
gibt für Notebooks, vielleicht noch ganz
interessant, ein Ding namens
IPyTest,
was eben PyTest in diese Notebooks
integriert, also man kann da einfach mit
Prozent-Prozent IPyTest,
kann man halt PyTest ausführen,
und hat dann auch Zugriff gleich auf die lokalen
Variablen aus dem Notebook und sowas,
und das, wenn man
das einmal einrichtet in einem Notebook,
dann kriegt man auch in diesem Notebook
global quasi
geschenkt die
Assertion-Infos, wenn eine Assertion fehlschlägt.
Ach, und das geht dann auch an anderen Stellen,
sozusagen, dann, ah ja.
Genau, das hängt sich dann halt da irgendwie ein.
Ach, cool, das kann ich auch noch nicht.
Ja.
Und noch mehr Plugins
hier benutzt?
Wollte ich nochmal freescannen,
wenn ich irgendwie so Zeit sagen will,
also zu der und der Zeit, oder die Zeit muss ich jetzt um
zwei Stunden verschieben, zwischen zwei Tests
oder sowas, das ist ganz nett,
mit Context-Manager oder so,
das ist cool.
Ja, das habe ich schon genutzt, Responses.
Das ist Mocking
halt für Requests, man
ruft eigentlich, wie man Requests abruft,
ruft man halt erstmal Responses auf,
und das mockt einem das weg.
Ich glaube, das gibt auch für HTTPX, wenn ich das richtig gesehen habe.
Und da,
ich fände es eigentlich schön, wenn es
mehr so Mocking-Libraries
gibt, also sowas wie jetzt eben
freescannen, VCR, Responses
oder diesen HTTPX-Mock.
Ich bin eigentlich der Meinung,
jede Python-Library, die irgendwas macht
mit externen Systemen,
also auch sowas wie PySerial beispielsweise,
sollte halt
gerade auch irgendwie so Testsupport
oder so Mocks gleich mitliefern,
und dann auch schöne, maintained, getestete
Mocks.
Mocking ist immer noch sowas, das macht man irgendwie so
ad hoc in jeder Testsuite wieder neu
das Rad erfunden.
Ja, ist das nett.
Stimmt, da ist relativ viel Zeit
immer dann, bis man das richtig läuft.
Das ist wahrscheinlich sogar der Hauptteil,
den man braucht für Testschreiben.
Nö, das würde ich jetzt auch nicht sagen.
Aber es ist halt immer wieder
das.
Was ich noch gerne mache, ist
Insta-Fail.
Und dann sieht man halt direkt, wenn die Tests
ein bisschen länger laufen und die Tests, die fehlen schon mal,
kann man daran schon mal dann werkeln, weil man
einfach nur, keine Ahnung, sich verschrieben hat, vertippt hat oder so.
Hat man den schon mal dann drauf und das läuft dann
trotzdem noch.
Mhm. Ich nutze noch, da bin ich jetzt
nicht so stolz drauf, aber ich nutze noch
PyTest-Rerun-Failures,
wo man Tests halt als flaky markieren
kann und wenn sie fehlschlagen, werden sie halt
nochmal ausgeführt.
Weil ich bei Qt-Browser halt
wirklich aus GUI-Applikationen mit so
vielen externen Komponenten
dieses Problem mit flaky
Tests fast nicht in den Griff kriege.
Ah ja. Okay.
Und dann bis zu irgendwie eine
Assertion-Failure in der libc,
also so die Library-C selbst,
implementiert, wo ich sagen muss, dass
ich mir jetzt so viele Labels darunter, da kann
ich jetzt echt nichts daran ändern.
Also, was will ich machen?
Ja.
Aber natürlich nur so jedes tausendste Mal.
Ja.
Das ist ja ganz mies, wenn irgendwie so
ein Test nur jedes hundertste oder so
Mal-Fail schlägt, das ist ja ganz
eklig. Irgendwie so
das rauszufinden, bläh.
Das ist immer...
Ist das ein Plugin oder kann das Plug-Test, das weiß ich
gar nicht, aber dass man die Reihenfolge
irgendwie zufällig macht.
Random?
Ja, da gibt es ein paar.
Randomly.
Ja.
Ja, macht eigentlich Sinn, weil eben
Tests voneinander unabhängig sein sollten.
Und
andersrum gibt es PyTest-Order,
wo man sagen kann, Tests sollen halt voneinander
abhängig sein in einer bestimmten Reihenfolge.
Wie heißt das? Kannst du nochmal
betonen, bitte? PyTest-Order.
Ah.
Da kommt oft die Frage dann eben von
Kunden von mir, die dann
irgendwie Elektronik mit PyTest testen.
Weil da natürlich,
wenn man jetzt eine Klimakammer
hat oder so, dann ist das halt
nun mal so, dass die Dinge voneinander abhängen.
Oder dass man vielleicht
alle Tests irgendwie bei 30 Grad
laufen sollen, dass man
die erstmal laufen lassen will, anstatt
jedes Mal auf minus 10 Grad runter zu kühlen
und wieder hoch auf 30. Oder wie auch immer.
Ja.
Schlecht Sinn.
Ja.
Ja, PyTest-BDD nutze ich noch.
Ah, okay. Das ist interessant.
Ja, da habe ich auch schon häufiger was gehört.
Ja.
Ich habe es auch mal versucht zu nutzen.
Also, vielleicht nochmal kurz der Behavior-Driven
Development-Test.
Genau.
Man kann so Logik, so Business-Logik schreiben,
so für den PO oder so.
Und der kann dann so Sätze
formulieren in seiner eigenen Sprache
und dann guckt PyTest-BDD, ob es geht
oder nicht.
Aber so tief reinzukriegen...
Das ist im Prinzip einfach nochmal eine
kleine Abstraktion, dass man sagen kann,
given I have
an author user,
when I do this and that,
then this and that should happen.
Also mit diesem given, when, then.
Das halt wirklich als Testsprache
hat und dann die Implementation
der Tests
eigentlich nochmal abgekapselt
hat von den Test-Cases.
Also quasi so diese User-Story
reingießen, ja.
Genau.
Also ich hab's wieder rausgeschmissen, ich hab's ausprobiert,
aber irgendwie... Wahrscheinlich lag's aber auch
an einem Projekt halt, wo das halt nicht so wirklich
dazu gepasst hat.
Wofür verwendest du das?
Ich nutze halt ganz stark für die
End-to-End-Tests für Cube-Browser.
Jetzt müsste ich da vielleicht nochmal kurz einhaken,
was Cube-Browser denn überhaupt ist.
Jetzt hab ich's schon ein paar Mal erwähnt.
Das ist so mein Hauptprojekt
seit ziemlich genau
zehn Jahren. Ich glaub in
drei Tagen oder so sind's zehn Jahre.
Und zwar
ein Web-Browser, der
sehr stark auf Tastaturbedienung
ausgelegt ist, so inspiriert
von VI beziehungsweise WIM,
eben auf
Chromium aufsetzt und in Python
geschrieben ist. Und darüber
bin ich dann auch zu PyTest gekommen.
Und
das hat halt dann so
ein Interface
mit einer Command-Line quasi
eingebaut.
Und da hab ich dann halt auch viele End-to-End-Tests
wo ich halt einfach irgendwo ein Kommando
hinschicke zu einem laufenden Browser
und dann erstmal schaue
mit einem Web-Server, der direkt
im PyTest-Prozess läuft,
wurde dann das
die und die Seite aufgerufen oder ist
das und das passiert.
Und so diese End-to-End-Tests hab ich dann
halt eben mit diesem PyTest-BDD geschrieben,
dass ich sage, when I run
open und irgendwie
ein Pfad,
then this and that page should be loaded.
Hm.
Ja.
Ja, an der Stelle
klingt das durchaus sinnvoll, weil wahrscheinlich
hat man dann ganz viele davon und da will man ja
wahrscheinlich dann sozusagen nicht immer
das ganze Boilerplate
hinschreiben.
Ja, ich weiß auch nicht, ob ich es
nochmal so machen würde, weil
es sind jetzt halt doch sehr viele so End-to-End-Tests
geworden und da
ein einziges Problem mit flaky Tests
und mit langsamen Tests.
Aber ich glaube, für so gewisse Dinge
lohnt sich das schon. Also ich fand es auch ganz
angenehm, wenn halt neue Leute
dazukommen, die noch nie was mit PyTest
gemacht haben, dass du denen sagen kannst,
guck, schau dir das mal an,
das ist eine schöne,
eine hohe Abstraktion, nochmal höher als
Python-Code und schau mal, ob du so einen Test
schreiben kannst.
Ja.
An der Stelle ist es vielleicht auch noch ganz interessant, genau,
das ist ja auch, selbst wenn man jetzt nicht BDD
Tests sozusagen
so hinschreibt, sondern
normale Tests, dann empfiehlt es sich
da ja auch vielleicht, sich im Grunde an
dieses Pattern zu halten. Also
genau, Given-When-Then ist halt die eine
Formulierung, wie man das halt
ausdrücken kann. Es gibt noch eine andere,
die nennt sich irgendwie
Arrange-Act-Assert,
aber es ist im Grunde beides das Gleiche.
Es ist halt immer irgendwie, man baut sich zuerst irgendwie
einen
State zusammen, der halt irgendwie ist
und dann macht man
irgendwas drauf und dann guckt man hinterher, ist das rausgekommen,
was man sich irgendwie
was man erwartet hat und wenn nicht, ist halt
schlecht. Aber es macht halt
ja Sinn,
Tests immer so zu strukturieren, dass man
halt auch, wenn man jetzt auf den Test guckt,
sofort weiß, okay, ach, an der Stelle wird nur
irgendwas zusammengebaut, an der Stelle wird jetzt der eigentliche
Aufruf gemacht und hier assorten wir irgendwelche Dinge,
wo wir dachten, das müsste jetzt
da rauskommen, ja.
Das BDD, das klingt auch so ein bisschen
nach, als könnte man das mit Playwright machen.
Ich weiß nicht, ob das dieses Pattern auch ist.
Die Playwright-Tests,
die ich bisher gemacht habe,
ne, die waren halt einfach, da habe ich das alles immer von Hand hingeschrieben.
Ja.
Es ist halt, ja,
das macht aber so ein bisschen BDD auch, oder? Also es gibt halt
so einen Browser und sagt halt, okay, geh auf diese
Seite und drück mal so einen Knopf
und erwarte das. Ja, aber es sind schon
einfach Funktionsaufrufe, ist nicht irgendwie
Text, den man hinschreibt. Ja, okay, stimmt.
Ich wache es halt an, dass die es halt direkt abheißen, ja.
Ja.
Ja, ich glaube, ich, also mir fällt kein
Plugin mehr ein, was ich jetzt empfehlen wollen
würde. Welche hatten wir ja schon?
Ähm, was
muss ich mich fragen, ob sowas gibt, ich weiß
nicht, in der JavaScript-Welt, das sehe ich halt ab und zu
mal, gibt es halt auch so Dinge,
da läuft halt einfach immer irgendwie
oder da wird halt geguckt,
ob sich irgendwas an den Files geändert hat und wenn,
dann läuft halt da irgendwie der Testrunner
quasi die ganze Zeit und läuft
alle Tests, die dann halt sozusagen davon
beeinflusst sein könnten von irgendeiner Änderung, werden dann
halt nochmal ausgeführt und das gibt dann einem
so eine Art Dashboard, was halt gerade nicht funktioniert
oder was funktioniert, gibt es das
für PyTest eigentlich auch, weil ich glaube, sowas habe ich noch nicht
gesehen.
Ja, es gibt
Testmon.
Ah, okay, cool.
Ein größeres Projekt,
Testmon.org,
hatte ich mir mal angeschaut, aber jetzt auch schon
länger nicht mehr.
Ein paar Linken, guck mal nochmal rein.
Ich weiß, dass es auch
ein, zwei Leute gibt, die jetzt da so ein bisschen
noch schauen, wie
kann ich mit Coverage
halt auch dann schauen, welche Tests wirklich
beeinflusst sind von
einer Änderung und sowas.
Aber es ist schon noch so etwas, was
jetzt nicht so
in fix fertig, jetzt eben aus der
Testmon, also es gibt schon in fix fertig, aber
jetzt auch noch was, was ich weiß, dass Leute
dann arbeiten.
Ja.
Ja, ansonsten, ich weiß nicht, was haben wir denn noch
so für Themen?
Noch irgendwie größere Dinge
gar nicht besprochen oder?
Ja, vielleicht noch den
Development Sprint.
Naja, und zwar
gab es im 2016
glaube ich mal einen Development Sprint,
wo wir uns alle mal getroffen hatten
in Freiburg im Breisgau
und halt mal zusammen
rumgehackt haben an PyTest.
Zum einen halt eben so die
wirklichen Verdächtigen, die
Core-Entwickler, zum anderen aber auch
ganz viele Leute von irgendwelchen Plugins
oder auch einfach Leute, die mal was an PyTest
machen wollten. Und
ich bin gerade daran, fürs
24 sowas wieder zu
organisieren,
müsst ihr wahrscheinlich mal noch schauen, dass ich das auf die
PyTest-Webseite auch mache, weil
bisher war die Resonanz
nicht so
viel.
Ich hab da halt mal
von einem Kunden von mir das Angebot
bekommen, dass die
uns da
hosten bei sich in Vorarlberg,
was erstmal so
eben nirgendwo ist.
Vorarlberg klingt nach Alpen
irgendwo.
Ja, das ist tatsächlich ziemlich nah
als Österreich, aber
gerade an der Schweizer Grenze.
In einem Dorf mit irgendwie
3000 Leuten oder so
sind die zu Hause.
Omikron
heißen die und die hatten
mir angeboten, das halt
da zu hosten und
meinten noch, ja, wir können da
gratis essen und so und haben Sitzungsräume
und sowas.
Und da
hatte ich jetzt mal so eine Umfrage
gemacht, wer dann so kommen will und
es haben sich halt irgendwie fünf Leute oder so gemeldet.
Ich würde
da eigentlich ganz gerne ein paar mehr Leute noch haben.
Also eben in
2016 waren es 27
Leute.
Diesmal könnten wir schon
so 30, 35 oder so
könnten wir hosten.
Wahrscheinlich dann auch mit
Preise teilweise bezahlt und sowas
Unterkunft teilweise bezahlt. Müsste man sich
alles im Detail mal anschauen.
Wenn wirklich die Resonanz auch da ist.
Ja, cool. Also da kann man sich
auf jeden Fall mal melden, wenn man da Interesse hat.
Wann wäre das denn ungefähr
im Sommer oder?
Genau im Juni.
Dann ist noch ein bisschen Zeit.
Genau, Mitte,
Ende Juni, sowas. Müssen noch schauen,
welche Woche das wird.
Und dann
wäre eben so die Hoffnung,
dass wir da Leute zusammenkriegen,
die irgendwas machen wollen. Jetzt ohne
eine fixe Idee zu haben, was genau ist,
kommt dann mal alles noch.
Aber halt einfach so ein Development Sprint
wieder mal zu haben und sich mal wieder in Person
zu sehen auch.
Gute Sache.
Ja, was gibt's noch?
Ich würde sagen, mit Pytest sind wir glaube ich
mit den Themen, die ich zumindest auf der
Liste hatte, soweit.
Dann können wir vielleicht zu den Pics
der Woche des Monats der Folge
übergehen. Ja, können wir gerne machen.
Alles klar, dann mache ich
mal Kapitelmarke, Pics,
Upsi.
Also ich picke
fstring.help.
Aha, mich geehrt.
Ich glaube, ich hatte das auch schon
mal irgendwann gepickt, meine ich. Aber wir müssen mal
gucken. Wir picken immer nur noch Sachen,
die wir schon mal gepickt haben.
Ja, ist mir jetzt
letztens auch passiert, da habe ich es genau
in der nächsten Episode noch mal gepickt,
was ich schon mal gepickt hatte.
Ja, lass mal überlegen, was würde
ich denn picken? Ah, ich glaube, ich mache mal irgendwas aus dem
Data-Science-Bereich. Jetzt hat man das am Anfang schon,
so ein bisschen
den Mund wässrig gemacht mit dem
OpenAI-Thema und dann kam
aber überhaupt gar nichts mehr.
Ich versuche mich da wieder so ein bisschen reinzufuchsen. Ich mache das
ja auch, aber in letzter Zeit viel mehr Web-Entwicklungen
gemacht aus, weiß gar nicht, warum.
Eigentlich ist ja auch das große Thema
gerade, aber
und deswegen habe ich mir
auch mal geguckt, was gibt es denn da so an Kursen,
wenn man sich jetzt für diese ganzen Geschichten
LLM-Deployment-Kram
interessiert. Und da gibt es einen
Fast-Kurs von Fast.ai.
Jeremy Howard macht das, das ist super.
Den verlinke ich dann auch mal in den
Shownotes.
2022 und 23, ich weiß nicht,
ob es die 23 schon gibt,
aber die 22 ist auf jeden Fall, ich glaube, die habe ich,
das Ding ist echt.
Eigentlich müssten wir dazu eh noch mal eine Folge machen. Ich würde sagen, der Einstiegskurs
ist vielleicht sogar CS50
AI with Python für die Leute, die
so ein bisschen mehr anfangen, die Grundlagen
irgendwie. Und dann
parallel mit der
Video-Tutorial-Serie von Andrew Capaci
ein Fast.ai.
Ja. Würde ich sagen, dann ist
mein Datasign schon mit der Nase
ganz schön tief drin.
Wenn man so ein bisschen noch Statistik macht, vielleicht dann.
Oh, und dann picke ich vielleicht die andere
Geschichte, die ich mir auch aufgeschrieben hatte, gleich mit.
Es gibt eine super schöne
Visualisierung von, wie funktionieren
diese LLMs eigentlich, wo man halt sieht, wie ein
Token irgendwie oben so grafisch
irgendwo reinfällt und dann halt
irgendwie in Embeddings umgewandelt
wird und dann durch diese ganze Maschinerie durchläuft.
Dann kann man auch noch auswählen, welches Modell hätte man gerne.
Und wenn man das
natürlich, oh, das ist aber eine beeindruckende Visualisierung
und naja, das ist ja bestimmt alles irgendwie nur so,
hat sich jemand halt, ein Grafiker halt hingemalt
oder sowas. Nein, es ist tatsächlich, sind die
echten mehr oder weniger, also gut,
vielleicht nicht in jedem letzten Detail, aber es sind schon fast
die, schon quasi die echten Modelle
und da hat jemand sich echt Mühe gegeben
und in WebAssembly die ganzen
Operationen
alle nachimplementiert und
das ist schon großartig. Es gibt auch
den Source dazu.
Ja, es ist halt hauptsächlich
TypeScript und WebAssembly, aber
das ist aber nicht ManimaML.
ManimML.
Ne, wüsste ich jetzt nicht. Also, das ist halt einfach so
grafisch, man sieht halt quasi
wie so ein Ergebnis von
so einem Modell berechnet wird, halt grafisch.
Und wie heißt das?
Also, ich kenne ManimML.
ManimML.
Da muss ich mal grad nachgucken,
ob das genau so
heißt.
Das heißt einfach nur
LLM Visualization.
Ah, cool.
Also, bbcroft.net
Also, was man mit ManimML kann man
quasi seine eigenen Sachen auch bauen, weil man
da kann man sich auswählen, welche Layer man in sein
Neural-Network reinsteckt und dann
sowas bauen. Oh, das sieht aber auch
schick aus. Ja, gut, kann man jetzt nicht sehen, wenn man
es nur hört, aber... Ja, ja, Jochen hat es gerade aufgemacht
auf dem Screen. Das sieht sehr nice aus.
Das bitte auch einmal linken.
Genau, das hätte ich dann halt auch nochmal verlinken.
Ja, dann machst du ManimML direkt noch dazu.
Dann haben wir beide. Okay.
Mach ich dann auch.
Ja.
Florian, hast du auch einen Pick?
Ja, ich hatte erst mal gar nichts
und jetzt sind mir da gleich zwei Dinge eingefallen.
Ja, sehr gut.
Zum einen, als du Data Visualization
erwähnt hattest,
eine Webseite, die ich letztens
von einem Kollegen
gekriegt habe, datatowith.com,
was
einem so durchleitet, wenn ich eine gewisse
Art von Daten habe, also
jetzt irgendwie numerische Daten,
zwei Variablen, ordered,
was mir dann anzeigt,
wie plotte ich das am schönsten.
Mit dann auch gerade Links
zu irgendwie Python-Example-Code
und sowas. Ja, schick.
Das war das eine.
Das andere ist
die Evol-Game.
Weiß nicht, ob ihr das mitbekommen habt mit
The Password Game.
Eine Webseite, wo man halt ein Passwort eingeben soll
und dann kommen mehr und mehr
Regeln dazu, das irgendwie
um es dann dann
unmöglich zu machen.
Und basierend darauf,
Das Passwort-Game will ich auch.
Und basierend darauf hat jemand halt
The Evol-Game gemacht, wo man eine Python-Expression
eingeben muss, die dann immer mehr und mehr
Regeln folgen.
Okay, interessant. Das klingt gut.
The digits in your password
must add up to 25.
Großartig.
Sehr gute Idee.
Ganz so ähnlich sieht es dann auch beim Evol-Game aus.
Ja, nee.
Vielen Dank. Das klingt doch super.
Ja.
Ja.
Ja, ich glaube, dann sind wir
heute durch.
Vielen Dank, dass du da warst, Florian. Ich fand's
sehr schön.
Ja, danke euch.
Viele Dinge, die ich noch nicht wusste.
Ja, Python ist ein ganz essentieller
Teil, glaube ich, von dem, was wir so machen.
Auf jeden Fall.
Ja, dann danke, Florian.
Bleibt uns alle gewogen. Danke, Jochen.
Schreibt ein, wenn ihr wollt, wenn ihr irgendwas noch wissen
wollt, Fragen habt, Anregungen, Kommentare.
Vielen Dank auch von unseren lieben Hörerinnen und Hörern,
die uns Fanpost schicken oder
Fragen stellen und so. Das ist immer sehr nett.
Hallo at pythonpodcast.de
könnt ihr uns erreichen.
Dann bis bald und ein
gutes Jahresende, kann man ja fast schon sagen.
Wir sind ja bald schon im sechsten Podcast. Ja, Jochen.
Ach du jemine. Echt? Ist das schon so lang?
Ja.
Ui. Jetzt fühle ich mich ja noch älter als
normalerweise schon fühle. Aber gut.
Heißt also, die Folge muss jetzt noch
dieses Jahr rauskommen. Das wird aber auch noch nicht.
Ja, hier denke ich. Ja. Gut, gut.
Heute Abend.
Ja, schauen wir mal.
Also,
vielen Dank für eure Aufmerksamkeit. Ja, ebenso.
Ciao, Jochen. Tschüss.
Tschüss.