Unit testing 单元测试建议

Unit testing 单元测试建议,unit-testing,tdd,Unit Testing,Tdd,我有一个由大约50-60个表组成的大型数据库支持的中等到高度复杂的应用程序。我试图在代码上获得尽可能多的单元测试覆盖率,但我真的很难模拟数据集和一些关键概念。实际上,一想到要实现完整的单元测试覆盖率,我就感到焦虑,因为我不知道如何做到以下几点: 1) 测试每个功能的每个可能场景和数据组合。即,我们的一个函数返回一个基于大约20个输入的值,每个输入有3个不同的可能值。我们怎么可能测试所有类似的值呢?如果我可以测试所有这些组合,我必须在测试中编写完全相同的逻辑代码,以确定它是否应该通过(这不是多余的

我有一个由大约50-60个表组成的大型数据库支持的中等到高度复杂的应用程序。我试图在代码上获得尽可能多的单元测试覆盖率,但我真的很难模拟数据集和一些关键概念。实际上,一想到要实现完整的单元测试覆盖率,我就感到焦虑,因为我不知道如何做到以下几点:

1) 测试每个功能的每个可能场景和数据组合。即,我们的一个函数返回一个基于大约20个输入的值,每个输入有3个不同的可能值。我们怎么可能测试所有类似的值呢?如果我可以测试所有这些组合,我必须在测试中编写完全相同的逻辑代码,以确定它是否应该通过(这不是多余的吗?)

2) 数据和结果随时间而变化!例如,如果我查询上周租车的员工人数,随着时间的推移,我总是会返回不同的结果。我如何编写一个单元测试,知道如果结果从一天到下一天会发生变化,那么预期会有多少结果


有人说,如果您在单元测试中遇到困难,说明您做得不对,那么请告诉我如何最好地处理这些情况。

尽管我有上述评论,但还是有一些想法:

  • 在单元测试中,您测试“单元”。单元测试的一大技巧是确定“单元”到底是什么。那么你们的单位是什么?提示:它们几乎从不包含涉及数据库的内容
  • 确定适当的单位是防止结果和数据更改问题的关键。如果一个核心功能发生了变化,那么当然,单元测试需要修改甚至删除,否则它应该是最低限度的维护
  • 组合和排列-测试您实际需要测试的东西。您可以为此编写一些帮助程序代码。然而,您并不总是需要绝对地测试所有东西,测试到有用的程度,而不需要进一步测试
  • 我发现高水平的测试很有用,但您可能不会。您在单元测试方面的经验和能力决定了测试的有用程度

我感谢你的否决票。如果有原因的话,我会更感激的。我很想知道单元测试变量的最佳实践是什么,这些变量随着时间的推移而变化,并且有x^n个可能的输入。原因是没有一个具体的问题。基本上,您需要的是“单元测试建议”,您可以通过简单的谷歌搜索找到它(尽管我建议您专门寻找BDD建议)。换句话说:你有什么具体的问题,你尝试过什么?1)测试边缘情况;希望使用一个允许“数据驱动”测试的测试框架。2) 测试结果不应随时间而变化,只应随数据而变化。接受此类测试的时间参数(现在只有数据),并使用DI/IoC获取时间对象,以便在测试中模拟它们!查询的测试数据库也应该是不变的(对于预期的数据/结果)。读取点1和点2。点1是一个函数,它接受一个对象,该对象有大约20个属性,每个属性有大约3个可能的值。如果满足某些条件,则返回TRUE或FALSE。这实际上是一段非常简单的代码,但是用这些值的每一个组合进行单元测试似乎有点不可能。问题2是,我的搜索功能依赖于需要进行单元测试的时间。这有点简单,因为我可以模拟一个我知道将在我搜索的日期范围内的对象。@user2864740谢谢!谢谢我最近读到的一篇文章建议首先测试几个边缘案例,然后如果生产中出现任何bug,就将它们添加回单元测试中。我需要一些数据来测试我的方法,这就是为什么我有测试数据。我没有对实际的查询生成进行单元测试,只是方法返回了正确的内容。@RaySülzer数据库通常被视为外部系统,因此不属于“单元”。通常在这种情况下,您要么将数据作为参数传入,要么将数据源建立在接口上并将其存根。在一个方法中加入20个参数是一个可怕的想法,尽管部分原因正是您所陈述的。它们不可能控制计算的所有相同方面。我鼓励你把它分开。Joshua Bloch在一个方法中推荐的参数不超过四个。每个方法不超过20个参数,该方法接受一个类为“Employee”的对象,该对象上有一组属性。然后,该方法调用一组传递属性的私有方法,这些属性根据值返回bool。我将通过传入私有方法所需的一个或两个参数来对其进行单元测试,而不是对公共方法进行单元测试。是的,这可能是您目前的最佳选择,但请注意,这会引发一些危险信号,表明您的设计可能存在问题,这些问题可能会在以后成为问题。对于该特定方法,因为它调用了很多其他可能处理数据的方法,所以将110%的精力放在流和行为上。我知道我会通过基于一些常规数据断言一个特定的行为来测试它(例如,按时调用方法x,方法y两次)。然后确保该方法尽可能少地处理数据本身。