您应该使用单元测试来测试尽可能多的逻辑,方法是抽象对接口后面的文件系统的调用。使用依赖注入和诸如FakeItEasy 之类的测试框架将允许您测试您的接口是否实际被使用/调用以对文件和文件夹进行操作。
然而,在某些时候,您还必须测试在文件系统上运行的实现,这就是您需要进行集成测试的地方。
您需要测试的东西似乎是相对孤立的,因为您想要测试的只是您自己的文件和目录,在您自己的文件系统上。如果您想测试数据库或其他具有多个用户的外部系统等,事情可能会更复杂。
我认为您不会找到任何关于如何最好地进行此类集成测试的“官方规则”,但我相信您走在正确的轨道上。您应该努力实现的一些想法:
-
明确的标准:让每项测试的规则和目的绝对清晰。
-
自动化:无需过多手动调整即可快速重新运行测试的能力。
-
可重复性:您可以“重置”的测试情况,因此您可以快速重新运行测试,只有轻微的变化。
创建可重复的测试场景
在您的情况下,我会设置两个主要文件夹:一个是所有内容都按预期进行的文件夹(即正常工作),另一个是所有规则都被破坏的文件夹。
我会创建这些文件夹和其中的任何文件,然后压缩每个文件夹,并在测试类中编写逻辑以解压缩每个文件夹。
这些并不是真正的测试;将它们视为设置测试场景的“脚本”,使您能够轻松快速地删除和重新创建文件夹和文件,即使您的主要集成测试在测试期间应该更改或弄乱它们。将它们放在测试类中的原因只是为了让您在测试期间使用相同的界面轻松运行。
测试
创建两组测试类,每种情况一组(正确设置文件夹与规则不规则的文件夹)。将这些测试放在对您有意义的文件夹层次结构中(取决于您的情况的复杂性)。
不清楚您对单元/集成测试的熟悉程度。无论如何,我会推荐NUnit。我也喜欢使用Should 中的扩展名。您可以从 Nuget 获得这两个:
install-package Nunit
install-package Should
should-package 将让您以如下方式编写测试代码:
someCalculatedIntValue.ShouldEqual(3);
someFoundBoolValue.ShouldBeTrue();
请注意,有几个可用的测试运行器可以用来运行您的测试。我个人只对 Resharper 内置的跑步者有任何实际经验,但我对它非常满意,我推荐它没有问题。
下面是一个包含两个测试的简单测试类示例。请注意,在第一个中,我们使用来自 Should 的扩展方法检查预期值,而在第二个中我们没有显式测试任何内容。那是因为它被标记为[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() is another option 用于确保根据需要抛出异常。就个人而言,我喜欢标签变体,with parameters,你也可以在那里检查错误消息之类的东西。另一个示例(假设您的计算器正在抛出自定义错误消息):
[ExpectedException(typeof(DivideByZeroException),
ExpectedMessage="Attempted to divide by zero" )]
public void When_attempting_something_silly(){
...
}