使用 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 必须很早就调用此静态初始化程序。
下一步是确保该线程安全:(
其他提示
对于单个初始化点,您应该使用标记为的类 [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。任何命名空间之外的 SetUpFixture 为整个程序集提供 SetUp 和 TearDown。