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