我有一些类实现了一些与文件系统和文件相关的逻辑。例如,作为此逻辑的一部分,我正在执行以下任务:
现在,所有这些逻辑都有一些工作流,如果某些地方不正确,就会抛出异常(例如。在特定文件夹位置找不到配置文件)。此外,这个逻辑涉及到托管扩展框架(MEF),因为我正在检查的这些文件中有一些是托管DLL,我正在手动加载到MEF聚合等等.
现在我想用某种方式测试所有这些。我正在考虑在HDD上创建几个物理测试文件夹,这些文件夹涵盖各种测试用例,然后针对它们运行我的代码。例如,我可以创建:
这是正确的做法吗?但我不确定如何在这种情况下运行我的代码.我当然不想运行整个应用程序并指向它来检查这些模拟文件夹。我是否应该使用一些单元测试框架来编写某种“单元测试”,即针对这些文件系统对象执行我的代码?
一般来说,对于这种测试场景,所有这些都是正确的方法吗?还有其他更好的方法吗?
发布于 2013-12-16 19:46:26
--首先,,我认为,编写单元测试来测试您的逻辑,而不涉及任何外部资源()是更好的做法。在这里你有两个选择:
在单元测试中,您不需要测试外部库(如MEF )的逻辑。
其次,如果您想编写集成测试,那么您需要编写“愉快路径”测试(当一切正常时),以及一些测试边界情况下的逻辑的测试(没有找到文件或目录)。与@Sergey不同,我建议为每个测试用例创建单独的文件夹。主要的优点是:
对于单元测试和集成测试,可以使用普通的单元测试框架(比如NUnit或xUnit.NET)。有了这个框架,在构建服务器上连续集成场景中启动测试是非常容易的。
如果您决定编写这两种测试,那么需要将单元测试与集成测试分离开来(您可以为每种测试创建单独的项目)。理由如下:
发布于 2013-12-17 07:36:35
您应该使用单元测试测试尽可能多的逻辑,方法是将调用抽象到接口后面的文件系统。使用依赖项注入和测试框架(如FakeItEasy )将允许您测试是否实际使用/调用了您的接口来对文件和文件夹进行操作。
然而,在某个时候,您也必须测试在文件系统上工作的实现,这就是您需要集成测试的地方。
您需要测试的东西似乎是相对独立的,因为您只需要在您自己的文件系统上测试您自己的文件和目录。如果您想要测试一个数据库或具有多个用户的其他一些外部系统,那么事情可能会更复杂。
我不认为您会找到任何“官方规则”,如何最好地进行这种类型的集成测试,但我相信您是在正确的轨道。一些你应该努力实现的想法:
创建一个可重复的测试场景
在您的情况下,我将设置两个主要文件夹:一个文件夹中的所有内容都应该是正确的(即正确工作),另一个文件夹中的所有规则都被破坏了。
我会创建这些文件夹和它们中的任何文件,然后压缩每个文件夹,并在测试类中编写逻辑,用于解压缩每个文件夹。
这些并不是真正的测试,而是将它们看作设置测试场景的“脚本”,使您能够轻松、快速地删除和重新创建文件夹和文件,即使您的主要集成测试应该在测试期间更改或破坏它们。将它们放到测试类中的原因只是为了使您在测试期间使用的相同接口更容易运行。
测试
创建两组测试类,一组针对每一种情况(正确设置文件夹与规则中断的文件夹)。将这些测试放在对您有意义的文件夹层次结构中(取决于情况的复杂性)。
还不清楚您对单元/集成测试有多熟悉。无论如何,我会推荐NUnit。我也喜欢在Should
中使用扩展。你可以从Nuget那里得到这两个:
install-package Nunit
install-package Should
应该包将允许您以如下方式编写测试代码:
someCalculatedIntValue.ShouldEqual(3);
someFoundBoolValue.ShouldBeTrue();
请注意,有几个测试运行程序可用,以运行您的测试。我个人只拥有任何真正的经验,跑步者内置到Resharper,但我非常满意,我没有问题推荐它。
下面是一个包含两个测试的简单测试类的示例。请注意,在第一个示例中,我们使用Note中的扩展方法检查预期值,而在第二个扩展方法中没有显式测试任何内容。这是因为它被标记为ExpectedException,这意味着如果在运行测试时没有引发指定类型的异常,它将失败。您可以使用它来验证当您的规则之一被破坏时,是否会抛出适当的异常。
[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()是另一种选择。就我个人而言,我喜欢标签变体,而带参数,您也可以在那里检查错误消息。另一个示例(假设正在从计算器中抛出自定义错误消息):
[ExpectedException(typeof(DivideByZeroException),
ExpectedMessage="Attempted to divide by zero" )]
public void When_attempting_something_silly(){
...
}
发布于 2013-11-28 11:51:26
我会用一个测试文件夹。对于各种测试用例,可以将不同的有效/无效文件作为上下文设置的一部分放入该文件夹。在测试中,只需从文件夹中删除这些文件即可。
例如用光谱流
Given configuration file not exist
When something
Then foo
Given configuration file exists
And some dll not exists
When something
Then bar
将每个上下文设置步骤定义为复制/不将适当的文件复制到文件夹。还可以使用表格来定义应该将哪个文件复制到文件夹中:
Given some scenario
| FileName |
| a.config |
| b.invalid.config |
When something
Then foobar
https://stackoverflow.com/questions/20265369
复制相似问题