首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在.NET中对真实文件进行集成测试?

如何在.NET中对真实文件进行集成测试?
EN

Stack Overflow用户
提问于 2013-11-28 11:46:46
回答 5查看 46.7K关注 0票数 60

我有一些类实现了一些与文件系统和文件相关的逻辑。例如,作为此逻辑的一部分,我正在执行以下任务:

  • 检查某个文件夹是否有特定的结构(例如。它包含具有特定名称等的子文件夹.)
  • 从这些文件夹中加载一些文件并检查它们的结构(例如。这些是一些配置文件,位于某个文件夹中的特定位置)
  • 从配置文件加载用于测试/验证的附加文件(例如。此配置文件包含有关同一文件夹中其他文件的信息,这些文件应该具有其他内部结构等.)

现在,所有这些逻辑都有一些工作流,如果某些地方不正确,就会抛出异常(例如。在特定文件夹位置找不到配置文件)。此外,这个逻辑涉及到托管扩展框架(MEF),因为我正在检查的这些文件中有一些是托管DLL,我正在手动加载到MEF聚合等等.

现在我想用某种方式测试所有这些。我正在考虑在HDD上创建几个物理测试文件夹,这些文件夹涵盖各种测试用例,然后针对它们运行我的代码。例如,我可以创建:

  • 具有正确结构和所有文件有效的文件夹
  • 具有正确结构但配置文件无效的文件夹
  • 具有正确结构的文件夹,但缺少配置文件等。

这是正确的做法吗?但我不确定如何在这种情况下运行我的代码.我当然不想运行整个应用程序并指向它来检查这些模拟文件夹。我是否应该使用一些单元测试框架来编写某种“单元测试”,即针对这些文件系统对象执行我的代码?

一般来说,对于这种测试场景,所有这些都是正确的方法吗?还有其他更好的方法吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-12-16 19:46:26

--首先,,我认为,编写单元测试来测试您的逻辑,而不涉及任何外部资源()是更好的做法。在这里你有两个选择:

  1. 您需要使用抽象层将逻辑与外部依赖关系(如文件系统)隔离开来。您可以在单元测试中轻松地进行存根或模拟(通过手工或借助约束隔离框架(如NSubstitute、FakeItEasy或Moq) )。我更喜欢这个选项,因为在这种情况下,测试会促使您进行更好的设计。
  2. 如果您必须处理遗留代码(仅在本例中),您可以使用一个不受约束的隔离框架(如TypeMock Isolator、JustMock或Microsoft伪),它可以对几乎所有东西(例如,密封和静态类、非虚拟方法)进行存根/模拟。但它们要花钱。唯一的“免费”选项是微软假货,除非你是Visual 2012/2013高级/终极版的快乐所有者。

在单元测试中,您不需要测试外部库(如MEF )的逻辑。

其次,如果您想编写集成测试,那么您需要编写“愉快路径”测试(当一切正常时),以及一些测试边界情况下的逻辑的测试(没有找到文件或目录)。与@Sergey不同,我建议为每个测试用例创建单独的文件夹。主要的优点是:

  1. 你可以给你的文件夹有意义的名字,更清楚地表达你的意图;
  2. 您不需要编写复杂的(即脆弱的)设置/拆卸逻辑。
  3. 即使您稍后决定使用另一个文件夹结构,也可以更容易地更改它,因为您已经有了工作代码和测试(在测试工具下进行重构要容易得多)。

对于单元测试和集成测试,可以使用普通的单元测试框架(比如NUnit或xUnit.NET)。有了这个框架,在构建服务器上连续集成场景中启动测试是非常容易的。

如果您决定编写这两种测试,那么需要将单元测试与集成测试分离开来(您可以为每种测试创建单独的项目)。理由如下:

  1. 单元测试是开发人员的安全网。它们必须在上次代码更改(bug修复、新特性)后提供系统单元预期行为的快速反馈。如果它们经常运行,那么开发人员就可以快速而容易地识别出一段代码,从而破坏了系统。没有人想要运行缓慢的单元测试。
  2. 集成测试通常比单元测试慢。但他们有不同的目的。他们检查单元在实际依赖项下是否按预期工作。
票数 65
EN

Stack Overflow用户

发布于 2013-12-17 07:36:35

您应该使用单元测试测试尽可能多的逻辑,方法是将调用抽象到接口后面的文件系统。使用依赖项注入和测试框架(如FakeItEasy )将允许您测试是否实际使用/调用了您的接口来对文件和文件夹进行操作。

然而,在某个时候,您也必须测试在文件系统上工作的实现,这就是您需要集成测试的地方。

您需要测试的东西似乎是相对独立的,因为您只需要在您自己的文件系统上测试您自己的文件和目录。如果您想要测试一个数据库或具有多个用户的其他一些外部系统,那么事情可能会更复杂。

我不认为您会找到任何“官方规则”,如何最好地进行这种类型的集成测试,但我相信您是在正确的轨道。一些你应该努力实现的想法:

  • 清晰的标准:使每个测试的规则和目的都非常清楚。
  • 自动化::能够快速地重新运行测试,而不需要太多的手工调整。
  • Repeatability:一种您可以“重置”的测试情况,这样您就可以快速地重新运行测试,只需稍作改动。

创建一个可重复的测试场景

在您的情况下,我将设置两个主要文件夹:一个文件夹中的所有内容都应该是正确的(即正确工作),另一个文件夹中的所有规则都被破坏了。

我会创建这些文件夹和它们中的任何文件,然后压缩每个文件夹,并在测试类中编写逻辑,用于解压缩每个文件夹。

这些并不是真正的测试,而是将它们看作设置测试场景的“脚本”,使您能够轻松、快速地删除和重新创建文件夹和文件,即使您的主要集成测试应该在测试期间更改或破坏它们。将它们放到测试类中的原因只是为了使您在测试期间使用的相同接口更容易运行。

测试

创建两组测试类,一组针对每一种情况(正确设置文件夹与规则中断的文件夹)。将这些测试放在对您有意义的文件夹层次结构中(取决于情况的复杂性)。

还不清楚您对单元/集成测试有多熟悉。无论如何,我会推荐NUnit。我也喜欢在Should中使用扩展。你可以从Nuget那里得到这两个:

代码语言:javascript
运行
复制
install-package Nunit
install-package Should

应该包将允许您以如下方式编写测试代码:

代码语言:javascript
运行
复制
someCalculatedIntValue.ShouldEqual(3); 
someFoundBoolValue.ShouldBeTrue();

请注意,有几个测试运行程序可用,以运行您的测试。我个人只拥有任何真正的经验,跑步者内置到Resharper,但我非常满意,我没有问题推荐它。

下面是一个包含两个测试的简单测试类的示例。请注意,在第一个示例中,我们使用Note中的扩展方法检查预期值,而在第二个扩展方法中没有显式测试任何内容。这是因为它被标记为ExpectedException,这意味着如果在运行测试时没有引发指定类型的异常,它将失败。您可以使用它来验证当您的规则之一被破坏时,是否会抛出适当的异常。

代码语言:javascript
运行
复制
[TestFixture] 
public class When_calculating_sums
{                    
    private MyCalculator _calc;
    private int _result;

    [SetUp] // Runs before each test
    public void SetUp() 
    {
        // Create an instance of the class to test:
        _calc = new MyCalculator();

        // Logic to test the result of:
        _result = _calc.Add(1, 1);
    }

    [Test] // First test
    public void Should_return_correct_sum() 
    {
        _result.ShouldEqual(2);
    }

    [Test] // Second test
    [ExpectedException(typeof (DivideByZeroException))]
    public void Should_throw_exception_for_invalid_values() 
    {
        // Divide by 0 should throw a DivideByZeroException:
        var otherResult = _calc.Divide(5, 0);
    }       

    [TearDown] // Runs after each test (seldom needed in practice)
    public void TearDown() 
    {
        _calc.Dispose(); 
    }
}

有了所有这些,您应该能够创建和重新创建测试场景,并以一种简单和可重复的方式对它们运行测试。

编辑:,如注释中指出的,确保异常按需要抛出的Assert.Throws()是另一种选择。就我个人而言,我喜欢标签变体,而带参数,您也可以在那里检查错误消息。另一个示例(假设正在从计算器中抛出自定义错误消息):

代码语言:javascript
运行
复制
[ExpectedException(typeof(DivideByZeroException), 
   ExpectedMessage="Attempted to divide by zero" )]
public void When_attempting_something_silly(){  
    ...
}
票数 8
EN

Stack Overflow用户

发布于 2013-11-28 11:51:26

我会用一个测试文件夹。对于各种测试用例,可以将不同的有效/无效文件作为上下文设置的一部分放入该文件夹。在测试中,只需从文件夹中删除这些文件即可。

例如用光谱流

代码语言:javascript
运行
复制
Given configuration file not exist
When something
Then foo

Given configuration file exists
And some dll not exists
When something
Then bar

将每个上下文设置步骤定义为复制/不将适当的文件复制到文件夹。还可以使用表格来定义应该将哪个文件复制到文件夹中:

代码语言:javascript
运行
复制
Given some scenario
| FileName         |
| a.config         |
| b.invalid.config |
When something
Then foobar
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20265369

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档