mat*_*i82 58 .net c# integration-testing unit-testing file
我有一些类实现了一些与文件系统和文件相关的逻辑.例如,我正在执行以下任务作为此逻辑的一部分:
现在所有这些逻辑都有一些工作流程,如果某些东西不正确(例如,在特定文件夹位置找不到配置文件),则抛出异常.此外,还有Managed Extensibility Framework(MEF)涉及此逻辑,因为我检查的其中一些文件是我手动加载到MEF聚合等的托管DLL ...
现在我想以某种方式测试所有这些.我想在HDD上创建几个物理测试文件夹,涵盖各种测试用例,然后针对它们运行我的代码.我可以创建例如:
这是正确的方法吗?我不确定在这种情况下如何运行我的代码...我当然不想运行整个应用程序并指向它来检查这些模拟的文件夹.我应该使用一些单元测试框架来编写一种"单元测试",它会针对这些文件系统对象执行我的代码吗?
总的来说,对于这种测试场景,这一切都是正确的方法吗?还有其他更好的方法吗?
Vla*_*aev 62
首先,我认为,最好在不触及任何外部资源的情况下编写单元测试来测试逻辑.这里有两个选择:
在单元测试中,您不需要测试外部库(如MEF)的逻辑.
其次,如果你想编写集成测试,那么你需要编写"快乐路径"测试(当一切正常时)和一些在边界情况下测试逻辑的测试(文件或目录未找到).与@Sergey Berezovskiy不同,我建议为每个测试用例创建单独的文件夹.主要优点是:
对于单元测试和集成测试,您可以使用普通的单元测试框架(如NUnit或xUnit.NET).使用此框架可以非常轻松地在Build服务器上的持续集成方案中启动测试.
如果您决定编写这两种测试,那么您需要将单元测试与集成测试分开(您可以为每种测试创建单独的项目).原因:
您应该通过抽象调用接口后面的文件系统来测试单元测试尽可能多的逻辑.使用依赖注入和测试框架(如FakeItEasy)将允许您测试您的接口实际被使用/调用以对文件和文件夹进行操作.
但是,在某些时候,您还必须测试在文件系统上工作的实现,这是您需要集成测试的地方.
你需要测试的东西似乎是相对孤立的,因为你想要测试的是你自己的文件和目录,在你自己的文件系统上.如果您想测试数据库或其他具有多个用户的外部系统等,事情可能会更复杂.
我认为你不会找到任何关于如何最好地进行这种类型的集成测试的"官方规则",但我相信你是在正确的轨道上.你应该努力的一些想法:
在你的情况下,我会设置两个主要文件夹:一个是所有内容都应该是(它正常工作),一个是所有规则都被破坏的文件夹.
我会创建这些文件夹及其中的任何文件,然后压缩每个文件夹,并在测试类中编写逻辑以解压缩每个文件夹.
这些并不是真正的考验; 将它们视为用于设置测试场景的"脚本",使您能够轻松快速地删除和重新创建文件夹和文件,即使您的主要集成测试在测试期间应该更改或弄乱它们.将它们放入测试类中的原因很简单,就是在测试过程中使用相同的界面轻松运行它们.
创建两组测试类,每种情况设置一组(正确设置文件夹与具有损坏规则的文件夹).将这些测试放在对您有意义的文件夹层次结构中(取决于您的情况的复杂程度).
目前尚不清楚您对单元/集成测试的熟悉程度.无论如何,我会推荐NUnit.我也喜欢使用扩展名Should
.你可以从Nuget获得这两个:
install-package Nunit
install-package Should
Run Code Online (Sandbox Code Playgroud)
should-package将允许您以如下方式编写测试代码:
someCalculatedIntValue.ShouldEqual(3);
someFoundBoolValue.ShouldBeTrue();
Run Code Online (Sandbox Code Playgroud)
请注意,有几个测试运行器可用于运行测试.我个人对于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();
}
}
Run Code Online (Sandbox Code Playgroud)
完成所有这些后,您应该能够创建并重新创建测试场景,并以简单且可重复的方式对它们运行测试.
编辑:正如评论中所指出的,Assert.Throws()是另一种确保根据需要抛出异常的选项.就个人而言,我喜欢tag-variant,并且通过参数,您可以检查错误消息等内容.另一个例子(假设您的计算器抛出了自定义错误消息):
[ExpectedException(typeof(DivideByZeroException),
ExpectedMessage="Attempted to divide by zero" )]
public void When_attempting_something_silly(){
...
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
41691 次 |
最近记录: |