22 Stimmen

Welche Strategien gibt es für das Testen großer Zustandsautomaten?

Ich habe einen großen und ziemlich komplexen Zustandsautomaten geerbt. Er hat 31 mögliche Zustände, die alle wirklich benötigt werden (großer Geschäftsprozess). Er hat die folgenden Eingaben:

  • Enum: Aktueller Zustand (also 0 -> 30)
  • Enum: Quelle (derzeit nur 2 Einträge)
  • Boolesch: Anfrage
  • Boolesch: Typ
  • Enum: Status (3 Zustände)
  • Enum: Handhabung (3 Zustände)
  • Boolesch: Abgeschlossen

Eine Aufteilung in separate Zustandsautomaten scheint nicht möglich zu sein, da jeder Zustand unterschiedlich ist. Ich habe Tests für die gebräuchlichsten Eingänge geschrieben, mit einem Test pro Eingang, wobei alle Eingänge konstant sind, außer dem Zustand.

[Subject("Application Process States")]
public class When_state_is_meeting2Requested : AppProcessBase
{
    Establish context = () =>
    {
        //Setup....
    };

    Because of = () => process.Load(jas, vac);

    It Current_node_should_be_meeting2Requested = () => process.CurrentNode.ShouldBeOfType<meetingRequestedNode>();
    It Can_move_to_clientDeclined = () => Check(process, process.clientDeclined);
    It Can_move_to_meeting1Arranged = () => Check(process, process.meeting1Arranged);
    It Can_move_to_meeting2Arranged = () => Check(process, process.meeting2Arranged);
    It Can_move_to_Reject = () => Check(process, process.Reject);
    It Cannot_move_to_any_other_state = () => AllOthersFalse(process);
}

Niemand ist sich ganz sicher, wie die Ausgabe für jeden Zustand und jeden Satz von Eingaben aussehen sollte. Ich habe begonnen, Tests dafür zu schreiben. Allerdings muss ich etwas schreiben wie 4320 Tests (30 * 2 * 2 * 2 * 3 * 3 * 2).

Welche Vorschläge haben Sie für das Testen von Zustandsautomaten?


Editar: Ich spiele mit all den Vorschlägen und werde eine Antwort markieren, wenn ich eine gefunden habe, die am besten funktioniert.

0 Stimmen

Haben Sie zufällig schon All Pairs ausprobiert? Haben Sie eine andere Methode gefunden, die Ihren Ansprüchen genügt?

0 Stimmen

Leider ist mein Arbeitsplan im Moment ziemlich eng - ich sollte diese Woche etwas mehr Zeit haben, um mich damit zu befassen. Derzeit sieht die State Map wie die beste Lösung (h2g2java's), obwohl ich nicht vollständig in alle von ihnen noch untersucht haben.

0 Stimmen

Ich bin mir nicht sicher, ob ich das Konzept der Staatliche Karten (eigentlich habe ich am sicher, dass ich das nicht verstehe)

6voto

Finglas Punkte 15260

Ich verstehe das Problem, aber ich würde auf jeden Fall versuchen, die Logik aufzuspalten.

Der große Problembereich ist in meinen Augen:

  • Es gibt 31 mögliche Zustände, in denen er sich befinden kann.
  • Sie verfügt über die folgenden Eingänge:
    • Enum: Aktueller Zustand (also 0 -> 30)
    • Enum: Quelle (derzeit nur 2 Einträge)
    • Boolesch: Anfrage
    • Boolesch: Typ
    • Enum: Status (3 Zustände)
    • Enum: Handhabung (3 Zustände)
    • Boolesch: Abgeschlossen

Es gibt einfach viel zu viel zu tun. Die Eingaben machen den Code schwer zu testen. Sie haben gesagt, es wäre mühsam, dies in überschaubarere Bereiche aufzuteilen, aber es ist genauso mühsam, wenn nicht sogar noch mühsamer, so viel Logik in einem Rutsch zu testen. In Ihrem Fall deckt jeder Unit-Test weit zu viel Boden.

Ce site Frage, die ich zum Testen großer Methoden gestellt habe ähnlicher Natur ist, fand ich meine Einheiten einfach zu groß. Sie werden immer noch viele Tests haben, aber sie werden kleiner und überschaubarer sein und weniger Fläche abdecken. Das kann aber nur gut sein.

Testen von Legacy-Code

Überprüfen Sie Pex . Sie behaupten, Sie hätten diesen Code geerbt, also handelt es sich eigentlich nicht um testgetriebene Entwicklung. Sie wollen einfach, dass Unit-Tests jeden Aspekt abdecken. Das ist eine gute Sache, da jede weitere Arbeit validiert wird. Ich persönlich habe Pex noch nicht richtig benutzt, aber das Video, das ich gesehen habe, hat mich begeistert. Im Wesentlichen generiert es Unit-Tests auf der Grundlage des Inputs, der in diesem Fall der endliche Zustandsautomat selbst wäre. Es wird Testfälle generieren, an die man nicht genug gedacht hat. Zugegeben, dies ist nicht TDD, aber in diesem Szenario, Prüfung Legacy-Code, sollte es ideal sein.

Sobald Sie Ihre Testabdeckung haben, können Sie mit dem Refactoring beginnen oder neue Funktionen hinzufügen, wobei Sie sich auf eine gute Testabdeckung verlassen können, um sicherzustellen, dass Sie keine bestehenden Funktionen zerstören.

4voto

Lieven Keersmaekers Punkte 55277

All-Pair-Tests

Um die Anzahl der zu testenden Kombinationen einzuschränken und einigermaßen sicher zu sein, dass die wichtigsten Kombinationen abgedeckt sind, sollten Sie einen Blick auf All-Pair-Tests werfen.

die Gründe für All-Pairs-Tests ist folgender: Die einfachsten Fehler in einem Programm werden im Allgemeinen durch einen einzelnen Eingabeparameter ausgelöst. Die nächst einfachste Kategorie von Fehlern besteht aus die von Interaktionen abhängen zwischen Paaren von Parametern abhängen, die die mit der Prüfung aller Paare erfasst werden können.1 Fehler, die Wechselwirkungen zwischen drei oder mehr Parametern sind immer seltener2, während gleichzeitig gleichzeitig immer teurer teurer zu finden durch erschöpfende Testen zu finden, das seine Grenze in der erschöpfende Prüfung aller möglichen Eingaben.

Werfen Sie auch einen Blick auf eine frühere Antwort hier (schamlose Werbung) für zusätzliche Informationen und Links zu All-Pair und Pict als Werkzeug.

Beispiel Pict-Modelldatei

Das gegebene Modell erzeugt 93 Testfälle, die alle Paare von Eingabeparametern abdecken.

#
# This is a PICT  model for testing a complex state machine at work 
#

CurrentState  :0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
Source        :1,2
Request       :True, False
Type          :True, False
Status        :State1, State2, State3
Handling      :State1, State2, State3
Completed     :True,False

#
# One can add constraints to the model to exclude impossible 
# combinations if needed.
#
# For example:
# IF [Completed]="True" THEN CurrentState>15;
#

#
# This is the PICT output of "pict ComplexStateMachine.pict /s /r1"
#
# Combinations:    515
# Generated tests: 93

3voto

Adam Gent Punkte 45977

Mir fällt kein einfacher Weg ein, ein FSM wie dieses zu testen, ohne wirklich pedantisch zu werden und Beweise zu verwenden, Techniken des maschinellen Lernens zu nutzen oder Brute-Force anzuwenden.

Brachiale Gewalt: Schreiben Sie etwas, das alle 4320 Testfälle auf eine deklarative Art und Weise mit meist falschen Daten erzeugt. Ich würde empfehlen, dies in eine CSV-Datei zu packen und dann etwas wie NUnits parametrische Tests zu verwenden, um alle Testfälle zu laden. Jetzt werden die meisten dieser Testfälle fehlschlagen, so dass Sie die deklarative Datei manuell aktualisieren müssen, um korrekt zu sein und nur eine Stichprobe der Testfälle zufällig zu beheben.

Technik des maschinellen Lernens: Sie könnten einige Vektormaschinen oder MDA-Algorithmen/Heuristiken einsetzen, um zu versuchen, aus dem oben genannten Beispiel zu lernen und Ihrem ML-Programm Ihr FSM beizubringen. Dann lassen Sie den Algorithmus auf alle 4320 Eingaben laufen und sehen, wo die beiden nicht übereinstimmen.

3voto

Yauheni Sivukha Punkte 2536

Wie viele Tests sind Ihrer Meinung nach erforderlich, um die Funktion sum(int a, int b) "vollständig" zu testen? In c# wäre es etwas wie 18446744056529682436 Tests... Viel schlimmer als in Ihrem Fall.

Ich würde folgendes vorschlagen:

  1. Testen Sie die meisten möglichen Situationen, Randbedingungen.
  2. Testen Sie einige kritische Teile Ihres SUT separat.
  3. Hinzufügen von Testfällen, wenn Fehler von QA gefunden werden oder in der Produktion.

In diesem speziellen Fall ist es am besten zu testen, wie das System von einem Zustand in einen anderen wechselt. Erstellen Sie eine DSL zum Testen des Zustandsautomaten und implementieren Sie die häufigsten Anwendungsfälle damit. Zum Beispiel:

Start
  .UploadDocument("name1")
  .SendDocumentOnReviewTo("user1")
  .Review()
  .RejectWithComment("Not enough details")
  .AssertIsCompleted()

Das Beispiel für die Erstellung einfacher Tests für Abläufe finden Sie hier: http://slmoloch.blogspot.com/2009/12/design-of-selenium-tests-for-aspnet_09.html

3voto

Peli Punkte 2455

Utilice SpecExplorer o NModel .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X