我很难将自动化测试引入特定应用程序。我发现的大多数材料都集中在单元测试上。由于以下几个原因,这对此应用程序没有帮助:
考虑这种情况:
var item = server.ReadItem(100);
var item2 = server.ReadItem(200);
client.SomethingInteresting(item1, item2);
server.SomethingInteresting(item1, item2);
服务器调用的定义:
Server::SomethingInteresting(Item item1, Item item2)
{
// Semi-interesting things before going to the server.
// Possibly stored procedure call doing some calculation
database.SomethingInteresting(item1, item2);
}
如何设置一些自动化测试,其中有客户端交互,服务器交互然后数据库交互?
据我所知,这不构成“单位”。这可能是功能测试的一个例子。
以下是我的问题:
非常感谢任何协助。
答案 0 :(得分:2)
如果这是贵公司非常重要的应用程序,预计会持续数年,那么我建议从小做起。开始寻找可以通过对代码进行少量修改来测试或测试的小块,以使其可测试。
这不理想,但在一年左右的时间里,你可能会比现在好多了。
答案 1 :(得分:2)
您应该查看Cucumber或Fitnesse等集成测试运行器。根据您的情况,集成测试运行器将充当您的服务器的客户端并对服务器进行适当的调用,或者它将与您现有的客户端共享一些域代码并运行该代码。您将为您的方案提供一系列应该进行的调用,并验证是否输出了正确的结果。
我认为您至少可以通过一些工作使应用程序的某些部分可测试。祝你好运!
答案 2 :(得分:2)
看看Pex和Moles。 Pex可以分析您的代码并生成将测试所有临界条件等的单元测试。您可以开始引入一个模拟框架来开始删除一些Complext位。
为了更进一步,你必须开始使用集成测试来访问数据库。为此,您必须控制数据库中的数据并在测试完成后进行清理。很少有这样做的方法。您可以在每次测试的设置/拆除过程中运行sql脚本。您可以使用编译时AOP框架(如Postsharp)来运行sql脚本,只需在属性中指定它们即可。或者,如果您的项目不想使用Postsharp,您可以使用称为“上下文绑定对象”的内置点网功能来注入代码以便以AOP方式运行Sql脚本。更多细节 - http://www.chaitanyaonline.net/2011/09/25/improving-integration-tests-in-net-by-using-attributes-to-execute-sql-scripts/
基本上,我建议的步骤,
1)安装Pex并生成一些单元测试。这将是生成一组良好的回归测试的最快,最省力的方法。
2)分析单元测试,看看是否有其他测试或可以使用的测试排列。如果是这样的话,请手写。如果需要,引入模拟框架。
3)开始进行端到端集成测试。编写sql脚本以将数据插入和删除到数据库中。编写一个运行insert sql脚本的单元测试。在应用程序前端调用一些非常高级的方法,例如“AddNewUser”,并确保它一直到后端。前端,高级方法可以在各个层中调用任意数量的中间方法。
4)一旦你发现自己在这种模式下编写了很多集成测试“运行sql脚本来插入测试数据” - >调用高级功能方法 - > “运行Sql脚本来清理测试数据”,您可以使用AOP技术(如Postsharp或Context Bound Methods)清理代码并封装此模式。
答案 3 :(得分:2)
理想情况下,您会随着时间的推移重构代码,以便使其更易于测试。理想情况下,该领域的任何增量改进都将允许您编写更多单元测试,这将大大增加您对现有代码的信心,以及编写新代码而不破坏现有测试代码的能力。
我发现这种重构通常也会带来其他好处,例如更灵活和可维护的设计。在试图证明这项工作的合理性时,要记住这些好处。
测试这样的应用程序是否是一个失败的原因?
我多年来一直在进行自动化集成测试,并且发现它对我自己以及我为之工作过的公司都非常有益。我最近才开始了解如何使应用程序完全可单元测试在过去3年左右的时间里,我之前正在进行完整的集成测试(使用自定义实现/黑客测试挂钩)。
所以,不,它不是一个失败的原因,即使应用程序的架构方式也是如此。但是如果你知道如何进行单元测试,你可以从重构应用程序中获得很多好处:测试的稳定性和可维护性,编写它们的容易程度,以及将故障隔离到导致失败的特定代码区域。
这可以使用像nUnit或MS Test这样的东西来完成吗?
是。您可以使用.Net单元测试库中的网页/ UI测试框架,包括Visual Studio内置的库。
通过直接调用服务器而不是通过UI(与重构应用程序时获得的优点相似),您也可以获得很多好处。您还可以尝试模拟服务器,并单独测试客户端应用程序的GUI和业务逻辑。
此测试的“设置”是否会强制启动完整的应用程序并登录?
在客户端,是的。除非您想测试登录,当然:)
在服务器端,您可以让服务器保持运行,或者在测试之间进行某种数据库恢复。数据库恢复是痛苦的(如果你写错了,会很不稳定)并且会减慢测试速度,但它会极大地帮助测试隔离。
我是否只是从数据库中重新读取item1和item2以验证它们是否已正确写入?
典型的集成测试基于Finite State Machine的概念。这些测试将被测代码视为一组状态转换,并对系统的最终状态进行断言。
因此,您事先将数据库设置为已知状态,在服务器上调用方法,然后再检查数据库。
您应该始终在低于您正在执行的代码级别的级别上执行基于状态的断言。因此,如果您使用Web服务代码,请验证数据库。如果您运行客户端并且正在运行真实版本的服务,请在服务级别或数据库级别进行验证。您永远不应该使用Web服务并在同一Web服务上执行断言(例如)。这样做可以掩盖错误,并且无法让您真正相信您实际上正在测试所有组件的完全集成。
你们有没有关于如何开始这个令人生畏的过程的任何提示?
分手你的工作。识别系统的所有组件(每个组件,每个运行的服务等)。尝试将这些分成自然类别。花一些时间为每个类别设计测试用例。
优先考虑设计您的测试用例。检查每个测试用例。想象一下可能导致它失败的假设场景,并试图预测它是否会成为一个停止显示错误,如果该错误可能会暂时停留,或者是否可能被另一个版本处罚。根据这些猜测为您的测试用例分配优先级。
识别具有尽可能少的依赖关系的应用程序(可能是特定功能),并为其仅写入最高优先级的测试用例(理想情况下,它们应该是最简单/最基本的测试)。完成后,继续下一个应用程序。
如果您拥有最高优先级测试用例所涵盖的应用程序的所有逻辑部分(所有程序集,所有功能),请尽可能地使这些测试用例每天运行。在进行其他测试实施之前,修复这些情况下的测试失败。
然后在您正在测试的应用程序上运行代码覆盖率。查看您错过的应用程序的哪些部分。
重复每个连续的更高优先级的测试用例集,直到整个应用程序在某个级别进行测试,并且您发货:)