C# 将单元测试添加到非为其设计的代码中

C# 将单元测试添加到非为其设计的代码中,c#,unit-testing,C#,Unit Testing,在工作中,我们有三层产品。有一个用户使用的客户端应用程序,它从服务器查询数据,服务器将这些请求转发到SQL数据库。我们不允许客户端直接访问SQL server 客户机产品是我想要进行单元测试的,但它有120多万行C#代码,而且是一个非常古老的产品。它的设计没有考虑到单元测试,该产品的主要开发人员通常反对单元测试,主要是因为风险与回报的关系,以及如何重新设计以减少需要进行的模拟量。这些核心的、低级的客户端库和对象的重新设计也引起了他们的关注 我的理念是绝对不要忽视单元测试(因为我们总是太忙了,而且

在工作中,我们有三层产品。有一个用户使用的客户端应用程序,它从服务器查询数据,服务器将这些请求转发到SQL数据库。我们不允许客户端直接访问SQL server

客户机产品是我想要进行单元测试的,但它有120多万行C#代码,而且是一个非常古老的产品。它的设计没有考虑到单元测试,该产品的主要开发人员通常反对单元测试,主要是因为风险与回报的关系,以及如何重新设计以减少需要进行的模拟量。这些核心的、低级的客户端库和对象的重新设计也引起了他们的关注

我的理念是绝对不要忽视单元测试(因为我们总是太忙了,而且它看起来总是有风险的,因此永远不会完成),并采取迭代的方法来实现单元测试

我很想听听这种情况的解决方案。我相信你们中的许多人都遇到过必须将单元测试添加到现有基础架构中的情况。单元测试如何能够在不影响生产率和发布周期的情况下迭代地添加到代码库中?

在这种情况下(事实上,我们已经经历了从旧webforms到MVC转换的相同过程),就是简单地开始测试新代码。随着时间的推移,旧代码最终将被重写或重构

在认为“新”代码有效之前,必须对其进行单元测试和代码审查。随着时间的推移,最终您会发现越来越多的解决方案正在接受测试,调用的旧代码也越来越少

我的经历:

  • 实现系统(端到端)测试的方法
  • 添加新功能时,请编写系统测试并使用单元测试设计新功能
  • 更改现有功能时,请事先编写系统测试
  • 不要试图重写现有模块,以便使用单元测试对其进行测试

  • 通过这种方式,您可以对新功能进行单元测试,并为旧功能创建一个(尽管范围很广)安全网。随着时间的推移,系统中越来越多的部分进行了系统测试,单元测试的覆盖率也越来越高(以百分比表示)。重新设计旧代码只是为了获得单元测试覆盖率是非常昂贵的。

    我支持您的首席开发人员。它有120万行代码,这意味着在测试和重新设计时有很大的出错空间。它不是为UT设计的,因此可能需要花费大量的精力来重写代码,以便对其进行测试。我相信单元测试会非常耗时。另外,它是一个旧产品,这可能意味着许多bug已经被发现并修复。如果它没有坏,就不要修理它。与测试和重构旧代码相比,您是否更愿意继续研究项目中更有趣的方面


    这就是说,如果我真的认为有必要这样做,我可能会在触摸它们的同时,为我触摸到的片段编写测试。如果我不碰它们,我就不会测试它们。

    我发现Michael Feathers在研究这个主题时很有用。

    在我看来,风险在于不进行单元测试……你不能改变过去,为什么不在对现有代码进行任何更改或添加新代码时创建新的测试框架呢?这并不完美,但随着时间的推移,随着您开始接触一些东西,测试套件将涵盖越来越多的代码。不过,仅仅为了更好地支持测试而重新设计遗留代码(即稳定的代码)可能会导致比它所解决的问题更多的问题,除非你正在重构它的一部分。有点好奇他们所感知到的风险是什么?找虫子?(说真的,我想他们最有可能认为代码没有bug,因为它已经运行了这么长时间,所以为什么要“浪费”时间编写测试以捕获很少的bug呢?)我肯定同意Jon的观点。@pickypg我认为风险在于实际上只为了方便测试而对代码进行更改。我不会为了更好地测试它而重构已经运行的那种规模的东西。更不用说可能要付出的巨大努力了。但我肯定会开始添加测试,并做任何需要的事情,以使它们在现有结构中工作。@jamietre我完全同意。在我工作的地方,我们有同样的方法。旧的、未经测试的产品不会为了单元测试而重写,但是当它们被重构时,单元测试就会被编写。类似地,所有新代码都有它。然而,这稍微暗示了风险与回报的关系包括整体的单元测试。仅仅为了测试而重写某些东西是愚蠢的(您可能会通过破坏预期行为引入您自己的bug),但是新代码当然应该有单元测试,而旧代码应该在重构时慢慢开始测试。我们是一致的这是我们在旧产品上所做的工作。新代码现在进行单元测试,旧代码在接触时进行单元测试。我喜欢这种反应,但我认为实现新代码测试系统的最大问题是,旧代码的某些部分至少需要重新设计,以支持测试框架。这是无法逃避的。这是一个巨大的障碍,除此之外,在我们“太忙”的发布日程安排下找到时间让球滚动是管理层/业务层的另一个挑战;预防风险是他们的命运。我听过的最好的论据是它加快了上市时间;最初,是的,有一个减速。但后来,当你不必担心意外的副作用时,它肯定会加速开发。