2010-04-28 8 views
17

Je configure des tests unitaires basés sur MSTest. Pour rendre ma vie plus facile, je veux utiliser une classe de base qui gère l'installation générique et taredown tous mes tests exigent. Ma classe de base ressemble à ceci:Utilisation de l'héritage dans MSTest

[TestClass] 
public class DBTestBase { 
    public TestContext TestContext { get; set; } 

    [ClassInitialize()] 
    public static void MyClassInitialize(TestContext testContext) { 
     var config = new XmlConfigurationSource("ARconfig_test.xml"); 
     ActiveRecordStarter.Initialize(Assembly.Load("LocalModels"), config); 
    } 

    [TestInitialize()] 
    public void MyTestInitialize() { 
     ActiveRecordStarter.CreateSchema(); 
     Before_each_test(); 
    } 

    protected virtual void Before_each_test() { } 

    [TestCleanup()] 
    public void MyTestCleanup() { 
     After_each_test(); 
    } 

    protected virtual void After_each_test() { } 
} 

Ma classe de test réelle ressemble à ceci:

[TestClass] 
public class question_tests : DBTestBase { 

    private void CreateInitialData() { 
     var question = new Question() 
          { 
           Name = "Test Question", 
           Description = "This is a simple test question" 
          }; 
     question.Create(); 
    } 

    protected override void Before_each_test() { 
     base.Before_each_test(); 
     CreateInitialData(); 
    } 

    [TestMethod] 
    public void test_fetching() { 
     var q = Question.FindAll(); 
     Assert.AreEqual("Test Question", q[0].Name, "Incorrect name."); 
    } 
} 

La fonction TestInitialize fonctionne comme prévu. Mais la fonction ClassInitialize ne s'exécute jamais. Il ne fonctionne si j'ajoute ce qui suit à ma classe enfant:

[ClassInitialize()] 
    public static void t(TestContext testContext) { 
     MyClassInitialize(testContext); 
    } 

Est-il possible d'obtenir ma classe initialize de base fonction pour exécuter sans faire référence dans ma classe enfant?

+2

Trop hacky à ajouter en guise de réponse: essayez d'utiliser un constructeur statique dans la classe de base. – roufamatic

+0

J'ai fini par utiliser AssemblyInitialize(). Pas exactement ce que je voulais, mais je suppose que MSTest ne le fait pas. @Roufamatic, votre réponse est probablement le seul moyen. Si vous l'affichez, je l'accepterai. – oillio

Répondre

4

Confirmer que c'était un problème pour moi aussi. J'ai utilisé un constructeur sur la base et un destructeur pour le nettoyage

+1

Le problème avec cela est que le finaliseur n'est pas garanti pour fonctionner à un moment déterministe. Par exemple, dans mes tests, je veux emprunter l'identité d'un utilisateur donné, mais une fois mes tests terminés, annuler l'usurpation d'identité. Cela ne fonctionnera pas avec un finaliseur, car il est probable qu'un certain nombre de mes autres tests seront exécutés avant d'être exécutés. –

+4

Le problème avec le constructeur est qu'il fonctionne de la même manière que TestInitialize. Il fonctionnera à chaque test. – bygrace

+0

Il n'y a pas de Finalizer ici - seulement l'utilisation de TestCleanup() - BIG difference. Le comportement et l'exécution de TestCleanup() sont déterministes et bien définis. –

8

La méthode ClassInitialize est exécutée si et seulement si la "classe" concernée contient au moins un TestMethod, et qu'au moins un TestMethod de la classe est sélectionné pour l'exécution.

+0

Eh bien, c'est une façon assez stupide de le coder. TestInitialize et TestCleanup ne fonctionnent pas de cette façon ... – oillio

+0

convenu - mais c'est la façon dont il est :-( – Ambuj

+0

J'ai ajouté à mon code: [ClassInitialize] nouveau ClassSetup public static void (contexte TestContext) { TestBase .ClassSetup (contexte); } –

0
[TestClass] 
public class question_tests : DBTestBase { 
... 
    [TestCleanup()] 
    public void TestCleanup() 
    { 
     base.MyTestCleanup(); 
    }