控制台目标日志记录不适用于 NUnit 测试用例源提供程序中调用的方法
Console target logging does not work for methods called within NUnit test case source provider
当通过 NUnit TestCaseSource.
调用的 class 方法的控制台输出中未显示日志消息时,我花了几个小时调试这个问题
所以我有一个 class,我在其中执行日志记录以进行调试。
public class TestHelper
{
private readonly Logger logger;
public TestHelper()
{
logger = LogManager.GetCurrentClassLogger();
}
public IEnumerable<int> GetTestData()
{
List<int> testData = new();
for (var i = 0; i < 10; i++)
{
logger.Info("This message is ignored when is called from NUnit test data provider {i}", i);
testData.Add(i);
}
return testData;
}
}
我有一个测试夹具:
public class DemoTestFixture
{
private static readonly ClassWithLoggingInside ClassWithLoggingInside = new();
private static readonly TestHelper TestHelper = new();
private readonly Logger logger = LogManager.GetCurrentClassLogger();
[Test]
[TestCaseSource(nameof(GetTestData))]
public void LoggingFromTestDataSourceIsIgnored(int i)
{
Assert.DoesNotThrow(() => ClassWithLoggingInside.Log());
logger.Debug("Message from test fixture {i}", i);
}
[Test]
public void LoggingIsShown()
{
Assert.DoesNotThrow(() => TestHelper.GetTestData());
}
private static IEnumerable<int> GetTestData()
{
IEnumerable<int> testData = TestHelper.GetTestData();
foreach (int i in testData) yield return i;
}
}
并且当从参数化测试调用 TestHelper.GetTestData() 时 - 未显示该方法的控制台输出,但是,消息 被记录 到文件中。
当该方法不作为测试数据提供程序的一部分被调用时 - 消息完美地记录到控制台目标中。
我正在使用最新的 NLog 记录器、.NET5、最新的 NUnit。使用 log4net 记录器尝试了以下 - 结果相同。
测试是 运行 使用 Resharper/dotnet 测试命令。
我怀疑问题出在 static 初始化的某处,但无法理解为什么文件目标日志记录工作正常并且控制台输出存在问题。有什么解释吗?
可以找到演示项目here。
答案相对简单,但可能对您没有帮助。 :-(
您在控制台执行的任何日志记录出现在 NUnit 输出中的原因是 NUnit 在 运行测试.[=10= 时捕获控制台输出 ]
但是,当 NUnit 运行测试时,不会执行您的测试用例源代码,而是在它发现测试时。发现发生在它开始测试执行之前的年龄(在计算机时间)。
我怀疑这会变得更加混乱,因为我们允许您将数据源放在与测试本身相同的 class 中,尽管它也可能位于单独的 class 中。然而,该静态方法的执行 不是 测试的一部分 运行。事实上,只有在那个方法是 运行 之后,NUnit 才知道有多少测试。
如果您需要 NUnit 捕获和显示记录的输出,则必须在测试方法本身或设置或拆卸方法之一中完成。
当通过 NUnit TestCaseSource.
调用的 class 方法的控制台输出中未显示日志消息时,我花了几个小时调试这个问题所以我有一个 class,我在其中执行日志记录以进行调试。
public class TestHelper
{
private readonly Logger logger;
public TestHelper()
{
logger = LogManager.GetCurrentClassLogger();
}
public IEnumerable<int> GetTestData()
{
List<int> testData = new();
for (var i = 0; i < 10; i++)
{
logger.Info("This message is ignored when is called from NUnit test data provider {i}", i);
testData.Add(i);
}
return testData;
}
}
我有一个测试夹具:
public class DemoTestFixture
{
private static readonly ClassWithLoggingInside ClassWithLoggingInside = new();
private static readonly TestHelper TestHelper = new();
private readonly Logger logger = LogManager.GetCurrentClassLogger();
[Test]
[TestCaseSource(nameof(GetTestData))]
public void LoggingFromTestDataSourceIsIgnored(int i)
{
Assert.DoesNotThrow(() => ClassWithLoggingInside.Log());
logger.Debug("Message from test fixture {i}", i);
}
[Test]
public void LoggingIsShown()
{
Assert.DoesNotThrow(() => TestHelper.GetTestData());
}
private static IEnumerable<int> GetTestData()
{
IEnumerable<int> testData = TestHelper.GetTestData();
foreach (int i in testData) yield return i;
}
}
并且当从参数化测试调用 TestHelper.GetTestData() 时 - 未显示该方法的控制台输出,但是,消息 被记录 到文件中。 当该方法不作为测试数据提供程序的一部分被调用时 - 消息完美地记录到控制台目标中。
我正在使用最新的 NLog 记录器、.NET5、最新的 NUnit。使用 log4net 记录器尝试了以下 - 结果相同。 测试是 运行 使用 Resharper/dotnet 测试命令。
我怀疑问题出在 static 初始化的某处,但无法理解为什么文件目标日志记录工作正常并且控制台输出存在问题。有什么解释吗?
可以找到演示项目here。
答案相对简单,但可能对您没有帮助。 :-(
您在控制台执行的任何日志记录出现在 NUnit 输出中的原因是 NUnit 在 运行测试.[=10= 时捕获控制台输出 ]
但是,当 NUnit 运行测试时,不会执行您的测试用例源代码,而是在它发现测试时。发现发生在它开始测试执行之前的年龄(在计算机时间)。 我怀疑这会变得更加混乱,因为我们允许您将数据源放在与测试本身相同的 class 中,尽管它也可能位于单独的 class 中。然而,该静态方法的执行 不是 测试的一部分 运行。事实上,只有在那个方法是 运行 之后,NUnit 才知道有多少测试。 如果您需要 NUnit 捕获和显示记录的输出,则必须在测试方法本身或设置或拆卸方法之一中完成。