2

我有许多依赖于 csv 文件的单元测试。如果这个文件明显不存在,他们会抛出异常。

是否有任何 Gallio/MbUnit 方法可以有条件地跳过运行测试?我正在运行 Gallio 3.1 并使用 CsvData 属性

[Test]
[Timeout(1800)]
[CsvData(FilePath = TestDataFolderPath + "TestData.csv", HasHeader = true)]
public static void CalculateShortfallSingleLifeTest()
{
    .
    .
    .

谢谢

4

4 回答 4

7

根据这个问题的答案,如果文件丢失 ,您需要新建TestDecoratorAttribute一个调用。Assert.Inconclusive

Assert.Inconclusive非常适合您的情况,因为您并不是说测试通过或失败;你只是说它不能在当前状态下执行。

于 2010-07-01T11:12:00.293 回答
4

您在这里拥有的不是单元测试。单元测试测试单个代码单元(尽管它可能很大),并且不依赖于外部环境因素,如文件或网络连接。

由于您依赖于此处的文件,因此您拥有的是集成测试。您正在测试您的代码是否安全地与代码控制之外的东西(在本例中为文件系统)集成。

如果这确实是一个集成测试,您应该更改测试,以便测试您真正想要测试的东西。

如果您仍将其视为单元测试,例如您正在尝试测试 CSV 解析,那么我将重构代码,以便您可以模拟/存根/伪造 CSV 文件内容的实际读取。这样,您可以更轻松地向 CSV 解析器提供测试数据,而无需依赖任何外部文件。

例如,您是否考虑过:

  • 防病毒程序包可能无法让您立即访问该文件
  • 一个典型的程序员工具,如 TortoiseSvn,将 shell 覆盖集成到资源管理器中,有时会保留文件太长时间,并且并不总是让程序访问文件(您删除了文件,并尝试用新文件覆盖它) ? 当然,让我先完成删除,但是有一个程序保留了该文件,因此可能需要一段时间...)
  • 该文件可能实际上并不存在(为什么?)
  • 您可能没有对该路径的读取权限
  • 您可能有错误的文件内容(早期调试会话的剩余内容?)

一旦你开始涉及文件系统、网络连接等外部系统,就会有很多事情可能出错,以至于你所拥有的基本上是一个脆弱的测试。

我的建议:弄清楚您要测试的内容(文件系统?CSV 解析器?),并删除与该目标冲突的依赖项。

于 2010-07-01T11:23:08.067 回答
2

一种简单的方法是在测试开始时包含一个 if 条件,如果可以找到 CSV 文件,它将只执行测试中的任何代码。

当然,这有一个很大的缺点,即测试将是绿色的,尽管它们实际上并没有运行并断言任何东西。

不过,我同意 Grzenio 的观点,如果您有严重依赖外部条件的单元测试,它们并没有真正帮助您。在这种情况下,您永远不会真正知道单元测试是成功运行还是被跳过,这与单元测试的实际用途相矛盾。

在我个人看来,我只会编写测试,以便在文件不存在时它们正确失败。如果它们失败,则表明有问题的文件应该在运行单元测试的机器上可用。这有时可能需要进行一些手动调整(将文件发送到有问题的计算机或服务器),但至少您有可靠的单元测试。

于 2010-07-01T11:08:35.607 回答
1

Gallio/MbUnit v3.2 中,抽象ContentAttribute及其具体派生类型(例如[CsvData]有一个新的可选参数,允许在打开或读取文件数据源时发生错误时更改测试的默认结果(参考issue 681 ). 语法如下:

[Test]
[CsvData(..., OutcomeOnFileError = OutcomeOnFileError.Inconclusive)]
public void MyTestMethod()
{
  // ...
}
于 2010-07-02T16:55:00.417 回答