Test pyramid - a critical look - Ronald Brill

Поделиться
HTML-код
  • Опубликовано: 4 окт 2024

Комментарии • 7

  • @wolfsluytermanvanlangeweyd6741
    @wolfsluytermanvanlangeweyd6741 4 месяца назад +2

    Interessante Anregungen zu diesem Thema. Damit kann man prima in eine Diskussion einsteigen. Eventuell stelle ich das mal meinem Team vor.

  • @StefanMenzner
    @StefanMenzner 3 месяца назад +2

    Ich würde so nicht wirklich „pauschalisieren „.. Testpyramide ist eine visuelle Metapher zu einer effizienten Gestaltung der Teststufen.. insbesondere in einem agilen Umfeld wie Scrum. Sie gibt eine sinnvolle Richtung für die Software-Qualitätssicherung vor. Daher würde ich sie nicht so einfach „weg lächeln “:)
    Microservises-Architektur hat selber kein einheitliches Kochrezept sondern sind Dinge im Kontext zu betrachten. Integrationstests feingranular betrachtet sind Tests der Komponenten auf Unittest-Ebene. Testpyramide ist übrigens ISTQB-konform und daher standard. .

  • @caelis512
    @caelis512 4 месяца назад +1

    Vielen Dank für den Podcast, tolles Video! Meinen Senf dazu:
    Was aus meiner Sicht ein pragmatischer Ansatz ist - und in den letzten Jahren bei “meinen” Projekten gut funktioniert hat … (Projekte sind meist kleine bis mittelgrosse Projekte, Hauptsächlich CRUD mit ein wenig Geschäftslogik, klassisch Client (Web) / Server (meist Spring) … ne DB und 1 bis 4 externe Systeme, ein Team von 3-6 Personen, nix Microservices, sondern Monolith oder modularer Monolith):
    Tests greifen so gut wie immer (und einzig) auf das “Public-API” zu. Pragmatisch umgesetzt bedeutet dies, das wir die Controller (HTTP-API) meist dumm gehalten haben (zu 80% sind die Methoden im Controller ein Einzeiler, die führen lediglich einen Call auf public Service durch). Die Tests verwenden somit dieselben Service-Methoden, welche auch vom Controller verwendet werden (nenne die “Public-API”). Alternativ denkbar ist, direkt das HTTP-API aufzurufen (ist etwas umständlicher; aber da der Controller dumm gehalten wird; ist es meist vertretbar die Service-Methoden zu verwenden).
    Frontend wird versucht (sofern Anforderungen das zulassen) so dumm wie möglich zu halten … Validierungen finden zu 95% rein im Backend statt (sind somit einfach mit-testbar).
    Externe Systeme werden beim Testen durch “Simulatoren” ersetzt. Diese sollten sich ähnlich wie das richtige System verhalten (werden bei der Testerstellung schrittweise erweitert / verfeinert; je nachdem was ich im Test benötige). Diese Simulatoren lassen sich währen der Testausführung manipulieren (z.B. mit Daten befüllen). Daten halten diese einfach In-Memory (z.b. in HashMaps). Die Simulatoren setzen möglichst spät an, üblicherweise direkt dort, wo das richtige externe-System per HTTP (oder gRPC, …) aufgerufen wird (Umgesetzt per Spring DI; haben dann 2 Implementierungen: Die eine ruft das externe System per HTTP auf, die andere Implementierung ist der Simulator).
    Für die Testausführung wird dann ne H2-DB verwendet (per Default). Bei der Test-Ausführung in der Pipeline kann die H2 mittels Testcontainers auch durch PostgreSQL/SQL-Server/… ersetzt werden.
    Beim Test-Setup (Daten für den Test vorbereiten) benutzen wir ebenfalls (zu 95%) nur das Public-API und die das API der Simulatoren (externe Systeme). Also manipulieren nichts direkt an der DB, sondern verwenden dieselben Funktionen, die auch ein Benutzer verwenden würde, wenn dieser nene Geschäftsfall anlegt (sind somit auch gleich mit-getestet).
    Tests testen die Spezifikation (wenig interne Details).
    Reine Unit-Tests verwenden wir eher wenig, lediglich in Spezialfällen aus Performance-Gründen; beispielsweise um eine eine komplexe Gebührenberechnungs-Funktion (Geld!, schlecht wenn das was falsch berechnet wird) mit allen Edge-Cases zu testen.
    Wir haben somit vielleicht zu 85% Integrationstests, 15% Unit-Tests. Da hauptsächlich das Public-API in Tests verwendet wird, sind die Tests auch relativ robust gegen internes Refactoring.
    Schöner Nebeneffekt mit den Simulatoren ist: Ich muss nicht warten, bis das externe System fertig entwickelt worden ist. Ich bin nicht betroffen von Ausfällen des externen Systems (kann passieren, falls sich das noch ein Entwicklung befindet). Und: Mit den Simulatoren und der H2-DB hab ich ein (falls ich das will; kann optional echte DB und echte externe Systeme einbinden) ein komplett eigenständiges Backend. Git-Checkout und starten… ich muss keine DB einrichten, kein Docker, brauche keine Verbindung zu den externen Systemen… könnte auf einer einsamen Insel offline entwickeln.

    • @caelis512
      @caelis512 4 месяца назад

      Vielleicht noch Nachtrag, wie das (angenommen Spring/Java) konkret umgesetzt aussieht:
      Angenommen mein Projekt heisst “myproject”:
      Maven-Modul “myproject”:
      * Hier befindet sich der eigentliche Code.
      * Echte Anbindung an die Produktiv-Systeme (HTTP/gRPC/SOAP-Aufrufe).
      * Die 15% Unit-Tests.
      * Application-Properties konfiguriert für die Produktion.
      * Das Modul wird in Produktion aufgeliefert.
      Maven-Modul “myproject-dev”:
      * Dieses Modul wird *nicht* in Produktion ausgeliefert.
      * Hat ne Dependency auf “myproject”.
      * Hier befinden sich die Simulatoren.
      * Application-Properties, welche die Prod-Services (für Externe-Systeme) durch die Simulatoren ersetzt und H2 Konfiguriert.
      * Hier befinden sich die 85%-Integrations-Tests (Grund: Benötigen die Simulatoren).
      * Kann auch verwendet werden um das Backend ohne externe Dependencies zu starten (ohne DB-Setup oder Verbindung zu externen Systemen).
      … ist ne Vereinfachung und andere Setups sind denkbar.

    • @richard-seidl
      @richard-seidl  4 месяца назад

      Danke für die Insights! Sehr spannend! 🖖🏻

    • @konstantinf.905
      @konstantinf.905 3 месяца назад +1

      Moin, schon Mal über Wiremock nachgedacht? So könntest Du dir die zweite Impl. sparen und die erste wird schon früher in den Tests ausgeführt - nicht erst auf dev/prod. Viele Grüße