2016-03-28 4 views
1

Ich arbeite an einer erheblichen Anzahl von Integrationstests in MSTest (100+ für ein Subsystem), und ich möchte wirklich verwandte Tests in ihre eigenen Testklassen gruppieren, für die Lesbarkeit und weil anders Testgruppen erfordern unterschiedliche Konfigurationseinstellungen.Sharing Services über Testklassen in MSTest

Die Tests begannen ursprünglich mit einer großen Testklasse, die statische Instanzen bestimmter Dienste enthielt. Diese Dienste brauchen eine Weile, bis sie hochgefahren sind, und sie werden die Testausführungszeit dominieren, wenn sie für jeden Test hochgefahren und abgerissen werden. Der ursprüngliche Testcode hat so angefangen.

Das Problem damit ist, dass verschiedene Testgruppen die Dienste in verschiedene Zustände setzen müssen, bevor die Tests ausgeführt werden.

Meine erste Idee war es, die statische Dienste in einer gemeinsamen Basistestklasse zu halten, und dann neue Testklassen erstellen, die für jede Testgruppe von der Basisklasse erben, wie folgt aus:

[TestClass] 
public class TestClassA : IntegrationTests 
{ 
    /* tests */ 
} 

[TestClass] 
public class TestClassB : IntegrationTests 
{ 
    /* tests */ 
} 

[TestClass] 
public class TestClassC : IntegrationTests 
{ 
    /* tests */ 
} 

Das Problem mit Das heißt, die Dienste werden für jede Testklasse hochgefahren und abgerissen. Zugegeben, das ist nicht so schlimm, wie sie für jeden einzelnen Test erstellt und zerstört werden, aber ich möchte sie für jeden Testlauf einmal erstellen.

Gibt es eine Möglichkeit, separate Testklassen zu verwenden, die alle die gleichen Dienste für Integrationstests in MSTest verwenden?

Antwort

1

Wenn ich Ihre Frage richtig verstanden habe, können Sie diese Dienste mit einem separaten Singleton implementieren. Etwas wie:

public class Services 
{ 
    static ServiceA _serviceA 
    static ServiceB _serviceB 
    public static ServiceA InstanceA 
    { 
    if (_serviceA == null) 
     _serviceA = new ServiceA(); 
    return _serviceA; 
    } 
    public static ServiceB InstanceB 
    { 
    if (_serviceB == null) 
     _serviceB = new ServiceB(); 
    return _serviceB; 
    } 
} 

Dann kann diese Klasse von allen Testklassen geteilt werden.

+0

Wie üblich, habe ich es geschafft, meine eigene Frage vor jemand anderem zu beantworten. Die Lösung war sehr ähnlich. Innerhalb meiner Test-Basisklasse habe ich einen statischen Konstruktor erstellt, der den gesamten Initialisierungscode verarbeitet. Diese Methode würde auch funktionieren. – CHendrix

0

IProgrammer's Antwort wird funktionieren, aber hier ist die Lösung, die ich gefunden habe.

Ich habe einen statischen Konstruktor die die Basistestklasse, wo alle Dienste sind hochgedreht, etwa so:

[TestClass] 
public class IntegrationTests 
{ 
    static ServiceA serviceA = new ServiceA(); 
    static ServiceB serviceB = new ServiceB(); 

    //Static constructor gets called once during the lifetime of the appdomain. 
    static IntegrationTests() 
    { 
    /* Gets the services up and going */ 
    } 
    [TestInitialize] 
    public void TestInit() 
    { 
    /* Gets services back into good states */ 
    } 

    /* Lots and lots of Integration tests */ 
} 

die Ressourcen Aufräumen, nachdem alle Tests war C# ein wenig komplizierter lief, da hat keine statischen Destruktoren.

Allerdings ist this answer provided eine ziemlich saubere und clevere Problemumgehung.

Hier ist der "statische" Destruktor-Code.

private static readonly Destructor Finalise = new Destructor(); 
private sealed class Destructor 
{ 
    ~Destructor() 
    { 
    /* Service cleanup code here */ 
    } 
}