Automated testing is an excellent way to make sure application code does what its author intends. The Zero Framework provides unit tests, integration tests, and load tests. Testing frameworks on the .NET platform include xUnit, NUnit, and MSTest, with xUnit being the most widely used. Whichever testing framework you use, tests can be run from the command line or from an IDE.

Unit Tests

A unit test is a test that exercises an individual software component or method, also known as the “unit of work.” Unit tests should only test code within the developer’s control; they do not test infrastructure concerns. Infrastructure concerns include interactions with databases, file systems, and network resources. Unit tests in the Zero Framework use the xUnit framework.

Project naming convention: <ProjectName>.UnitTests.

public class Calculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

public class CalculatorTests
{
    [Fact]
    public void Add_WhenCalled_ReturnsTheSumOfArguments()
    {
        // Arrange
        var calculator = new Calculator();

        // Act
        var result = calculator.Add(1, 2);

        // Assert
        Assert.Equal(3, result);
    }
}

Unit Testing Best Practices

https://learn.microsoft.com/zh-cn/dotnet/core/testing/unit-testing-best-practices

Integration Tests

Integration tests, also known as functional tests, differ from unit tests in that they exercise the ability of two or more software components to work together. These tests run against a broader slice of the system under test, whereas unit tests focus on individual component functions. Integration tests typically also cover infrastructure concerns, such as interactions with databases, file systems, and network resources.

Project naming convention: <ProjectName>.FunctionalTests.

public class Controller: ControllerBase
{
    private readonly IService _service;

    public Controller(IService service)
    {
        _service = service;
    }

    [HttpGet]
    public async Task<IActionResult> Get(int id)
    {
        var result = await _service.Get(id);
        return Ok(result);
    }
}

public class Service: IService
{
    public async Task<Model> Get(int id)
    {
        return await _repository.Get(id);
    }
}

public class ServiceTest: IClassFixture<WebApplicationFactory<Startup>>
{
    private readonly WebApplicationFactory<Startup> _factory;

    public ServiceTest(WebApplicationFactory<Startup> factory)
    {
        _factory = factory;
    }

    [Fact]
    public async Task Get_WhenCalled_ReturnsModel()
    {
        // Arrange
        var client = _factory.CreateClient();
        var response = await client.GetAsync("/api/controller/1");
        response.EnsureSuccessStatusCode();
        var model = await response.Content.ReadAsAsync<Model>();

        // Assert
        Assert.NotNull(model);
    }
}