2012-01-26 7 views
3

デバッグビルドで渡すが、正しいリリースビルドで失敗する単体テストのコードがあります。ただし、JetBrains dotCoverを使用して実行すると、同じテストがデバッグモードとリリースモードの両方で実行されます。dotCoverを使用したときのテスト結果が一致しません。

バックグラウンドのビットを与えるために、違反テストコードがあります。これは、リリースビルドで失敗した理由を説明するためのものです。基本的に、コード最適化によるスタック情報の減少によるものです。

using System.Diagnostics; 
using NUnit.Framework; 

namespace DotCoverTest 
{ 
    [TestFixture] 
    public class TestLogger 
    { 
     [Test] 
     public void GetCurrentClassLoggerReturnsLoggerWithOwningTypeName() 
     { 
      Assert.AreEqual(Logger.GetCurrentClassLogger(), GetType().Name); 
     } 
    } 

    public class Logger 
    { 
     public static string GetCurrentClassLogger() 
     { 
      return new StackFrame(1, false).GetMethod().DeclaringType.Name; 
     } 
    } 
} 

編集:私はカバレッジ・ツールの有無にかかわらず同一の試験結果を得るように私は私のビルドを設定することができますどのように 任意のアイデア?

注:この質問は、最初はTeamCityの問題であると信じられていましたが、そうではありません。

+0

TeamCityのリリースビルドは、実際にリリースDLLを使用していて、デバッグビルドではありませんか? – Pedro

+0

単体テストを実行しているビルドスクリプトを見ておくと便利です –

+0

返信ありがとうございました - 元の投稿の問題に関する詳細を追加しました – MickG

答えて

2

ここでの主な問題はTail call optimizationです。コンパイラがパフォーマンスを向上させるためにスタックフレームを折りたたむ場所です。これはリリースモードでのみ発生します。

dotCover(他の.NETのプロファイラなど)妥協の結果を防止し、CLRの最適化の一部を無効に - 彼らは実行しない場合には、メソッドの実行をカウントするのは難しいだろう...

私はあなたを伝えることはできませんNCoverが最適化を克服できない場合や、別の方法でこれを解決する場合、私はdotCoverについてはかなり確信しています。

+0

問題の行が変更されていないようにGetCurrentClassLogger()を変更しました最後にはまだ期待どおりに動作しません。あなたが残りの部分について正しいように見える。 あなたはそれを回避する方法を知っていますか? – MickG

+0

フレーム全体(GetCurrentClassLogger)がその親フレームを使用しているので、メソッドの行順を変更することは役に立ちません。なぜあなたはそれを回避したいのかわかりません...テールコールの最適化を無効にするか(〜しないでください)、フレーム数に依存するコードを使用しないでください。スタックに依存する必要がある場合は、テストでそのことを認識させるようにします(もちろん、実際のコードなしでは正確ではありません)。 – seldary

+0

私は問題を説明するための例としてこのコードを使用していましたが、とにかくこれを削除しなければなりませんでした。おそらく、StackFrameだけでなく、最適化後に同じ効果をもたらす可能性のあるものが他にもあるでしょうか? Visual StudioとdotCoverで同じビルド設定を共有する方法を見つけることができれば、同じコードが今後レーダーの下でスリップしないことが確実にわかります。あなたの助けをありがとう – MickG

関連する問題