2012-03-07 12 views
2

NUnitプロジェクトでlog4Netを初期化する最良の方法は何ですか?もちろん、可能な限り多くの初期ログ出力を取得できるようになるとすぐに、initコード(つまり、XmlConfigurator.Configure())を呼び出したいと思います。しかし、私のプロジェクトはNUnitを介して実行されているので、私はそのエントリポイントをほとんど制御していません。NUnitでできるだけ早くlog4Netを初期化してください。

NUnitの文書によると、最初にいくつかのコンストラクタを呼び出し、次に[TestFixtureSetup]とマークされたクラスに[SetUp]という属性を付けたメソッドを呼び出す必要があります。

まず、静的ヘルパークラスを作成しましたが、何度も何度も呼び出すことができます。

public static class LoggingFacility 
    { 
    private static bool _loggerIsUp = false; 

    public static void InitLogger() 
    { 
     if (_loggerIsUp == false) 
     XmlConfigurator.ConfigureAndWatch(f); 

     _loggerIsUp = true; 
    } 
    } 

その後、私が作ったすべての私の[TestFixtureSetup]LoggingFacility.initLogger()を呼び出すよりも他にほとんど何もしない単一のものを継承します。しかし、それはまだ私がランダムに仮定することができる順序で、より早く実行されるすべてのコンストラクタを残します。さらに、私はいくつかのコードを実行することさえできる前に、おそらく静的な初期化を行うでしょう。

実際、私のログで見ることができるように、最初の4秒ほどの実行は完全に記録されていません。

すべてのコンストラクタでInitLogger()を呼び出して、静的な初期化子の使用を禁止する必要がありますか?それは厳しい仕事です!

誰かがこれで魔法を知っていますか?例えば、あなたが[SetUp]が付い[SetUpFixture]属性とメソッドの付いたクラスを使用する必要があり、単一の初期化のポイントについては、

+1

はちょうどあなたがテストの進行状況/結果をログに記録するか、一部のクラスの依存関係としてロガーをインスタンス化するために、テストでlog4netのを使用している目的のために不思議 – sll

+0

@sll?:私は2つのロギング出力を使用します:最初はテスト出力がNUnitより少し冗長であり、もう1つは速い準備ができていることですが、テストアプリケーションのデバッグ用です – PPC

答えて

1

は仕事仲間が仕事をしていません次の回避策、と私を提供:

をロギングを必要とするすべての私のクラスでは、私は単にそれを変更し、次のロガーの初期化

private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

を持っていました私はすべてのクラスでこのコードを持っているので、シングルトンの初期化子

private static readonly ILog Log = LoggingFacility.GetLoggerWithInit(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

/*** ... ***/ 

public static class LoggingFacility 
{ 
    private static bool _loggerIsUp = false; 

    public static ILog GetLoggerWithInit(Type declaringType) 
    { 
    if (_loggerIsUp == false) 
     XmlConfigurator.Configure(_log4NetCfgFile); 
    _loggerIsUp = true; 
    return LogManager.GetLogger(declaringType); 
    } 
} 

に、この静的初期化子があり私のテストクラスをインスタンス化することによって、非常に早く呼び出されるようになりました。

次のステップは、スレッドセーフにすることです:(

4

:今

[SetUpFixture] 
public class TestsInitializer 
{ 
    [SetUp] 
    public void InitializeLogger() 
    { 
     LoggingFacility.InitLogger(); 
    } 
} 

は、すべてのテスト前 を実行します。この方法([SetUp] InitializeLogger)が実行され、同じすべてのテストが実行されると[TearDown]とマークされたものが実行されます。しかしここにキャッチがあります - 任意すべてこのコンテキストでは、キャッチは何ですか?クラスからのテストは、[SetUpFixture]とマークされたクラスと同じ名前空間で宣言されています。例えば

、このように階層構造を想定して:

- Tests 
--- Business 
----- TestsInitializer.cs // SetUpFixture class 
----- FirstBusinessTests.cs 
----- SecondBusinesTests.cs 
--- ComplexLogic 
----- VeryComplexLogicTests.cs 

FirstSecondBusinessTestsTestsInitializerからSetUpを実行します、しかしVeryComplexLogicTestsランダムな順序で実行される場合があります。

あなたが任意の名前空間の外でSetUpFixtureクラスを宣言した場合linked documentationによれば、セットアップとティアダウンは、アセンブリ全体に適用されます:

つだけSetUpFixtureは、指定された名前空間内に作成する必要があります。任意の名前空間の外部にあるSetUpFixtureは、アセンブリ全体に対してSetUpとTearDownを提供します。

+0

名前空間のヒント、しかし、私の問題は、NUnitが[SetUpFixture]について疑問を抱く前にたくさんのコードを実行していることです。コンストラクタと静的初期化子です。このコードもログに記録したいです。 – PPC

+0

@PPC:どのようなコードが実行されますか? * before *?あなたはNUnitの初期化を意味します。コード、テストクラスのコンストラクタなど?私はかなり 'SetUpFixture'はあなたのカスタムコードをNUnitに接続するとすぐになると確信しています。 *たぶん*あなたは設定ファイルであなたのやり方を操作することができますが、正直言って私はこれまで誰もそのようなことをしていることは見たことがありません。 –

+0

はい、私はコンストラクタなどを意味します。私の最初のログエントリは約5秒の稼働時間に始まり、私のコンストラクタの大部分はそこにログインしていません。 – PPC

関連する問題