单元测试程序主要与外部资源交互

And*_*rea 20 unit-testing

我想在我的应用程序中开始进行更多的单元测试,但在我看来,我所做的大部分工作都不适合进行单元测试.我知道单元测试应该如何在教科书示例中起作用,但在现实世界的应用程序中它们似乎并没有多大用处.

我编写的一些应用程序具有非常简单的逻辑和与我无法控制的事物的复杂交互.例如,我想编写一个守护进程来响应某些应用程序发送的信号,并更改操作系统中的一些用户设置.我可以看到三个困难:

  • 首先,我必须能够与应用程序进行交谈并获得有关其活动的通知;
  • 然后我需要在收到信号时与操作系统进行交互,以便更改相应的用户设置;
  • 最后所有这些应该作为一个守护进程.

所有这些都可能是微妙的:我将不得不浏览可能复杂的API,我可能会引入错误,比如错误解释一些参数.单元测试能为我做什么?我可以模拟外部应用程序和操作系统,并检查给定来自应用程序的信号,我将在操作系统上调用适当的API方法.这是......嗯,应用程序的简单部分.

实际上我做的大多数事情涉及与数据库,文件系统或其他应用程序的交互,这些是最精细的部分.

再看另一个例子,看看我的构建工具PHPmake.我想重构它,因为它写得不是很好,但我担心这样做,因为我没有测试.所以我想补充一些.重点是单元测试可能无法捕获可能被重构破坏的东西:

  • 要做的事情之一是决定要构建哪些内容以及哪些内容已经是最新的,这取决于上次修改文件的时间.当触发某些构建命令时,此时间实际上是由外部进程更改的.
  • 我想确保正确显示外部进程的输出.有时buikd命令需要一些输入,并且还应该正确管理.但我不知道先验流程将会运行 - 它可能是任何东西.
  • 一些逻辑涉及模式匹配,这似乎是可测试的部分.但是进行模式匹配的函数使用(除了他们自己的逻辑之外)PHP函数glob,它与文件系统一起使用.如果我只是模拟一棵树代替实际的文件系统,glob将无法正常工作.

我可以继续更多的例子,但重点是以下几点.除非我有一些精巧的算法,否则我所做的大部分工作都涉及与外部资源的交互,这不适合单元测试.更重要的是,通常这种互动实际上是非平凡的部分.仍有许多人将单元测试视为基本工具.我错过了什么?我怎样才能学会成为更好的测试人员?

Car*_*ngo 9

我想你在问题中提出了一些问题.

首先,当您的应用程序与外部环境(如操作系统,其他线程等)集成时,您必须将(1)与外部环境相关的逻辑和(2)您的业务代码分开(即,应用程序的功能.这与在应用程序(或Web应用程序)中分离GUI和SERVER的方式没有什么不同.

其次,你问你是否应该测试简单的逻辑.我会说,这取决于.通常,简单的提取/存储功能很适合进行测试.这就像你的应用程序的基础..因此它很重要.基于你的基础构建的其他商业资料非常简单,你可能很容易发现自己都觉得自己在浪费时间,而且大多数情况下你都是:-)

第三,重构现有程序并在其现有状态下对其进行测试可能是个问题.如果您的PHP程序根据某些输入生成一组文件,那么,也许这就是您测试的入口点.当然测试可能是高级的,但这是确保在重构​​之后,程序产生相同输出的简单方法.因此,在重构工作的开始阶段,针对那种情况下的更高级别测试.

我想推荐一些文献,但我只想出一个标题."有效地处理遗产代码"作者:Micheal Feathers.这是一个好的开始.另一个是Gerard Meszaros的"xUnit测试模式:重构测试代码"(虽然那本书更加草率和完整的复制粘贴文本).