【问题标题】:where should I put my test code for my class?我应该把我的课程的测试代码放在哪里?
【发布时间】:2009-10-24 15:00:05
【问题描述】:

所以我已经编写了一个类并且我有代码来测试它,但是我应该把那个代码放在哪里呢?我可以为该类创建一个静态方法 Test(),但这在生产期间不需要存在并且会使类声明混乱。一些搜索告诉我将测试代码放在一个单独的项目中,但该项目的格式究竟是什么?一个静态类,每个类都有一个方法,所以如果我的类被称为 Randomizer,该方法将被称为 testRandomizer?

关于组织测试代码有哪些最佳实践?

编辑:我最初用多种我认为相关的语言标记了该问题,但似乎该问题的总体答案可能是“使用测试框架”,这是特定于语言的。 :D

【问题讨论】:

  • 你在使用测试框架吗?也许是 JUnit?
  • 不,我只是写了一些代码,以确保我的 Randomizer 为我提供了我想要的随机数的分布。但是我对 JUnit 不是很有经验,并且很想听听任何关于它如何工作的建议,如果它与问题相关,它会帮助测试过程。 :D
  • JUnit 及其等价物非常有用。单个类可能需要许多测试以确保其正常工作,并且每次修改代码时都应执行这些测试。您是否要在每次构建时手动运行所有测试?可能不是。 JUnit 自动执行这些测试。

标签: c# java c++ unit-testing


【解决方案1】:

无论您是否使用测试框架(我强烈建议您这样做),单元测试的最佳位置是在单独的程序集 (C/C++/C#) 或包 (Java) 中。

您将只能访问公共和受保护的类和方法,但是单元测试通常只测试公共 API。

我建议您为每个现有项目/程序集/包添加一个单独的测试项目/程序集/包。

项目的格式取决于测试框架 - 对于 .NET 测试项目,使用 VS 内置的测试项目模板或您的版本中的 NUnit VS 不支持单元测试,对于 Java 使用 JUnit,对于 C/ C++ 可能是 CppUnit(这个我没试过)。

测试项目通常包含一个静态类初始化方法、一个静态类拆卸方法、一个用于所有测试的非静态初始化方法、一个用于所有测试的非静态拆卸方法和一个非静态方法每个测试+任何您添加的其他方法。

静态方法让您复制 dll、设置测试环境和清理测试环境,非静态共享方法用于减少重复代码,实际测试方法用于准备特定于测试的输入、预期输出和比较它们。

【讨论】:

    【解决方案2】:

    您将测试代码放在哪里取决于您打算如何处理这些代码。如果它是一个独立的类,例如,您打算让其他人可以下载和使用,那么测试代码应该是解决方案中的一个项目。测试代码除了提供对类正在执行您希望它执行的操作的验证之外,还为您的类的用户提供了一个示例,因此它应该是有据可查且非常清晰的。

    另一方面,如果您的类是库或 DLL 的一部分,并且只能在该库或 DLL 的生态系统中工作,那么应该有一个测试程序或框架将 DLL 用作实体。代码覆盖工具将证明测试代码实际上是在执行代码。以我的经验,这些测试程序就像单类程序一样,被构建为构建 DLL 或库的解决方案中的一个项目。

    请注意,在上述两种情况下,测试项目都不是标准构建过程的一部分。您必须专门构建它。

    最后,如果您的课程要成为更大项目的一部分,您的测试代码应该成为为您更大的团队定义的任何框架或流程的一部分。例如,在我当前的项目中,开发人员单元测试维护在一个单独的源代码控制树中,该树的结构与交付代码的结构平行。单元测试需要通过开发和测试团队的代码审查。在构建过程中(现在每隔一天),我们构建交付代码,然后是单元测试,然后是 QA 测试代码集。单元测试在 QA 代码之前运行,所有测试都必须通过。这几乎是一个冒烟测试,以确保我们没有破坏最低级别的功能。需要单元测试来生成失败报告并以否定状态代码退出。不过,我们的流程可能比许多流程更正式。

    【讨论】:

      【解决方案3】:

      在 Java 中,您应该单独使用 Junit4,或者(我认为更好)与 IDE 一起使用。我们使用了三种环境:Eclipse、NetBeans 和 Maven(有和没有 IDE)。如果没有系统地部署,它们之间可能会有一些轻微的不兼容。

      通常所有测试都在同一个项目中,但在不同的目录/文件夹下。因此一个类:

      org.foo.Bar.java
      

      会进行测试

      org.foo.BarTest.java
      

      它们在同一个包 (org.foo) 中,但会被组织在目录中:

      src/main/java/org/foo/Bar.java 
      

      src/test/java/org/foo/BarTest.java 
      

      这些目录被 Eclipse、NetBeans 和 Maven 普遍识别。 Maven 是最挑剔的,而 Eclipse 并不总是严格执行。

      您可能应该避免调用其他类 TestPlugh 或 XyzzyTest,因为一些(旧)工具会将它们作为包含测试来选择,即使它们没有。

      即使您的方法只有一个测试(并且大多数测试机构希望更多地练习边缘案例),您也应该安排这种类型的结构。

      编辑请注意,即使它们在同一个包中,Maven 也能够在没有测试的情况下创建发行版。默认情况下,Maven 还要求在部署项目之前通过所有测试。

      【讨论】:

        【解决方案4】:

        我见过或使用的大多数设置都有一个单独的项目,其中包含测试。这使它更容易和更清洁的工作。作为一个单独的项目,您可以轻松部署代码,而不必担心测试是实时系统的一部分。

        随着测试的进展,我看到了单元测试、集成测试和回归测试的单独项目。这样做的主要想法之一是让您的单元测试尽可能快地运行。由于测试的性质(连接到数据库等),集成和回归测试往往需要更长的时间

        【讨论】:

          【解决方案5】:

          我通常在同一项目的不同源代码树中创建并行包结构。这样,您的测试就可以访问被测类的公共、受保护甚至包私有成员,这通常很有用。

          例如,我可能有

          myproject
              src
                  main
                      com.acme.myapp.model
                          User
                      com.acme.myapp.web
                          RegisterController
                  test
                      com.acme.myapp.model
                          UserTest
                      com.acme.myapp.web
                          RegisterControllerTest
          

          Maven 会这样做,但这种方法与 Maven 并没有特别的联系。

          【讨论】:

          • 只是因为我不希望测试具有包访问权限,所以我们使用相同的模型,但是测试中的包名是从要测试的类的包名中派生的,通过替换 @987654322 @ 前缀为 test. 这样很容易创建一个应用程序 jar 和一个带有测试类的 jar,同时没有将测试类放在 .test 子包中的缺点。
          【解决方案6】:

          这取决于您使用的测试框架。 JUnit、NUnit 还是其他?每个人都会记录一些组织测试代码的方法。此外,如果您使用的是持续集成,那么这也会影响您放置测试的位置和方式。例如,this article 讨论了一些选项。

          【讨论】:

            【解决方案7】:

            在与您的代码相同的解决方案中创建一个新项目。

            如果您使用的是 c#,那么如果您选择“测试”>“新建测试”,那么 Visual Studio 将为您执行此操作...它有一个向导可以指导您完成整个过程。

            【讨论】:

              【解决方案8】:

              嗯。你想测试随机数生成器......可能会更好地创建算法正确性的强大数学证明。因为否则,您必须确保生成的每个序列都具有所需的分布

              【讨论】:

              • 我关心的是在哪里放置/如何处理测试代码,而不是如何测试
              • 哦,我误解了你的问题,对不起。
              【解决方案9】:

              为单元测试、集成测试和功能测试创建单独的项目。即使您的“真实”代码有多个项目,您也可以为每种测试类型使用一个项目,但区分每种测试类型很重要。

              对于单元测试,您应该创建一个并行的命名空间层次结构。所以如果你有 crazy.juggler.drummer.Customer,你应该在 crazy.juggler.drummer.CustomerTest 中对它进行单元测试。这样就很容易看出哪些类被正确测试了。

              功能测试和集成测试可能更难放置,但通常您可以找到合适的位置。数据库层的测试可能属于 my.app.database.DatabaseIntegrationTest 之类的地方。功能测试可能需要自己的命名空间:my.app.functionaltests.CustomerCreationWorkflowTest。

              但是提示 #1:严格区分各种测试。尤其要确保将单元测试的集合与集成测试分开。

              【讨论】:

                【解决方案10】:

                对于 C# 和 Visual Studio 2010,您可以创建一个 test project from the templates,它将包含在您的项目解决方案中。然后,您将能够指定在构建项目期间要触发哪些测试。所有测试都将存在于单独的程序集中。

                否则,您可以使用NUnit Assembly,将其导入您的解决方案并开始为您需要测试的所有对象创建方法。对于更大的项目,我更喜欢将这些测试放在单独的程序集中。

                您可以生成自己的测试,但我强烈建议您使用现有框架。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2010-10-23
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-02-27
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多