【问题标题】:An example of unit testing in C#?C# 中的单元测试示例?
【发布时间】:2016-02-12 18:12:08
【问题描述】:

究竟什么是单​​元测试,我该如何编写?我听到很多次人们甚至在他们的应用程序编写之前就编写了它们,这怎么可能?我的印象是,单元测试是一些代码,它使用设定值调用应用程序的方法,并期望返回特定值,如果特定值没有返回,则测试失败。我在这里错了还是误导了?我阅读了很多关于单元测试的内容,但我对它在代码中的实际外观知之甚少,所以一个示例会很棒。

这是单元测试吗?

开始伪代码...

CheckForDuplicateSubdomains(){
  get all users in DB with matching subdomains
  if greater than zero, fail test
}

PS:我在 C# 中使用 ASP.NET MVC

【问题讨论】:

标签: asp.net-mvc unit-testing


【解决方案1】:

您对单元测试的看法是正确的。这个想法是用不同的输入一个一个地测试你的所有功能,以确保它们像你期望的那样工作(而不是在它们被插入应用程序之后才发现......然后使测试更加复杂)。

在编写函数之前编写单元测试是一种称为“测试驱动开发”的方法的一部分。您仅在其中编写函数的骨架,然后首先编写所有单元测试。所以一开始你所有的测试都会失败(b/c这个功能还没有被编程)。之后,您对函数进行编程,直到所有测试都通过。

【讨论】:

  • TDD 涉及编写单个单元测试,然后编写使其通过的代码,然后重构该代码以清理它,最后重复一个新的单元测试。你不会写一堆测试,然后是你似乎暗示的一堆代码。
  • 我不认为 TDD 会阻止一次编写多个测试,尽管也许我对这件事一无所知。例如,如果函数必须做两件事——例如,将一行插入数据库并返回行号,该怎么办。这可能需要两个测试,一个测试输入的行,第二个测试显示行号是否正确。当然,您可以在一个测试中同时进行这两个验证,但在这一点上,我们正在对组成单个测试的定义进行区分。
  • Ref: agileinaflash.blogspot.com/2009/07/… 你只写了足够多的测试来获得失败,然后只有足够的代码让它通过,然后足够让另一个失败。将其视为编写规范,然后编写足够的代码来满足规范。当您看到代码时,您会意识到您需要一个更好的规范,并且每个规范都会导致更好的代码。最后,测试会显示您考虑过的所有案例,并且对于下一个人来说是很好的阅读材料。
【解决方案2】:

是的,您的示例将是一个单元测试。首先创建测试有几个原因。首先,它充当您项目的活文档。它建立了行为和预期结果,这应该可以帮助您实际实现您的代码(编写一些东西更容易,知道它需要做什么以及基本上它是如何启动的)。其次,如果你在之后编写测试,你更有可能编写一个与你已经编写的代码一起工作的测试,这对你没有帮助。定义一个代码单元需要做什么,编写测试,并编写/修复代码以反映测试中的行为。随着您的应用程序的发展,这种策略会转化为更好的理解和质量。

【讨论】:

    【解决方案3】:

    单元测试是对一小部分代码进行测试的测试,通常是一个方法(确切地说是一个单元)。

    在 TDD 中,开发人员能够在编写方法之前编写单元测试,因为他们已经知道代码单元应该做什么。不管它是如何工作的……测试只是确保结果是正确的。

    并且该伪代码可以用作单元测试(不确定它会测试什么,但我不得不假设您正在测试一个不应返回重复子域的方法)。

    理论上,单元测试(和测试驱动开发)应该通过确保每个代码单元完全按照预期执行,从而进一步缓解令人头疼的问题。

    【讨论】:

      【解决方案4】:

      单元测试是单元级别的自动化测试。通过单元级别,它们表示原子代码单元,因此您无法进一步分解它。功能或对象的特定部分。平方函数的单元测试看起来像

       assertEqual(4, square(2));
       assertEqual(4, square(-2));
       assertEqual(0, square(0));
      

      现在你一旦决定了square的接口就可以写这个,对于更复杂的函数你可以通过测试通过的次数来衡量完成函数的接近程度。

      【讨论】:

        【解决方案5】:

        我的印象是,单元测试是一些代码,它使用设定值调用应用程序的方法并期望返回特定值,如果特定值未返回,则测试失败.我在这里错了还是误导了?

        不,你完全正确。

        单元测试最重要的是尽可能测试一小段代码。

        在您的示例中,您从数据库中获取一些信息,然后计算项目数...如果您的方法失败,您将永远无法确切知道哪里出了问题,因为有太多可能出错的地方... .

        您的数据库连接可能丢失,sql 无效,...

        如果你使用的是 asp.net MVC,你应该比使用普通的 asp.net 更容易编写单元测试

        【讨论】:

          【解决方案6】:

          xUnit 系列框架中有非常完善的单元测试约定,最初源自 jUnit。在该框架中,断言是进行测试的主要工具。在测试套件中,目标是确保 100% 的断言是正确的。

          考虑你的例子。

          CheckForDuplicateSubdomains(){
            get all users in DB with matching subdomains
            if greater than zero, fail test
          }
          

          这个测试通常有一个以“test”开头的名字,这让框架的测试运行器知道这个函数是一个测试而不是一个设置方法,比如说。重要的是要明确我们正在测试代码的行为,而不是数据的状态

          testNoDuplicateSubdomains(){
          }
          

          在每个测试中,都有four phases

          • 夹具设置,
          • 练习 SUT,
          • 结果验证和
          • 夹具拆卸。

          SUT 是“被测系统”,通常是生产代码中类的一种方法。

          testNoDuplicateSubdomains(){
            // fixture setup
            prepareDatabaseTestData()
            // exercise SUT, 
            SUT = new ProductionObject()
            result = SUT.getAllUsersWithMatchingSubDomains()
            // result verification and 
            assertEmpty(result) // or whatever makes sense
            // fixture teardown.  
            removeDatabaseTestData()
          }
          

          与许多软件开发技术一样,编写单元测试需要一段时间才能获得经验。学习最佳实践的好资源是 Gerard Meszaros 的 xUnit Test Patterns

          【讨论】:

          • OP 的示例 CheckForDuplicateSubdomains() 似乎存在误解,因为它似乎倾向于验证某些数据的状态而不是某些代码块的行为。尽管我已将其带入我修改后的示例中,但我相信讨论仍然提供了丰富的信息。顺便说一句,我建议初学者更喜欢在不靠近数据库的一段代码中获得构建单元测试的经验。代码-数据库接口是单元测试中出了名的麻烦。
          猜你喜欢
          • 2012-11-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-27
          • 1970-01-01
          相关资源
          最近更新 更多