診断方法“ TestFixtureSetUp Failed”
質問
TeamCityをCIサーバーとして使用しており、テスト失敗ウィンドウで" TestFixtureSetUp Failed"
が表示されるようになりました。
この問題をデバッグする方法はありますか?テストはワークステーションで正常に実行されます(VS2008のR#テストランナー)。
解決
TestFixtureSetUp(およびTestFixtureTearDown)の実装には、例外が適切に報告されないというちょっとした欠陥があります。私はそれらの最初の実装を書きましたが、それが想定された方法で動作することはありませんでした。当時、NUnitコードの概念は、アクションが単一のテストに直接関連しているという考えと密接に結びついていました。したがって、すべてのレポートはテスト結果に関連していました。大幅な書き直しをせずに、スイートレベルで発生したことを報告するスペースは実際にはありませんでした(羊をエスカレーターに変更するときのリファクタリングではありません)。
その歴史のおかげで、TestFixtureSetUpで実際に何が起こったのかを知るのは困難です。エラーを添付するのに適した場所はありません。 TestFixtureSetUp呼び出しは、テストに直接関連するのではなく、テストを実行する副作用です。
@TrueWillには正しい考えがあります。ログを確認し、必要に応じてテストを変更してさらにログを追加します。 TestFixtureSetup内のtry / catchに配置し、catchブロックに多くのログを記録することができます。背景を追加できると思っただけです(言い換えれば、それは私のせいです)。
他のヒント
最初にビルドログを確認します。
それから明らかでない場合は、テストにConsole.WriteLinesを含めることを試みることができます-私は肯定的ではありませんが、それらはビルドログに書き込まれると思います。または、ファイルにログを記録することもできます(空想を取りたい場合はlog4netを使用します)。
CIサーバーにVisual Studioがインストールされている場合は、そこからビルド/テストを実行してみてください。接続の問題であれば、それで解決する可能性があります。
ただし、ファイルへの相対パスが正しくなくなったり、絶対パスが使用されたりするパスの問題が発生しました。これらはデバッグが難しく、パスをログに記録し、ビルドサーバーに存在するかどうかを確認する必要があります。
今日は、重複したくないセットアップを長時間実行する統合テストを作成するときにこれに遭遇しました。最終的に、すべてのテストフィクスチャセットアップロジックをtry / catchでラップしました。次に、フィクスチャのセットアップ中に障害が発生したかどうかを確認し、より良いログを提供することを唯一の目的とするSetUpメソッドを追加します。
Exception testFixtureSetupException = null;
[TestFixtureSetUp]
public void FixtureSetup()
{
try
{
// DoTestFixtureSetup
}
catch (Exception ex)
{
testFixtureSetupException = ex;
}
}
[SetUp]
// NUnit doesn't support very useful logging of failures from a TestFixtureSetUp method. We'll do the logging here.
public void CheckForTestFixturefailure()
{
if (testFixtureSetupException != null)
{
string msg = string.Format("There was a failure during test fixture setup, resulting in a {1} exception. You should check the state of the storage accounts in Azure before re-running the RenewStorageAccountE2ETests. {0}Exception Message: {3}{0}Stack Trace:{4}",
Environment.NewLine, testFixtureSetupException.GetType(), accountNamePrefix, testFixtureSetupException.Message, testFixtureSetupException.StackTrace);
Assert.Fail(msg);
}
}
Visual NUnitを使用してSpecFlowでテストを実行しているときに、同じエラーが発生していました。ユニットテストエクスプローラー(Resharper提供)から同じことをしようとすると、もう少し役立つメッセージが表示されました。10個を超えるパラメーターを持つバインドメソッドはサポートされていません。 10個を超えるparamsを持つSpecFlowメソッドを使用できないため、テストを削除する必要があることに気付きました。
VS単体テストにすばやく切り替えることで、テストデータベースを正しく作成していないことがわかりました。私のケースでは、失敗した理由に対してより良い応答を返すことができました。私は通常NUnitを使用します。 "クラスXのインスタンスを作成できません。エラー:System.Data.SqlClient.SqlException:ファイルのアクティブ化エラーが発生しました。物理ファイル名「\ DbTest.mdf」が正しくない可能性があります。追加のエラーを診断して修正し、操作を再試行します。 CREATE DATABASEが失敗しました。リストされている一部のファイル名を作成できませんでした。関連するエラーを確認してください。 "
デバッグモードで単体テストを実行します。セットアップで実行時エラーが見つかる場合があります。
Visual StudioでSpecFlowとC#を使用している場合、テストが失敗した後、自動生成された< whatever> .feature.cs
ファイルを確認します。 public partial class< whatever> Feature
行に、ホバーするとNUnitフィクスチャのセットアップが失敗した理由を示すシンボルが表示されます。私の場合、 TestHooks
クラスの BeforeFeature
メソッドの一部は静的ではありませんでした。すべての BeforeTestRun
、 AfterTestRun
、 BeforeFeature
、および AfterFeature
メソッドは静的である必要があります。
この問題が発生したのは、 private const string
を追加するのとほぼ同じ方法で、プライベート読み取り専用 Dictionary
をクラスに追加したことが原因です。
Dictionary
を定数にしようとしましたが、コンパイル時にはできません。これを返すメソッドに Dictionary
を入れることでこれを解決しました。
フィールドの初期化中のエラーが原因でこの症状が発生しました。 [SetUp]
メソッドでフィールドを初期化すると、より良いエラーメッセージが表示されるはずです。
[TestFixture]
internal class CommandParserTest
{
// obscure error message
private CommandParser parser = new CommandParser(...);
...
}
[TestFixture]
internal class CommandParserTest
{
private CommandParser parser;
[SetUp]
public void BeforeTest()
{
// better error message
parser = new CommandParser(...);
}
...
}
今日、これに悩まされました。実際のエラーを取得するために次のことを行いました。
(1)トラブルテストフィクスチャのインスタンスを初期化し、TestFixtureSetUpやSetUpなどのセットアップメソッドを明示的に呼び出し、ターゲットテストメソッドを実行する別のフィクスチャに別のテストを記述します。
(2)上記の新しいコードに例外処理コードを追加し、実際の例外をどこかに記録/出力します。
誰かを助けることができる場合: 例外をキャッチして、TearDownのコンソールに書き込むことができます
次のようなもの:
[SetUpFixture]
public class BaseTest
{
private Exception caughtException = null;
[SetUp]
public void RunBeforeAnyTests()
{
try
{
throw new Exception("On purpose");
}
catch (Exception ex)
{
caughtException = ex;
}
}
[TearDown]
public void RunAfterAnyTests()
{
if (caughtException != null)
{
Console.WriteLine(string.Format("TestFixtureSetUp failed in {0} - {1}", this.GetType(), caughtException.Message));
}
}
}
そして結果は次のようになります:
TestFixtureSetUpはIntegratedTests.Services.BaseTestで失敗しました-意図的に