我目前正在使用Entity Framework 5进行MVC 5项目(我可能会很快切换到6)。我首先使用数据库,使用MySQL和现有数据库(大约40个表)。这个项目最初是作为“概念证明”开始的,现在我公司决定使用我正在开发的软件。我正在努力测试部分。
我的第一个想法是主要使用集成测试。这样我觉得我可以测试我的代码以及我的底层数据库。我创建了一个脚本,将现有的数据库模式转储到MySQL中的“测试数据库”中。我总是使用没有数据的干净数据库开始我的测试,并为每个测试创建/删除一些数据。问题是我运行测试需要相当长的时间(我经常进行测试)。
我正在考虑用单元测试替换我的集成测试,以加快运行它们所需的时间。我会“删除”测试数据库,只使用模拟代替。我已经测试了一些方法,它看起来效果很好,但我想知道:
我知道这类问题很容易出现“这取决于你的需求”的反应,但我确信有些人可能已经通过这个并且可以分享他们的知识。我也知道在一个完美的世界里,我会做两件事(通过使用模拟和使用数据库进行测试),但我没有这种时间。
作为一个侧面问题,您会建议使用什么工具进行模拟。我被告知“moq”是一个很好的框架,但它有点慢。你觉得怎么样?
答案 0 :(得分:4)
- 您是否认为模拟我的数据库可以“隐藏”只有在我的代码针对真实数据库运行时才会出现的错误?请注意,我不想测试实体框架(我确信微软的优秀人员在这方面做得很好),但是我的代码可以很好地针对模拟和针对MySQL的打破吗?
醇>
是的,如果您只使用Mocks测试代码,那么您很容易对代码产生错误的信心。当你嘲笑数据库时,你正在做的是说"我希望这些调用能够进行#34;。如果您的代码拨打了这些电话,那么它就会通过测试,但如果他们拨打了错误的电话,那么它就无法在生产中工作。在简单的层面上,如果您在数据库中添加/删除列,则可能需要更改数据库交互,但在更新模拟之前,添加/删除列的过程将从测试中隐藏。
- 您认为从集成测试到单元测试是否是“降级”之王?
醇>
它不是降级,它有所不同。单元测试和集成测试具有不同的好处,在大多数情况下会相互补充。
- 您认为放弃集成测试和采用单元测试以提高速度是可以的。
醇>
好的是非常主观的。我拒绝,但是您不必在所有的所有时间内运行所有。大多数测试框架(如果不是全部)允许您以某种方式对测试进行分类。这允许您创建测试的子集,因此您可以例如拥有" DatabaseIntegration"您将所有数据库集成测试放入的类别,或者" EndToEnd"完整的端到端测试。我首选的方法是单独构建。我在每次签到之前/之后运行的常规/连续构建仅运行单元测试。这提供了快速反馈和验证,没有任何破坏。除了运行单元测试之外,不常见/每日/夜间构建还将运行较慢/可重复的集成测试。如果代码有可能影响集成,我还倾向于在检查代码之前对我正在处理的领域进行集成测试。
- 我知道有一些框架存在针对内存数据库(即Effort框架)运行测试,但我没有看到这个与模拟的优点,我缺少什么?
醇>
我还没有使用它们,所以这是猜测。我认为主要的好处是,不是必须模拟数据库与模拟的交互,而是设置数据库并测量帖子状态。测试变得不那么 你做了什么以及更多移动了哪些数据。从表面上看,这可能会导致较少的脆弱测试,但是您可以有效地针对您不会在生产中使用的其他数据提供商编写集成测试。如果它是正确的做法再次,非常主观。
我想第二个好处可能是你不一定需要重构代码才能利用内存数据库。如果您的代码没有被构造为支持依赖注入,那么您很可能需要执行某种程度的重构以支持模拟。
我也知道,在一个完美的世界里,我会做两件事(通过使用模拟和使用数据库进行测试),但我没有这种时间。
我真的不明白你为什么会这样。您已经说过,您已经进行了集成测试,而您正在计划更换单元测试。除非您需要进行重大重构以支持单元测试,否则您的集成测试仍然可以正常工作。您通常不需要与需要单元测试一样多的集成测试,因为单元测试用于验证功能,并且集成测试用于验证集成,因此创建它们的开销应该相对较小。使用分类来确定您运行的测试将减少运行测试的时间影响。
作为一个侧面问题,您会建议使用什么工具进行模拟。我被告知“moq”是一个很好的框架,但它有点慢。你觉得怎么样?
我使用了不少不同的模拟库,而且大多数情况下它们都非常相似。使用不同的框架,有些事情会变得更容易,但是如果你不知道自己在做什么,很难说你是否会注意到。如果您还没有考虑依赖注入而构建代码,那么您可能会发现将模拟带到您需要的地方很有挑战性。
任何类型的模拟通常都非常快,您通常(除非您使用部分模拟)删除了您所嘲笑的类/接口的所有功能,因此它会被“嘲笑”。比普通代码执行速度更快。我听说过的唯一性能问题是,如果你是MS伪造/垫片,有时候(取决于伪装配件的复杂程度),可能需要一段时间来创建假装配。
我使用的两个框架有点不同的是MS假货/垫片和Typemock。 MS版本需要一定级别的视觉工作室,但允许您生成带有某些类型对象的垫片的假装配,这意味着您不必将测试中的模拟传递到他们使用的位置。 Typemock是一个商业解决方案,它使用分析API在您的测试运行时注入代码,这意味着它可以到达其他模拟框架无法实现的部分。如果你的代码库没有用单元测试编写,这有助于缩小差距,那么它们特别有用。