Bei der Entscheidung, ob ich einer Regressionssuite etwas hinzufüge oder nicht, würde ich eine Reihe von Aspekten berücksichtigen. Vieles von dem, was ich in Betracht ziehen würde, wäre allerdings sehr produktspezifisch; zu verstehen, wie die Kunden das Produkt verwenden, wie das Upgrade-Verhalten aussieht und so weiter, wäre hier notwendig.

  1. Wie hoch ist das Risiko, dass der Fehler, den der Test aufdecken soll, übersehen wird?
    Je nachdem, auf welcher Ebene der Test stattfindet (Einheitstest, Integrationstest, Validierungstest usw.), kann dies schwer abzuschätzen sein, aber je näher ihr an dem seid, was der Endbenutzer sehen wird, desto einfacher ist es wahrscheinlich, das Risiko einzuschätzen.
  2. Wo in der Programmhierarchie befindet sich die Codeänderung, die getestet werden soll? Bei miserablem Spaghetti-Code ist das vielleicht schwer zu erkennen, aber je mehr Dinge von einer Funktion abhängen, desto weniger Dinge müsst ihr (wahrscheinlich) im Zusammenhang mit dieser Funktion testen, da ihr Ausfall eine Reihe anderer Komponenten des Betriebssystems zerstören könnte.
  3. Wie viele Dinge müssen schiefgehen, damit der Fehler aufgedeckt wird? Hier würde ich dazu tendieren, Dinge, bei denen mehr Dinge schiefgehen können, in der Regressionssuite zu belassen, als Dinge, die sich leichter aufdecken lassen, weil es wahrscheinlicher ist, dass man die einfachen Fehler in unverbundenen Tests findet, als die komplizierteren Fehler. (Dies setzt voraus, dass ihr Tester habt, denen Fehler auffallen, die nicht in der Dokumentation des Testszenarios enthalten sind).
  4. Wie lange ist der fragliche Fehler schon im Code, und wodurch wurde er aufgedeckt? Dies ist schwer zu quantifizieren, ohne mehr darüber zu wissen, was getestet wird, aber wenn ihr etwas habt, das speziell durch einen Sonderfall aufgedeckt wurde, würde ich es nicht unbedingt zu einem Regressionssuit hinzufügen, aber ich würde es zu meiner Liste der “dummen Dinge, die Endbenutzer tun, die mir nie in den Sinn gekommen wären” hinzufügen, die ich in Zukunft beim Schreiben von Tests berücksichtigen sollte.
  5. Wie subtil wäre ein Problem in einem bestimmten Bereich? Je subtiler das Problem ist, desto mehr Tests solltet ihr darum herum durchführen.
  6. Wie oft wird eine Funktion in der Praxis vorkommen? In dem von Ihnen genannten Beispiel, der Datenbankaktualisierung, muss diese Funktion vielleicht nur einmal getestet werden, wenn ihr sicher sein könnt, dass jeder den neuen Code erhält, sobald er freigegeben wird, bevor ihr eine neue Version veröffentlichen. Wenn ihr jedoch jemanden habt, der in drei Jahren eine neue Version des Programms erhält und derzeit eine Version benutzt, die zwei Jahre veraltet ist, dann könnte es ein Problem sein, das Upgrade-Szenario nicht in Ihren Regressionssuit aufzunehmen. (Ich bin mir nicht sicher, wie ihr die Migrationstests jetzt durchführt, daher kann dies etwas sein, worüber ihr euch Gedanken machen müsst, oder auch nicht).

Ich verstehe die Bedeutung von guten “Regressionstests”, um sicherzustellen, dass behobene Fehler nicht erneut auftreten. Aber ich denke, es ist möglich, zu weit zu gehen und am Ende mit einer massiven “Regressionstest-Suite” für jeden behobenen Fehler, jede geänderte Funktion, sogar jede entfernte Funktion zu landen… ihr versteht, worauf ich hinaus will. Gibt es Heuristiken oder Techniken, um zu identifizieren, wann ein Test in die langfristige Regressionssuite gehört, im Gegensatz dazu, wann es besser wäre, einen “Einmal”- oder “Wegwerf”-Test zu schreiben, der für die nächste Version ausgeführt und dann verworfen wird? Idealerweise möchten wir dies zum Zeitpunkt der Erstellung der Tests identifizieren, aber auch Tipps zur Identifizierung dessen, was im Laufe der Zeit aussortiert werden kann, sind hilfreich.

Die Hauptsorge besteht darin, den Zeitaufwand für jeden Release-Test zu minimieren. Wir haben eine große Legacy-Codebasis, die alte Technologien verwendet, die nicht sehr geeignet für automatisiertes Testen sind, was bedeutet, dass ein großer Teil unserer Regressionstests manuell durchgeführt wird. Wir möchten unsere manuelle Testbelastung für jeden Release nicht mit Tests erhöhen, die keinen langfristigen Wert bieten.

Wir befinden uns auch in einer regulierten Umgebung, daher benötigen wir eine Möglichkeit, zu dokumentieren, was wir getestet haben, und ich denke, es ist sinnvoll, einen guten Test zu entwerfen, wenn ihr etwas ändert, anstatt nur ad hoc zu testen. Aber einige Dinge werden realistischerweise nicht zwei Jahre später plötzlich fehlschlagen, wenn wir jetzt zeigen, dass sie behoben sind.

Einige Beispiele, bei denen mein “Bauchgefühl” sagt, dass sie nur für die erste Version nützlich sind:

  • Änderung der Form einer grafischen Steuerungsanzeige und Sicherstellen, dass alle Stellen, an denen eine solche Anzeige angezeigt wird, die neue Form verwenden (d.h., wir haben uns nicht wiederholt und den Code für die Anzeige dupliziert – dies ist ein Beispiel aus unserer Legacy-Codebasis, in der wir häufig kopierten Code und andere Wiederholungen gefunden haben).
  • Für ein Softwareprodukt, das Hardware steuert, haben wir die Unterstützung für einige Add-On-Geräte entfernt, die von der Hardware unterstützt wurden und in einer Datenbank gespeichert sind. Wir haben getestet, dass ein Upgrade der Datenbank von der Version, die die Geräte unterstützt hat, zur Version, die sie nicht mehr unterstützt, angemessen funktioniert und dass die Geräte in der neuen Version nicht mehr vorhanden sind.
  • Behebung eines “offensichtlichen” Fehlers, bei dem ein Dialogfeld nicht ordnungsgemäß aufgeräumt wird, wenn abgebrochen wird, usw.

Um die manuelle Regressionssuite davor zu bewahren, übermäßig groß zu werden:

  • Testwartung und -bereinigung: Überprüft regelmäßig die vorhandene Regressionssuite und identifiziert Tests, die nicht mehr relevant sind, redundant sind oder nur geringen Mehrwert bieten. Entfernen oder überarbeitet solche Tests, um Duplizierungen zu minimieren und den Fokus der Suite zu optimieren.
  • Testpriorisierung: Priorisiert die Tests basierend auf ihrer Bedeutung, der Abdeckung von Risiken und den Nutzungsmustern. Konzentrieren Sie sich auf kritische Funktionen, Bereiche mit hohem Risiko und häufig verwendete Funktionen. Durch die Priorisierung von Tests können begrenzte manuelle Testressourcen effektiv eingesetzt werden.
  • Risikobasiertes Testen: Wendet risikobasierte Testtechniken an, um Bereiche mit hohem Risiko zu identifizieren und die Testbemühungen entsprechend zu verteilen. Diese Vorgehensweise stellt sicher, dass die kritischsten und anfälligsten Teile des Systems angemessen berücksichtigt werden, während weniger kritische Bereiche einer leichteren Prüfung unterzogen werden.
  • Automatisierungsmöglichkeiten: Untersucht die Möglichkeiten zur Automatisierung bestimmter Aspekte des Regressionstests. Automatisierte Tests können den manuellen Testaufwand erheblich reduzieren und eine umfassendere Abdeckung ermöglichen, ohne dass dabei erheblicher Zeitaufwand entsteht. Konzentriert euch auf die Automatisierung von wiederholten oder zeitaufwändigen Tests.
  • Testgetriebene Entwicklung: Fördert einen testgetriebenen Entwicklungsansatz, bei dem Tests vor der Implementierung neuer Funktionen oder der Behebung von Fehlern geschrieben werden. Diese Praxis fördert die Erstellung gezielter, gut konzipierter Tests, die weniger dazu neigen, die Regressionssuite aufzublähen.

Beachtet, dass es ein iterativer Prozess ist, die richtige Balance zwischen gründlichem Regressionstesten und effizientem manuellem Testen zu finden. Überprüft und passt die Regressionssuite regelmäßig anhand von Feedback, Testergebnissen und sich ändernden Prioritäten an.