【问题标题】:Specflow test will never failSpecflow 测试永远不会失败
【发布时间】:2021-08-08 12:56:47
【问题描述】:

我有一个Specflow 集成测试,它导致数据被添加到数据库中。这可能会很快完成,也可能需要一些时间,具体取决于消息积压的大小。我检查数据到数据库的步骤如下:

[Then(@"the enriched messages are written to the DB")]
public void ThenTheEnrichedMessagesAreThenWrittenToTheDB()
{
    try
    {
        var DbConnectionOptions = new DbConnectionOptions();
        _configuration.GetSection("ConnectionStrings").Bind(DbConnectionOptions);
        SqlConnection myConnection = new SqlConnection(DbConnectionOptions.HistoryDb);

        myConnection.Open();
        SqlCommand myCommand = new SqlCommand("select * FROM dbo.Trades WHERE TradeId = 148874",
                                            myConnection);

        int timeout = 1000;
        for (int i = 0; i < 13; i++)
        {
            using (var reader = myCommand.ExecuteReader())
            {
                if (reader.Read())
                {
                    reader[reader.GetOrdinal("DealId")].Should().Be("148874");
                }
            }
            Thread.Sleep(timeout);
            timeout = timeout * 2;
        }
    }
    catch (Exception e)
    {
        _logger.LogInformation("SQL Exception: " + e.ToString());
    

我想在其中轮询数据库以进行测试交易。每次轮询超时都应该加倍。

我的问题是这个测试永远不会失败。如果测试成功,则 if 中的流畅断言将通过,但如果不成功,则永远不会达到该条件而失败。如果我把它移到别处,即使交易被搁置,测试也可能会失败,如果我把它留在原处并且​​交易永远不会到达数据库,它将通过,因为断言永远不会被执行。我该如何解决这个问题?

【问题讨论】:

  • 作为一般规则,测试永远不应该捕获异常(除非它实际上是在测试异常)。未处理的异常将导致测试失败;处理它不会。

标签: c# .net testing automated-tests specflow


【解决方案1】:

从步骤定义中删除 try-catch 块。未处理的异常将使测试失败。测试结果会显示异常消息和堆栈跟踪,因此无需记录。不过,您将需要额外的代码更改。随着每次迭代的等待时间加倍,在更糟糕的情况下,您的测试最终失败的时间应该不超过 27 秒(加上查询时间)。

[Then(@"the enriched messages are written to the DB")]
public void ThenTheEnrichedMessagesAreThenWrittenToTheDB()
{
    var DbConnectionOptions = new DbConnectionOptions();
    _configuration.GetSection("ConnectionStrings").Bind(DbConnectionOptions);
    SqlConnection myConnection = new SqlConnection(DbConnectionOptions.HistoryDb);

    myConnection.Open();
    SqlCommand myCommand = new SqlCommand("select * FROM dbo.Trades WHERE TradeId = 148874",
                                        myConnection);

    int timeout = 1000;
    int maxAttempts = 13;
    int currentAttempt = 0;

    for (currentAttempt; currentAttempt < maxAttempts; currentAttempt++)
    {
        try
        {
            using (var reader = myCommand.ExecuteReader())
            {
                if (reader.Read())
                {
                    reader[reader.GetOrdinal("DealId")].Should().Be("148874");
                    break; // Assertion passed, so do not bother checking again.
                }
            }
            Thread.Sleep(timeout);
            timeout = timeout * 2;
        }
        catch (Exception ex)
        {
            _logger.LogInformation("Exception thrown when attempting to get DealId: " + ex);
        }
    }

    if (currentAttempt == maxAttempts)
    {
        throw new TimeoutException("Timed out checking TradeId 148874");
    }
}

try-catch 块应该只是包装查询数据库的尝试。如果抛出异常,您仍然可以记录异常以进行调试。只有在超过最大尝试次数后,您才应该抛出 TimeoutException,这将导致测试失败。 这个异常应该不被处理。最后一个主要的变化是如果你对DealId的断言通过了,就跳出循环。如果您已经断言 DealId 是正确的,那么等待超时时间是没有意义的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 2020-06-03
    • 1970-01-01
    相关资源
    最近更新 更多