尝试为包含 VS 中的时间戳的数据库构建功能测试

Trying to build feature test for database containing timestamps in VS

我是我们组织的测试和开发套件的新手。这一切都在 Visual Studio 中,自动化测试是使用 SpecFlow(也许还有 NuGet v2?)进行的。

我们有 ETL 过程(简而言之)从 Excel 文件中获取输入,写入数据库并生成各种输出文件。我正在查看的测试(.feature 文件)的具体部分采用以下形式:

Then the CSV file 'filename.csv' in the Outputs directory contains the following content
| Period  | Org Ref | Org Name  | Question    | Answer  |
| APR2020 | XXX     | XXX       | Q1          | No      |

我们已收到在某些输出中包含时间戳的请求,但由于时间戳的本质,每次 运行 时都会发生变化,我们无法让它通过这些功能测试,因此无法升级为 Live。

在不深入研究底层 C# 的情况下(我们组织在这方面的专业知识很少),是否可以允许某些字段接受 any 数据,或者可能包括正则表达式模式检查,而不是完全匹配。

非常感谢任何帮助。如果这是重复的,我深表歉意,因为我对我正在使用的工具缺乏了解,我花了整整几天的时间进行毫无结果的搜索,而且大多数结果都假设有相当多的先验知识。

干杯!

这是个有趣的问题我前阵子也运行研究过。我没有处理 Excel 文件,而是我有一个 When 步骤“现在”做了一些事情,还有一个 Then 步骤断言它“现在”发生了。

我不得不选择“正确 now-ish”——现在之前不少于 3 秒,现在之后不超过 3 秒。

这应该为您的测试提供足够的填充来执行操作,然后断言。如果不是,只需调整您的 window 时间。

首先,对您的步骤进行修改:

Then the CSV file 'filename.csv' in the Outputs directory contains the following content
    | Timestamp | Period  | Org Ref | Org Name  | Question    | Answer  |
    | Now       | APR2020 | XXX     | XXX       | Q1          | No      |

“时间戳”列在 C# 中只是一个 string 值。然后您可以将该字符串值转换为当前日期和时间。您需要一些实用方法来进行转换和比较:

public static class DateTimeUtils
{
    /// <summary>
    /// Converts this string to DateTime, taking in to account relative terms like "now" and "yesterday".
    /// </summary>
    public static DateTime ConvertToRelativeDateTime(this string text)
    {
        switch (text.ToLower())
        {
            case "now":
                return DateTime.UtcNow; // Or DateTime.Now for a time zone specific "now"
            case "tomorrow":
                return DateTime.Today.AddDays(1);
            case "yesterday":
                return DateTime.Today.AddDays(-1);
            default:
                return DateTime.Parse(text);
        }
    }

    /// <summary>
    /// Returns whether or not this DateTime is "right now," give or take a few seconds either side of "now".
    /// </summary>
    public static bool IsNowIsh(this DateTime date, int numberOfSecondsToGiveOrTake = 3)
    {
        var now = DateTime.Now;
        var min = now.AddSeconds(numberOfSecondsToGiveOrTake * -1);
        var max = now.AddSeconds(numberOfSecondsToGiveOrTake);

        return date >= min && date <= max;
    }
}

最后是您的步骤定义:

[Then(@"Then the CSV file '(.*)' in the Outputs directory contains the following content")]
public void ThenTheCSVFileInTheOutputsDirectoryContainsTheFollowingContent(string filename, Table table)
{
    // ...

    foreach (var row in table.Rows)
    {
        var timestamp = row["Timestamp"].ConvertToRelativeDateTime();
        var isNow = timestamp.IsNowIsh(); // Returns true if timestamp is within 3 seconds before or 3 seconds after right now

        // ...
    }
}

如果你的测试因为 timestamp 超过 3 秒而失败,那么用 int 参数调用它以在几秒内调整填充:

var isNow = timestamp.IsNowIsh(5); // Returns true if timestamp is no less than 5 seconds before now and no more than 5 seconds after now

诀窍是获得足够的精度,以便您的测试始终如一地通过,同时让您确信它验证时间戳“足够好”。你永远无法做到完美。