Python单元测试以及何时进行模拟

时间:2012-07-26 17:29:57

标签: python unit-testing mocking

我正在开始一项新工作的新项目。这是我第一次大量使用Python。与我必须以静态类型语言跳过的箍相比,嘲笑是一个全新的野兽。我自己去研究团队的单元测试,并希望将其中的一部分从使用Dingus升级为Mock。

今天早些时候,我遇到了一些正在检查转换类的测试。具体来说,它将十六进制数字的字符串转换为Mongo ObjectIds(唯一标识符)。我期望看到的是在给定有效十六进制数的情况下验证的测试,将返回具有相同十六进制数的ObjectId - 或者 - 如果给出错误的十六进制数,则会发生错误。相反,测试验证的所有内容都是创建并返回了ObjectId。事实上,ObjectId完全被嘲笑,十六进制数也是如此!

现在,从字符串创建ObjectId不需要去服务器或任何东西。一切都在当地进行。

我和我的新同事一起询问了这个特定的测试套件。他们的想法是应该使用集成测试验证实际转换并进行单元测试,所有单元测试应该确保代码按预期从上到下流动并创建并返回ObjectId。因此,基本上,测试只验证此类是否以预期的方式与环境交互。

我一直在写单元测试。根据我的经验,我根本不会使用模拟,我只会验证按预期发生的转换。这意味着与另一个模块的ObjectId类进行交互。也许我对单元测试的想法过于笼统。我一直保留用于连接远程服务器,文件和诸如此类的集成测试。

我看待它的方式,在这个例子中使用ObjectId与使用str或list没什么不同。当然,我可以模拟str和list,但由于它们对我的代码所做的事情至关重要,因此在我的脑海里嘲笑它们并没有多大意义。我应该关心与依赖项交互的唯一时间是它何时可以改变测试的结果。

编写单元测试是否有任何价值只是检查代码流?单元测试不应该是考虑到代码行为/正确性的结果吗?

1 个答案:

答案 0 :(得分:1)

所以,很难在不看代码的情况下确切地看到发生了什么,但完全基于你的解释......

我同意你的看法。行为是重要的,而不是代码的流程。

如果稍后某人需要更改代码流以支持不同的情况(例如,使用具有不同参数的函数来完成相同的结果),该怎么办?他们可以在不破坏现有测试的情况下这样做。

如果升级正在使用的库,现在调用该函数实际上有不同于您想要的结果,该怎么办?您的测试仍然有效(正在调用该函数),但单元测试实际上正在尝试测试的不是。

真的,如何使用嘲讽和测试仍然是一个非常年轻的学科。对于单元测试(以及单元测试中使用的各种策略,例如模拟)是否被认为是“好事”,评审团仍然不清楚。然而,毫无疑问,我发现自己创建的测试不是为了实际测试行为,而是为了让我可以说我有测试,并且不正确地使用模拟是一种很好的方式来假装你真正创建了测试'我们刚刚创造了一种错误的成就感,你的代码现在已经得到了更严格的测试。