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

发布于 2024-09-06 07:49:34 字数 920 浏览 5 评论 0原文

我有这个简单的测试:

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 单独运行相同的测试,输出就很好并且不会重复。但是,如果我与同一类中的其他 2 个测试一起运行此测试,则输出会重复 3 次。

我完全困惑了。这到底是怎么回事?

I have this simple test:

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 is set up like this:

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

The problem is, that if I run this test in nUnit once, I get the output (as expected):

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

But if I press RUN in nUnit.exe again (or more) I get the following:

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

And so on (if I run it 5 times, I'll get 5 repeating lines). Now, if I run the same test alone from reSharper the output is fine and does not repeat. However, if I run this test along side 2 other tests in the same class, the output is repeated three times.

I am totally confused. What the hell is going on here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

镜花水月 2024-09-13 07:49:34

Log4net 在每次测试运行时都会重新初始化,并且每次都会添加附加程序。我怀疑 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();
    }
}

Log4net is being re-initialized on each test run, and appender(s) added each time. I suspect that ReSharper does not exhibit the behaviour as it starts a new process each time (the ReSharper test runner) whereas the NUnit GUI does not.

I have had various flavours of this in the past, but for quite a while now I have used a "SetupFixture" to initialize log4net (amongst other things).

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

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

Add one of these per test assembly, and ensure the class has no namespace. It will be run once for all of your tests i.e. all tests in the assembly. I personally have one of these at solution level and then add it in as a link to each test project.

Update

The example above follows the question and sets up basic configuration. In my actual SetUpFixture I initialize log4net from a log4net configuration file (which I again store at solution level and then add as a link to all test projects), e.g.

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

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

And a sample LogFactory type class.

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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文