假设我有一些Manager类,需要通过删除代码来更改现有功能。

管理器总是在建立连接后发送初始消息以执行操作,例如clearInitialData()。我必须删除此初始发送。

在这个类的单元测试套件中,大约有30个测试。Unittest风格是一种集成测试,但带有模拟。

然而,除了testCreation()之外的每个单元测试都依赖于这个测试用例“testInitialDataCleared()”,它测试初始发送是否完成。然而,这正是我需要删除的行为。

我在如何开始这方面有点困难,所以我的方法是:

  1. 进行新的测试,确保清除的初始数据不会完成

  2. 删除了2个明显过时的测试用例,因为它们只是测试这种初始清除步骤

  3. 运行所有测试。正如所料,我自己的新测试在旧测试通过的地方失败了。

  4. 编辑现有测试以依赖于我创建的新测试用例。这似乎是一件合理的事情,因为之前这些测试都是在假定会有初始清算发送的情况下开始的

  5. 查看更多测试失败

  6. 做我认为会实现的修复。从实现中删除代码。

  7. 现在我看到断言从业务逻辑中失败了,并且由于核心从断言中转储(使用googletest/mock-btw),所有测试用例都无法完成运行。

不确定这是否是最好的TDD实践,也许我的实现修复有点过于侵入。无论如何,我可能需要在调试器中运行测试,以找出到底出了什么问题。

你有过类似的开发问题吗?你有什么好的建议吗?

结论和college一起看了一眼。实际的业务逻辑实现删除非常可靠。导致测试断言的原因是uut确实保持了静态状态。我的新单元测试将uut运行到一个意外的状态,因此其他测试中的一个具有此断言。所以基本上,由于静态数据的原因,我忘记了在新添加的单元测试结束时进行重置。所以基本上,我在谷歌测试中把测试作为单独的测试用例,这引起了问题。

在单元测试端我们的想法是用测试助手替换所有testInitialDataCleared(),而测试助手什么也没做。两个旧的行为单元测试被明确删除。

4
  • 在我看来,如果测试相互依赖,那么它们并不是真的单元测试。 5月5日10:01
  • 1
    撇开测试不谈,如果不调用“clearInitialData”,逻辑运行似乎会有所不同?它意味着某种共享状态。你确定你所需要做的就是删除清除呼叫吗?
    – 伊万
    5月5日12:44
  • 1
    @伊万:那是准确地说我的回答是,谢谢,这里至少有一个人和我一样理解这个问题。 5月5日15:33
  • 1
    是的,问题在(5)之后变得混乱,他们做出了正确的改变吗?是测试出错还是BL出错?编写测试或TDD时有问题吗?人们正在接受共享测试,但在这种情况下,它似乎并没有引起问题?
    – 伊万
    5月6日11:12

3个答案

重置为默认值
7

当测试不是为了独立而编写时,您会感到痛苦。第一步是使所有这些测试相互独立。打破两者之间的依赖关系测试初始数据已清除以及所有其他测试。概率是所有测试调用第一个测试以简化每个测试的设置。

考虑将最小的通用测试设置逻辑转移到可重用的实用程序方法中。我建议不要在内部调用这种常见的设置方法测试初始数据已清除只是为了保持第一个测试的独立性。此外,您无论如何都要删除该测试。

测试可以有一个通用的设置例程。第一次测试时不太好设置例程。测试独立后,删除被测系统中的代码,然后删除过时的测试并更改其余测试的通用设置。剩下的工作应该更容易,并在那之后显露出来。

在添加、删除和更改测试时,请记住,单元测试是由被测试的需求、实现需求所需的最小代码单元以及在代码单元不再实现需求时确保测试失败所需的最少断言数定义的。

4
  • 我怀疑这个问题读了两遍测试初始数据已清除包含其他测试的常见设置逻辑,可以轻松提取。我猜虽然OP称它为“测试”,但它只是一个帮助方法,用于验证其他每个测试中的不变“初始数据已清除”。 5月5日6:02
  • @DocBrown,验证不变的“初始测试数据已清除”与测试初始数据已清除有何不同?此外,OP声明除一个测试外,所有测试都依赖于testInitialDataCleared。如果它走路像鸭子,叫起来像鸭子的话,那它就是鸭子。这是行走和嘎嘎作响,就像一个测试是其他测试设置的一部分,这导致了删除行为和更改测试的头痛。 5月5日12:52
  • 1
    好吧,你写了“当第一个测试是设置例程时,这是不好的。”我怀疑这是警察的案子。由于一些常见的设置逻辑,没有调用“testInitialDataCleared”,我相信调用它是为了验证在其他测试描述的每个用例中都清除了初始数据。因此,在测试不变量的自动化测试中,可以使用可重用的方法。但是,通过将其重命名为“validateInitialDataWasCleared”而不将其用作独立测试本身并不能解决OP问题。。。。 5月5日14:10
  • …我想真正的问题不是“testInitialDataCleared”中“用例测试”的依赖性,而是BL代码对清除初始数据-这是必须打破的依赖关系。 5月5日14:21
2

我认为在不了解整个系统的情况下很难给你合理的建议,但我最好的猜测是你把Manager类改为不调用清除初始数据()此外,您的测试套件帮助您正确地实现了这个目标。

到目前为止,一切都很好。然而。发送清除初始数据()当然,业务逻辑是有目的的&仅仅删除它可能会导致不必要的副作用,而这些副作用只有在业务逻辑运行时才会显现出来。

因此,您首先需要了解的是,要了解删除的内容清除初始数据()将意味着你代码的BL部分。理想情况下,业务逻辑部分(单独)无论有无都能正常工作清除初始数据()在调用之前,决定是否调用它是在代码中的不同级别进行的,并且应该与BL本身保持正交(包括BL的所有测试)。断言现在失败的事实表明,BL目前并不是这样设计的。

如果你想通过TDD来解决这个问题,你首先需要在这里写下

  • 运行受影响的业务逻辑的一个或多个单元测试没有Manager类

  • 一个参数,用于让测试设置控制是否清除初始数据()是否在之前调用(不必清除初始数据()本身,但从业务逻辑代码的角度模拟效果的等效方法)

然后,您可以使用TDD样式的此测试为即将到来的更改准备业务逻辑。完成此操作后,是时候开始更改Manager类及其测试套件了,这在理想情况下会产生更成功的结果。

6
  • 失败的断言与Manager类之外的业务逻辑无关,因此测试外部类是没有意义的。 5月5日10:26
  • @基本情况:OP写道“现在我看到断言从业务逻辑上失败了,”-我不知道你是怎么解释这个句子的,但对我来说,这些很清楚与业务逻辑相关的断言。 5月5日12:09
  • 我假设这些不是测试代码,而是像前置条件和不变量一样的内部一致性检查。 5月5日12:14
  • 1
    @Basilevs:那么您是说业务逻辑中的前置条件和不变量之类的内部一致性检查与业务逻辑无关?无法说服我, 5月5日12:17
  • 1
    这些错误只与Manager的修改有着不可分割的关系,一旦Manager和测试环境处于正常工作状态,这些错误很可能会自行修复。他们不是考试不及格的对象。 5月5日12:19
-3

大多数失败的测试都是在做出一个不相关的断言。在执行更改之前修复该问题。

测试应该断言与其模拟的用例相关的任何内容。由于删除无关代码时出现测试失败,因此测试执行了不必要的断言。修复测试,使其专注于自己的场景和结果,而不会断言不必要的环境细节。

无关单元测试切线

业内有一种观点认为,每个单元测试都应该做出一个断言。声明的好处是,故障原因一目了然,错误更容易定位。推理是无效的,因为在调查测试失败时,第一个失败的断言是唯一重要的。

在您的案例中,问题不是多个断言,而是与测试场景无关的断言。

无论如何,这是不相关的,因为我们处理的是集成测试,而对集成测试的看法则不那么严格,也不那么愚蠢。

您的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.