NUnit を使用して log4Net をできるだけ早く初期化する
質問
NUnit プロジェクトで log4Net を初期化する最良の方法は何だろうと考えています。もちろん、初期化コードを呼び出したいと思います(つまり、 XmlConfigurator.Configure()
)できるだけ早く、できるだけ多くの初期のログ出力を取得します。しかし、私のプロジェクトは NUnit を介して実行されるため、そのエントリ ポイントをほとんど制御できません。
NUnit のドキュメントによると、最初にいくつかのコンストラクターを呼び出してから、次のマークが付いたメソッドを呼び出す必要があります。 [SetUp]
でマークされたクラスの属性 [TestFixtureSetup]
.
そこで、まず、何回でも問題なく呼び出すことができる静的ヘルパー クラスを作成しました。
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()
すべてのコンストラクターで静的初期化子の使用を禁止しますか?それは大変な仕事だよ!
誰かこれを使った魔法のトリックを知っていますか?
解決 2
作品仲間は、次の回避策を説明した、それはジョブを行います:
ロギングを必要とするすべてのクラスでは、次のロガーの初期化がありました
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);
}
}
.
私はすべてのクラスにこのコードを持っているので、この静的イニシャライザは私のテストクラスをインスタンス化するNUnit Wileによって非常に早く呼ばれなければなりません。
次のステップは、そのスレッドを安全にすることです。(
他のヒント
単一の初期化ポイントの場合は、 でマークされたクラスを使用する必要があります。 [SetUpFixture]
でマークされた属性とメソッド [SetUp]
, 、 例えば:
[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
First
そして SecondBusinessTests
走ります 後 SetUp
から TestsInitializer
, 、 しかし VeryComplexLogicTests
ランダムな順序で実行される可能性があります。
によると リンクされたドキュメント, 、宣言すると SetUpFixture
名前空間の外側にあるクラスの場合、セットアップと破棄はアセンブリ全体に適用されます。
指定された名前空間には SetUpFixture を 1 つだけ作成する必要があります。名前空間の外側にある SetUpFixture は、アセンブリ全体に SetUp と TearDown を提供します。