Work in Progress
Diese Seite ist aktuell im Review! Die Seite wurde noch nicht qualitätsgesichert und kann Fehler enthalten.
Die verlinkten Seiten sind ggf. nur für Schleupen-Mitarbeiter sichtbar.

Testklasse für generische Tests

Das Ziel dieses Musters ist es, durch vorgefertigte Tests eine Fachapplikation (Land) auf allgemeine Fehler hin zu untersuchen und diese über Tests abzudecken. Durch Tests mithilfe von NUnit lassen sich komplexere Prüfungen als durch die statische Musterprüfung durchführen. Zu diesen Tests gehört beispielsweise das Aufdrahten des DI-Containers der Server-Applikation oder das Testen von Repositories.

Design

Um in der Fachapplikation die generischen Tests anzuschließen, muss eine Klasse angelegt werden, die sich von der Basisklasse Generic<XY>TestBase ableitet. Alle ausgeführten Tests sind dabei Unittests.

Implementierung

Zur Implementierung ist lediglich das Ableiten von der jeweiligen Basisklasse notwendig.

public sealed class GenericXYTests : GenericXYTestBase
{ }
Deaktivieren einer Prüfung

Um die Tests anzuschließen ist lediglich eine Ableitung von der Basisklasse notwendig. Möchte man einzelne Prüfungen für einen Typen deaktiveren, so ist das SuppressGenericTest-Attribut zu verwenden,

[SuppressGenericTestAttribute(GenericXYTestBase.CheckXY)] // Hierdurch wird die Prüfung XY unterdrückt.
public sealed class MyClassToCheck
{ }

Die im Attribut zu verwendende Konstante mit dem Namen des zu unterdrückenden Tests, befindet sich jeweils in der Basisklasse.

Repository-Tests (NHibernate)

Für Repositories nach Muster Objektpersistierung mit NHibernate für die Verwendung von NHibernate stehen aus dem Framework Basisklassen mit Tests zur Verfügung. Diese sollten in jeder Fachapplikation angeschlossen sein.

/// <summary>
/// Anschluss in Schleupen.Land.Repositories.
/// </summary>
public sealed class GenericRepositoryTests : Schleupen.CS.PI.Framework.Persistence.Testing.NHibernate.GenericRepositoryTestBase
{
    protected override Assembly Assembly => typeof(MyRepository).Assembly; // Assembly mit den Repositories

    protected override IConnectionInfoProvider ConnectionProvider => new ConfigurationFileConnectionInfoProvider();
}

Für Repositorys nach Muster Objektpersistierung mit NHibernate stehen Tests zur Verfügung, die die allgemeine Funktionalität sicherstellen sollen, z.B. wird das Mapping geprüft. Hierzu muss man sich von GenericRepositoryTestBase ableiten. Die Basisklasse durchsucht dann die Assembly, in der Unterklasse definiert ist nach zu prüfenden Typen; in diesem Fall also Repositorys.

Auch diese so angebundenen Tests für NHibernate-Repositorys sind dann in der NUnit-GUI zu sehen.

Deaktivieren von Prüfungen

Falls bspw. Aggregate von den Prüfungen ausgeschlossen werden sollen, müssen z.B. Properties CheckCourseGrainedLockAggregates und CheckValidatedAggregates überschrieben werden, indem dort die Typen rausgefiltert werden.

Service-Tests (DI, Castle)

Es gibt auch einen generischen Test, der prüft, ob die WCF-Services per DI zusammengebaut werden können. Dazu sucht er alle Service-Interfaces und versucht damit, eine Instanz des jeweiligen Services über Castle zu erzeugen:

/// <summary>
/// Testet alle Services.
/// </summary>
internal sealed class MyGenericServiceTest 
    : Schleupen.CS.PI.Framework.Testing.DependencyInjection.Castle.GenericServiceTestBase
{
    protected override Assembly ServiceAssembly => typeof(SomeType).Assembly;

    protected override ContainerConfigurator ServiceConfigurator => new MyTransientWcfConfigurator();


    protected override IEnumerable<System.Type> FilterTypesForGetImplementationOfInterface(
        IEnumerable<System.Type> serviceInterfaceTypes)
    {
        // ISomeService wird explizit ausgeschlossen
        return serviceInterfaceTypes.Except(new[] { typeof(ISomeService) });
    }

    private sealed class MyTransientWcfConfigurator : MyExistingWcfConfigurator
    {
        protected override void SetupLifestyle(Assembly assembly, BasedOnDescriptor descriptor)
        {
            if (descriptor == null { throw new ArgumentNullException(nameof(descriptor)); }

            descriptor.LifestyleTransient(); // Hier den Lifestyle ändern. Siehe Anmerkung unten.
        }
    }
}

Ab dem Framework in Version 3.3.0.0 muss der Konfigurator den Lifestyle der registrierten Komponenten des Frameworks auf Transient ändern. Der Standard aus dem Framework ist PerWcfRequest. Dies funktioniert im Kontext von Unittests nicht (im ServiceTestFixture (-> ComponentTest) bleibt es aber bei PerWcfRequest).

Soll eine Service-Schnittstelle vom Test ausgeschlossen werden, so kann dies durch das Attribut Schleupen.Framework.SuppressGenericTestAttribute oder direkt im Code durch überschreiben der virtuellen Methode FilterTypesForGetImplementationOfInterface erfolgen.

Sämtliche Services müssen getestet werden, ob diese durch Interceptoren gewrapped werden können.

Folgende Attribute müssen dazu auf true gestellt werden

protected override bool PerformServiceImplementationMethodsCanBeInterceptedTest => true;

protected override bool PerformServiceImplementationHasServiceBehaviorAttributeTest => true;

Um sicherzustellen, dass die Services überhaupt mit dem ErrorHandler-Attribut versehen sind, muss auch dies angeschaltet werden:

Folgendes Attribut muss dazu auf true gestellt werden:

protected override bool PerformServiceImplementationHasErrorHandlerBehaviorAttributeTest => true;
Assembler-Test

Für Assembler, die nach Muster Anschluss des Domänenmodells an die Service-Fassade erstellt wurden existieren ebenfalls automatisch generierte Tests.

internal sealed partial class GenericAssemblerTestBaseTest : GenericAssemblerTestBase
{
    protected override Assembly Assembly => typeof(SomeType).Assembly;

    protected override IContainerConfigurator ContainerConfigurator => new MyTestConfigurator();
}

Erweiterungen

Zusätzlich zu den durch die Basisklasse bereitgestellten Tests können eigene Tests für fachapplikationsspezifische Prüfungen in der Unterklasse implementiert werden.

Stärken und Schwächen

Stärken
  • Prüfung auf häufig auftretende Fehler
  • Geringer Implementierungsaufwand
  • Tests stehen allen Fachapplikationen zur Verfügung
Schwächen
  • Eigentlicher Testcode befindet sich nicht in der Fachapplikation, daher kann es etwas aufwändiger sein, im Fehlerfall diesen zu verstehen

Benutzte Muster

Cookie Consent mit Real Cookie Banner