65.9K
CodeProject 正在变化。 阅读更多。
Home

借助 xUnit 减少生产问题

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.53/5 (4投票s)

2020 年 5 月 24 日

CPOL

2分钟阅读

viewsIcon

5770

通过正确使用 xUnit,可以改进日志记录,并轻松解决甚至预防生产问题。

引言

生产问题是一个众所周知的问题。大多数情况下,你不知道问题的原因,因此首先要做的就是阅读日志。阅读日志后,开发团队可能会提出以下问题:

  1. 为什么没有记录我们期望记录的对象?
  2. 为什么找不到描述问题的警告或错误消息?
  3. 为什么找不到应该发生的异常?
  4. 为什么我们的测试没有失败,因为显然存在问题?

从 TDD 的角度来看,需要进行两项改进:

  1. 自动化测试需要更逼真,以便重现实际问题。
  2. 测试需要在缺少日志记录时失败。

本文档将解释如何做到这一点。

背景

如果你之前使用过 xUnit,这将非常有帮助,因为测试示例基于此。此外,一些 .NET Core 经验也有帮助,因为我们在这里使用的技术就是 .NET Core。

使用代码

为了演示目的,我们使用一个非常简单的控制器方法。传入的 value 包含 FirstNameMiddleName LastName ,以返回完整的姓名作为 ActionResult

[HttpPut]
public ActionResult<string> Put([FromBody] Name value)
{
    _logger.LogWarning("Warning Logged");
    _logger.LogInformation("This is the input {name}", value);
    _logger.LogError(new InvalidDataException("Some exception message"),"Some Exception");

    return Ok($"{value.FirstName} {value.MiddleName} {value.LastName}");
}

对于此方法,我们需要一个可以检测已记录内容(InvalidDataException、一些日志消息和类型为 Name 的数据对象)的测试。此外,测试需要逼真,这意味着它知道并使用设置依赖项的 Startup 类。在常规单元测试中,情况并非如此,但在 .NET Core 的集成测试中,情况就是如此,从此处显示的代码可以看出:

[Fact]
public async Task NoMiddleNamePutTest()
{
    await using (var fixture = new Fixture<Startup>())
    {
        var controller = fixture.Create<LogicController>();
        var response = controller.Put(new Name()
        {
            FirstName = "F",
            LastName = "L"
        });
        Assert.Equal(200, ((ObjectResult)response.Result).StatusCode);
        Assert.Single(fixture.LogSource.GetWarnings());
        var dataLogged = fixture.LogSource.GetLoggedObjects<Name>().ToList();
        Assert.Single(dataLogged);
        Assert.Equal("F", dataLogged.Single().Value.FirstName);
        Assert.Contains(fixture.LogSource.GetLogLines(), a => a == "Warning Logged");
        Assert.Contains(fixture.LogSource.GetLogLines(), a => a.Contains("This is the input"));
        Assert.Single(fixture.LogSource.GetExceptions().OfType<InvalidDataException>());
    }
}

Fixture<> 类来自 一个名为 IntegrationFixture 的公开可用的 NuGet 包。 它使用 WebApplicationFactory<> 类(在 此处 解释)以减少开发人员需要编写的样板代码。在 Startup 类中设置的真实类依赖项(而不是模拟对象)用于使测试逼真。LogSource 属性使开发人员能够调用返回我们关心的的数据的方法(例如,记录的数据对象、记录的行和记录的异常)。由于使用了真实的依赖项,因此生产问题的可能性降低,因此这些问题很可能在测试中得到覆盖。此外,如果出现生产问题,将提供足够的日志记录来帮助你解决问题,因为 xUnit 测试将简单地失败并防止部署,如果没有足够的日志记录。代码可在 GitHub 上找到。

关注点

在编写代码时,我越来越意识到自动化测试的重要性。作为开发人员,我们需要为 CI 目的编写集成测试,而不仅仅是单元测试。此外,我们不应只关注所需的功能,还应关注日志记录。拥有良好的日志记录对于快速解决生产问题至关重要,并且借助 提到的 NuGet 包,我们可以轻松检测已记录的内容。

历史

  • 2020 年 5 月 24 日:初始版本
© . All rights reserved.