Testing

In der GP-Komponente selber werden die Stufen UnitTests, ComponentTests, IntegrativeTests der Testpyramide für Workflows und UIs erstellt, um die Software zu testen und die notwendige Qualität sicherzustellen. Im Folgenden wird hier die Umsetzung der verschiedenen Tests und der dabei verwendeten Konstrukte beschrieben.

Die Struktur und das Codieren von Tests hat dieselben Qualitätsansprüche wie der Produktiv-Code!

Test von Workflows

Im Folgenden wird beschrieben, welche Arten von Tests für Workflows auf welche Weise erstellt werden.

UnitTests

Klassen, die für sogenannte UserCodes zur Umsetzung von Workflows nach der Generierung erstellt werden, können genauso wie UnitTests für Länder getestet werden. Die Struktur der UnitTests ist dabei identisch.

ComponentTests

Zur Implementierung eines ComponentTests für einen Workflow wird ein WorkflowServiceTestFixture<TProcessService> verwendet, das eine Ablaufumgebung für Workflows darstellt. Eine exemplarische Codierung zeigt folgender Code:

public class BuecherAusleihenProcessServiceTest
{
  [Test]
  public void RunWorkflow_HappyPath_ShouldPass()
  {
    using (var workflowFixture = new WorkflowServiceTestFixture<IBuecherAusleihenProcessService>(...))
    {
      string sessionToken = workflowFixture.SessionToken;
      workflowFixture.WithOpenedWorkflowServiceHost(testSequence =>
      {
        testSequence.StartWorkflow(m => m.Start(new StartRequest
                            {
                              SessionToken = sessionToken
                            }));
        testSequence.ExpectRequestReplyServiceCall<IBuecherAusleihenActivityService, AusleihenResponse>(
          x => x.Ausleihen(It.IsAny<AusleihenRequest>()),
          new AusleihenResponse());
      });
    }
  }
  ...
}

Dabei ist TProcessService die Schnittstelle des zu testenden Workflows. Mithilfe der Operation WithOpenedWorkflowServiceHost() wird ein Host gestartet, in dem der Worfkflow ausgeführt wird. Bei ComponentTests können mithilfe des WorkflowServiceTestFixture<TProcessService> Stubs und Mocks für die Serviceaufrufe spezifiziert werden, womit ein Durchlauf spezifiziert und getestet wird.

IntegrativeTests

Diese Tests werden genauso wie die vorherigen ComponentTests codiert, wobei i.A. die Services nicht durch Test-Double ersetzt werden.

Test von UIs

Im Folgenden wird beschrieben, welche Arten von Tests für UIs wie erstellt werden.

UnitTests

Klassen, die für sogenannte UserCodes zur Umsetzung von Workflows nach der Generierung erstellt werden, können genauso wie UnitTests für Länder erstellt werden.

ComponentTests

ComponentTests von Dialogschritten werden unter Zuhilfenahme des PresentationEngineFixtures erstellt. Deren Verwendung zeigt der folgende Code:

public sealed partial class BuchIdentStepStepActivityTest : IDisposable
{
  ...
  [Test]
  public void OnButtonClearQueryCriteriaClicked_ShouldClearCriteria()
  {
    BuchIdentStepStepActivity testObject = fixture.CreateAndOpenStep();
    testObject.BuchCriteria = new BuchCriteriaViewModel { Titel = "Per Anhalter durch die Galaxis", Autor = "Autor", Erscheinungsdatum = DateTime.Today };
    testObject.OnButtonClearQueryCriteriaClicked();
    Assert.That(testObject.BuchCriteria.Titel, Is.Null);
    Assert.That(testObject.BuchCriteria.Autor, Is.Null);
    Assert.That(testObject.BuchCriteria.Erscheinungsdatum, Is.Null);
  }
  private class Fixture : IDisposable
  {
    private readonly PresentationEngineFixture fixture = new PresentationEngineFixture();
    public BuchContract SampleBook { get; } = new BuchContract
    {
      Titel = "Per Anhalter durch die Galaxis",
      Autor = "Douglas Adams"
    };
    public BuchIdentStepStepActivity CreateAndOpenStep()
    {
      var stepActivity = new BuchIdentStepStepActivity(fixture.CreateStepDependencies());
      fixture.OpenDialogStep(stepActivity);
      return stepActivity;
    }
    public void RegisterBuchEntityServiceSubstitute()
    {
      Func<QueryRequest, QueryResponse> queryFunc = r => new QueryResponse { BuchListe = new[] { SampleBook }.ToList() };
      var substitute = new BuchEntityServiceFake(queryFunc);
      fixture.RegisterWebserviceSubstitute<IBuchEntityService>(substitute);
    }
    ...
    private class BuchEntityServiceFake : IBuchEntityService
    {
      private readonly Func<QueryRequest, QueryResponse> queryFunc;
      public BuchEntityServiceFake(Func<QueryRequest, QueryResponse> queryFunc)
      {
        this.queryFunc = queryFunc;
      }
      public QueryResponse Query(QueryRequest request)
      {
        return queryFunc(request);
      }
      ...
    }
  }

Das Fixture stellt dabei eine leichtgewichtige Implementierung dar, so dass das Auslösen eines Klicks explizit manuell initiiert wird (d.h. nicht per Framework-Aufruf, sondern durch Aufruf der hinter dem Button angeschlossenen Methode). 

IntegrativeTests

Diese werden mithilfe von Robot Framework und Selenium erstellt.

Test von Services

Services in GP-Komponenten werden identisch zu den Tests von Serivces in Ländern erstellt.

Cookie Consent mit Real Cookie Banner