web-dev-qa-db-ja.com

テストで各クラスの後にClassCleanup(MSTest)を実行する方法は?

テストスイートを備えたクラスがいくつかあります。

各テストクラスはClassInitializeで始まり、ClassCleanupで終わります。私の問題は、ClassCleanupが各クラスの最後に呼び出されるのではなく、3つのクラスのすべてのテストの後でのみ呼び出されることです。この問題を修正できますか?ありがとう!

[ClassInitialize]
public static void SetUpBrowser(TestContext context)
{
    pageObjectBase.SetBrowser("chrome");
    pagesManager.GetPageObjectBase();
}

[TestMethod]
public void FindCriticalBug()
{
    bla-bla-bla();
}

[ClassCleanup]
public static void CloseBrowser()
{
    pageObjectBase.Stop();
    pagesManager.GeneralClearing();
}
13
Ellina

クラス間のテストを含め、テストは順序なしで実行されます。このブログ投稿を参照してください:

http://blogs.msdn.com/b/ploeh/archive/2007/01/06/classcleanupmayrunlaterthanyouthink.aspx

引用するには:

いずれにせよ、これが私の出力ウィンドウからの結果です:

AssemblyInitialize
TestClass1: ClassInitialize
TestClass1: TestInitialize
TestClass1: MyTestCase1
TestClass1: TestCleanup
TestClass2: ClassInitialize
TestClass2: TestInitialize
TestClass2: MyTestCase2
TestClass2: TestCleanup
TestClass1: ClassCleanup
TestClass2: ClassCleanup
AssemblyCleanup

...これは、TestClass1のClassCleanupがクラスの最後のテストケースの直後に実行されるという意味ではありません。実際、すべてのテストケースが実行されるまで待機し、TestClass2のClassCleanupと一緒に実行されます。

これは最初は驚きましたが、それは明らかに私が実際に考えていなかったためです。テストは原則として順序付けられていないため、TestClass1のすべてのテストがすぐに連続して実行される保証はありません。理論的には、実行エンジンはTestClass1からテストケースを選択し、次にTestClass2からテストケースを選択し、次にTestClass1から別のテストケースを選択する場合があります。初期化されているため、すべてのClassCleanupメソッドは、すべてのテストケースが実行されるまで延期される可能性があります。

残念ながら、これがうまくいかない場合は、順序付けられたテストまたは別の単体テストフレームワークを確認する必要があります。

14
John Koerner

TestCleanupAttribute と呼ばれる別の属性があり、すべてのテストの後に実行されます。

TestInitializeAttribute と呼ばれるすべてのテストの前に実行する属性もあります。

これらが一緒に実行されている例を次に示します。

[TestClass]
public class MyTests
{
   [ClassInitialize]
   public void ClassInitialize() { Debug.Print("Running ClassInitialize"); }

   [TestInitialize]
   public void TestInitialize() { Debug.Print("Running    TestInitialize"); }

   [TestMethod]
   public void TestMethod1() { Debug.Print("Running       TestMethod1....."); }

   [TestMethod]
   public void TestMethod2() { Debug.Print("Running       TestMethod2....."); }

   [TestCleanup]
   public void TestCleanup() { Debug.Print("Running    TestCleanup"); }

   [ClassCleanup]
   public void ClassCleanup() { Debug.Print("Running ClassCleanup"); }
}

これにより、

Running ClassInitialize
Running    TestInitialize
Running       TestMethod1.....
Running    TestCleanup
Running    TestInitialize
Running       TestMethod2.....
Running    TestCleanup
Running ClassCleanup
6

私はいくつかのテストを行い、クラスの静的フィールドを使用して、すべてのメソッドが実行されたように見えることをTestCleanupメソッドに「通知」しました。次に、ClassCleanupを削除して、次のような操作を行うことができます。

private static int runs = 0;

[ClassInitialize]
public static void SetUpBrowser(TestContext context)
{
    pageObjectBase.SetBrowser("chrome");
    pagesManager.GetPageObjectBase();
}

[TestMethod]
public void FindCriticalBug()
{
    runs++;
    bla-bla-bla();
}

[TestMethod]
public void FindCriticalBug2()
{
    runs++;
    ble-ble-ble();
}

[TestCleanup]
public static void CloseBrowser()
{
    if (runs == 2)
    {
        pageObjectBase.Stop();
        pagesManager.GeneralClearing();
    }
}

私は非常にこのソリューションから遠く離れていますが、他に選択肢がなく、提供されたライフサイクルを使用するように設計をリファクタリングできない場合は、オプションになる可能性があります。おそらくここでもっと凝って、実行をカウントし、リフレクションを使用してこのようなものを自動化するテストメソッドの合計量を取得する独自の基本クラスを作成することができます。

4
julealgon

通常の単体テストは「順序なし」です。つまり、任意の順序で実行できます。あなたはおそらく注文されたテストのようなものを探しています(ドミニクに関するあなたのコメントを参照してください)。注文テストは特別な単体テストプロジェクトです。順序付けられたテストを実行すると、テストは構成方法で実行され、テストクラスが終了したら破棄されます。ユニットテストを順番に実行する必要がある場合、テストが互いに干渉しているのはにおいです。以前のテストで不良データが残ったために失敗したり、テスト自体が失敗したりするため、干渉テストは信頼できません。コードの何が本当に悪いのかを知る方法はありません。

1
Peter