1

プレトピック:
この問題については、Specflowの安定性のトピックで前述しましたが、新しいトピックで再度取り上げたいと思います。これは、前のトピックのタイトルが誤解を招きやすく(Specflowの安定性は問題ではないと思います)、問題にさらに正確に対処できるためです。

問題:
50程度のテストの完全なテストセットを実行すると、ほとんどの場合、ランダムに1つまたは2つのテストが失敗します(テストが失敗しない場合もあります)。完全なテストセットをより小さなテストセットにスライスし(たとえば、個別のユーザーストーリーごとに7つまたは8つのテストのテストセット)、これらのセットを個別に実行すると、すべてのテストに合格します。Specflowの安定性で述べたLukeMcGregorのように、テストはデータを共有しているため失敗しているようです。しかし、なぜこれは完全なセットが実行されたときにのみ発生し、小さいセットを使用しているときは発生しないのですか?

背景:
50程度のSpecflowテストのセットを実行しようとしています。これらのテストはすべて、WebサイトのUIをテストするように設計されています。テストは、ランナーツールとしてMsTestを使用して、VisualStudio2010で実行されます。使用しているブラウザはFireFoxです。現在、テストで実行される手順は次のとおりです。

  • 各シナリオの前に、新しいIISプロセスと新しいBrowserSessionが開始されます。
  • シナリオが実行されます。
  • 各シナリオの後、IISプロセスとBrowserSessionは終了します。

個々のテストシナリオの前に新しいIISプロセスと新しいBrowserSessionを開始する理由は、Lukeが述べた「データ共有」のリスクを最小限に抑えるためです。残念ながら役に立たなかった。

私は今、問題が何であるかについて少し迷っています。私はここで明白な(またはおそらくそれほど明白ではない)何かを見逃していますか?

前もって感謝します!

4

2 に答える 2

3

テストの失敗例をいくつか挙げていただけると助かります。

ページ上にいくつかの要素が見つからないため、テストは失敗しますか? その場合、WebDriver を使用している場合は、暗黙の待機を有効にすることをお勧めします。これにより、テスト スイートの実行が遅くなりますが、安定性が向上します。

WebDriver driver = new FirefoxDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));

ブラウザーを介したテストは、要素がページに表示されるのを待つようにテストが設計されていない場合、特にランダムな失敗を引き起こす可能性があります。ajax 呼び出しでも、事態は非常に複雑になる可能性があります。

余談ですが、新しいブラウザを実行するのは避け、各テストの前に IIS を起動することをお勧めします。その理由は、テスト スイートの実行に非常に長い時間がかかるためです。代わりに、次のことをお勧めします。 - テスト スイートの最初に IIS を 1 回だけ実行します。(タグ [BeforeTestRun] を使用できます) - テスト スイートの開始時に 1 回だけブラウザー セッションを開きます。([BeforeTestRun]) - 各テストの最後に、ユーザーをログアウトして、すべての Cookie を消去します。([アフターシナリオ])

これにより、テストスイートが大幅に高速化されます。

共有状態については、属性 [BeforeScenario] を使用して、テストで使用するすべてのデータをリセットすることをお勧めします。たとえば、テストでデータベースにデータをセットアップする場合、各テストを実行する前にデータベースをクリーンアップします。

最後に、テストが自己完結型であることを確認してください。他のテストで使用されるデータを使用しないでください。テストは常にクリーンな初期状態から実行し、必要なデータを作成する必要があります。

于 2012-10-05T20:25:06.440 に答える
1

静的クラスは 1 つの可能性です。
失敗したテストをよく見てください。パターンが見えますか?たまに失敗するテストもあれば、一度も失敗しないテストもあるでしょうか?失敗したものを詳しく見てください。


複数の単体テストで使用される静的クラスは、データ共有または状態共有の古典的なケースです。

たとえば、次のクラスを考えてみましょう。

public static class TimeProvider
{
    static TimeProvider()
    {
        CurrentTimeProvider = () => DateTime.Now;
    }

    public static Func<DateTime> CurrentTimeProvider { get; set; }

    public static DateTime Now { get { return CurrentTimeProvider(); } }
}

ここで、ある単体テストで、現在の時刻が関連するものをテストしたいとします。

public void AddItemSetsOrderDateAsCurrentTime()
{
    // Arrange
    var currentTime = new DateTime(2011, 1, 1, 12, 15);
    TimeProvider.CurrentTimeProvider = () => currentTime;

    // Act
    //...
}

を使用する以下のすべての単体テストTimeProvider.Nowは、現在の時刻の代わりに 2011-01-01 12:15 を取得します。これは、あるテストが別のテストにどのように影響するかの一例です。

于 2012-10-04T14:06:30.883 に答える