多次记录(或运行)单元测试

时间:2010-06-15 05:24:22

标签: c# nunit resharper log4net

我有这个简单的测试:

protected readonly ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().ReflectedType);
private static int count = 0;
[Test]
public void TestConfiguredSuccessfully()
{
    logger.Debug("in test method" + count++);
}

log4net设置如下:

[TestFixtureSetUp]
public void SetUp()
{
    log4net.Config.BasicConfigurator.Configure();
}

问题是,如果我在nUnit中运行一次测试,我得到输出(如预期的那样):

1742 [TestRunnerThread] DEBUG Tests.TestSomthing (null) - in test method0

但如果我再次在nUnit.exe中按RUN(或更多),我会得到以下内容:

1742 [TestRunnerThread] DEBUG Tests.TestSomthing (null) - in test method1
1742 [TestRunnerThread] DEBUG Tests.TestSomthing (null) - in test method1

等等(如果我运行5次,我会得到5条重复的线条)。现在,如果我从reSharper单独运行相同的测试,输出就可以了,不会重复。但是,如果我在同一个类中的另外两个测试中运行此测试,则输出重复三次。

我完全糊涂了。这到底是怎么回事?

1 个答案:

答案 0 :(得分:7)

每次测试运行时都会重新初始化Log4net,并且每次都会添加appender。我怀疑ReSharper没有表现出这种行为,因为它每次都会启动一个新进程(ReSharper测试运行器),而NUnit GUI却没有。

我过去曾经有各种各样的风格,但是很长一段时间以来我使用了“SetupFixture”来初始化log4net(以及其他内容)。

[SetUpFixture]
public class UnitTestSuiteSetupTeardown
{
    [SetUp]
    public void Setup()
    {
        log4net.Config.BasicConfigurator.Configure();
    }

    [TearDown]
    public void Teardown()
    {
        //Teardown stuff...
    }
}

为每个测试程序集添加其中一个,并确保该类没有名称空间。对于所有测试,即组件中的所有测试,它将运行一次。我个人在解决方案级别拥有其中一个,然后将其添加为每个测试项目的链接。

<强>更新

上面的示例遵循问题并设置基本配置。在我的实际SetUpFixture中,我从log4net配置文件初始化log4net(我再次在解决方案级别存储,然后添加为所有测试项目的链接),例如。

[SetUpFixture]
public class UnitTestSuiteSetupTeardown
{
    [SetUp]
    public void Setup()
    {
        LogFactory.Configure();
    }

    [TearDown]
    public void Teardown()
    {
        //Teardown stuff...
    }
}

示例LogFactory类型。

public static class LogFactory
{
    public const string DefaultConfigFileName = "log4net.config";

    static ILog GetLogger(Type callingType)
    {
        return new Log4NetLogger(LogManager.GetLogger(callingType));
    }

    public static void Configure()
    {
        Type type = typeof(LogFactory);
        FileInfo assemblyDirectory = AssemblyInfo.GetCodeBaseDirectory(type);
        FileInfo configFile = new FileInfo(Path.Combine(assemblyDirectory.FullName,
            DefaultConfigFileName));
        XmlConfigurator.ConfigureAndWatch(configFile);
        log4net.ILog log = LogManager.GetLogger(type);
        log.ToString();
    }
}
相关问题