首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我应该如何“单元测试”一个完整的包?

我应该如何“单元测试”一个完整的包?
EN

Software Engineering用户
提问于 2014-04-01 17:32:11
回答 3查看 1.5K关注 0票数 5

我仍然在学习如何做好单元级测试,因为过去我一直对只做功能测试有点草率,所以我想再次检查一下我是否做得对。

我有一个包,它负责自动神奇地更新一个特定的配置,该配置在运行时将定期更改。向主包类的构造函数提供要监视的对象列表。然后,在某个时候调用update,它将进入定义配置、检测更改、更新其监视对象的适当状态的所有多个位置,并提供所更改的内容的报告。这对所有其他包都是自动的,或者是透明的。

我倾向于把它作为一个单元来测试,但是它是一个相当大的单元,5-6类,从多个文件和restful接口中获取。测试任何较小的单元都需要花费更长的时间,对重构不那么灵活,并且只提供了更高的发现缺陷的机会,但这可能只是我的懒惰之言。在较低的水平上测试会被认为是“更好”吗?

假设将包作为一个单元进行测试是“正确的”,那么什么才是适合于模仿这样的东西的呢?有一些类的方法是由我的主类实例化的(即,不是我直接传入的东西,所以我不能只是传递我自己的模拟),这些方法都有我想要控制的方法。我相信我可以在我能想到的两种情况下使用powerMock (或者在我进一步研究PowerMock之后),但是我不确定这样做是否足够透明。在我的包试图打开配置文件时,配置PowerMock是否可以检测并返回模拟文件对象,即使它深深地隐藏在包逻辑中,还是被认为是滥用了我对实现特定细节的知识?实际上修改文件系统上的配置文件并让它们正常读取而不进行进一步的模拟会更“干净”吗?我需要定期修改文件进行测试.

编辑:为了澄清其中一个问题中提出的耦合问题,我不认为我的类过于耦合。实际上,我有三个类从A、B和C获取状态,然后是一个'main‘类,它从三个类获取状态,并决定如何正确地组合它(即,如果A和B不匹配,则使用A(除非C) )。我可以轻松地分别测试A、B和C,然后模拟它们来测试我的“主”类。然而,我的“主”类的测试似乎可以有效地测试A、B和C的相对简单的接口,如果我不对它们进行模拟的话。因此,单独测试它们就像是重复的工作。通过单独的测试,我可能会得到一些稍微好一些的代码覆盖率,而且只有一个测试是很好的。但我不知道这是否值得所有的间接费用为小利益。

EN

回答 3

Software Engineering用户

回答已采纳

发布于 2014-04-01 21:19:47

单元测试是测试的最低级别,但这只意味着它是您所做的最低级别,而不是您理论上可以做的最低级别。如果在类级别进行测试,则可以在方法级别进行测试,使用适当的测试工具获取私有成员。但是,如果在方法级别进行测试,则可以在语句级别进行测试,使用适当的测试工具来隔离地获取语句,从而对其进行测试。如果您确实决定在语句级别进行测试,那么这仍然是一个不进行指令或字节码级别测试的决定。而这种分解过程只有在某人认为“一个较小的单位是愚蠢的”时才会停止。

因此,“我应该如何单元测试”的问题完全等同于“我应该如何首先测试这个”。如果测试包的最佳方法是作为一个整体进行测试,因为它的大小和复杂性使其作为一个单元进行测试是满足您的可靠性和可维护性目标的最有效方法,那么就这样做吧。

如果不是,那就不要。

如果有人试图给出更具体的建议,而不是看你的代码库,或者不知道你的项目背景(孤儿院地下室的核电站,还是垃圾邮件生成器?)很可能不仅是错的,而且也是不明智的。

票数 7
EN

Software Engineering用户

发布于 2014-04-02 03:10:53

对于刚开始学习TDD的人来说,这是一个非常常见的问题。我不知道这是不是你的案子,但你能遵循的逻辑是一样的。

首先,暂时忘记“单位”这个词。想一想,你将如何从地面零和测试优先开发相同的软件包。您不能从测试“只测试类”或“只测试方法”开始,因为您还没有任何东西,而且您也不知道需要的所有类和方法。

因此,首先要指定测试中的第一个预期行为,然后通过测试,所有这些都包含行为的特定部分所需的最小代码量。重复此循环,直到实现所有行为,同时在循环之间进行重构。

在重构期间,您可以将逻辑拆分到不同的类中,并尝试设计选项。测试仍将运行在功能的“主”类或“公共API”上。为了避免妨碍重构代码的自由,这被认为是最佳做法的原因。

考虑到这个循环,在您的具体情况下,几乎没有必要嘲笑您自己的协作者。但是,您确实应该模拟代码的外部依赖关系,例如配置文件和restful服务。主要是因为您应该能够测试您的代码,而不依赖于环境因素,例如目录中的文件,而且如果您为这些依赖项提供了一个注入点,您还可以增加功能的灵活性。

PS:我知道您不会从头开始编写代码,但这是您使用TDD所遵循的过程的概要,只是为了让您了解测试的样子。

PS2:我所说的“模拟”指的是任何类型的双重测试,比如假货、假人、存根、间谍和真实的模拟。

票数 3
EN

Software Engineering用户

发布于 2014-04-01 17:41:53

单元测试就像归纳推理。您可以确保小块n行为良好,然后可以信任在您构建系统时,每个n + 1段也都具有良好的性能。

在您的情况下,我将隔离单个测试中的5-6类中的许多类,以确保每个类都在做它应该做的事情。(这有一个额外的好处,那就是加速您的编码,因为您并不总是被意外的缺陷所绊倒。)

如果你想单独测试那些一起工作的人,那很好--想想你需要模仿什么或者存根来启动特定的逻辑路径。在某种程度上,系统中有一些东西正在调用以触发更新--所以嘲笑一下吧。

一个好的经验法则是,不要测试你没有写过的东西

在更哲学的层面上;)“单位”的定义并不是一条光明的界线。单元可以是方法,也可以是类,但即使在方法中,也可能存在对多个对象的引用。只要你能在“单位”周围画出一个相当小的边界,并且孤立地运行它,那就好了。

..。

另一个考虑因素是,如果您的5-6个小班很容易单独进行单元测试,那么它们很可能设计得很好。如果这些类紧密耦合到不能单独使用每个类,这意味着您可能需要后退一步,查看您的设计。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/234428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档