如何编写基于验收的测试(从代码的角度来看)

本文关键字:代码 测试 验收 何编写 于验收 | 更新日期: 2023-09-27 17:57:59

我一直在研究基于验收的测试,它们看起来很不错,因为它们更自然地适合基于特性的开发。

问题是我不知道如何把它们放在代码中。我想尽量避免引入另一个框架来处理这个问题,所以我只是在寻找一种简单的方法来启动和运行这些测试。

我对代码结构所需的任何更改持开放态度。我也在使用规范来建立复杂的验收标准。

我尝试做的事情的例子:

public class When_a_get_request_is_created
{
    private readonly IHttpRequest _request;
    public When_a_get_request_is_created()
    {
        _request = new HttpRequest();
    }
    // How to call this?
    public void Given_the_method_assigned_is_get()
    {
        _request = _request.AsGet();
    }
    // What about this?
    public void Given_the_method_assigned_is_not_get()
    {
        _request = _request.AsPost();
    }
    // It would be great to test different assumptions.
    public void Assuming_default_headers_have_been_added()
    {
        _request = _request.WithDefaultHeaders();
    }
    [Fact]
    public void It_Should_Satisfy_RequestIsGetSpec()
    {
        Assert.True(new RequestUsesGetMethodSpec().IsSatisfiedBy(_request));
    }
}

我在这里可能完全偏离了目标,但本质上我希望能够在不同的假设和给定条件下运行测试。我不介意我是否必须制作更多的类或小的重复,只要我能把某人指向测试来验证给定的标准。

如何编写基于验收的测试(从代码的角度来看)

我强烈建议使用像SpecFlow甚至MSpec这样的ATDD框架来创建这种性质的测试。实现SpecFlow就是使用特定领域的语言编写规范,如果合适的话,与领域专家合作,然后通过代码满足功能中定义的场景步骤。在不了解更多确切需求的情况下,很难补充代码方面的内容,但一个示例功能可能看起来像这样:

Feature: HTTP Requests
    In order to validate that HTTP requests use the correct methods
    As a client application
    I want specific requests to use specific methods
Scenario Outline: Making HTTP Requests
    Given I am making a request
    When the method assigned is <Method>
    And the <Header> header is sent
    Then it should satisfy the requirement for a <Method> request
Examples:
| Method | Header   |
| Get    | Header 1 |
| Get    | Header 2 |
| Get    | Header 3 |
| Post   | Header 1 |

然后,在绑定到特性的步骤中,您可以编写满足规范步骤的代码。这里有一个例子:

[Binding]
public class HttpRequestSteps
{
    [When(@"the method assigned is (.*)")]
    public void WhenTheMethodAssignedIs(string method)
    {
        // not sure what this should be returning, but you can store it in ScenarioContext and retrieve it in a later step binding by casting back based on key
        // e.g. var request = (HttpRequest)ScenarioContext.Current["Request"]
        ScenarioContent.Current["Request"] = _request.AsGet();
    }
}