我应该把我的测试代码放在哪个班级?

时间:2009-10-24 15:00:05

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

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

有关组织测试代码的最佳做法是什么?

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

10 个答案:

答案 0 :(得分:4)

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

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

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

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

测试项目通常包含一个静态类init方法,一个静态类拆除方法,一个用于所有测试的非静态init方法,一个用于所有测试的非静态拆除方法和一个每个测试的非静态方法+任何你添加的其他方法。

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

答案 1 :(得分:3)

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

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

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

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

答案 2 :(得分:2)

在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还要求在部署项目之前通过所有测试。

答案 3 :(得分:1)

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

随着测试的进行,我看到了单独测试,集成测试和回归测试的单独项目。其中一个主要思想是尽可能快地运行单元测试。整合&由于测试的性质(连接到数据库等等),回归测试往往需要更长的时间。

答案 4 :(得分:1)

我通常在同一个项目中的不同源代码树中创建并行包结构。这样你的测试就可以访问被测试类的public,protected甚至是package-private成员,这通常很有用。

例如,我可能有

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有关。

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

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

答案 8 :(得分:0)

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

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

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

答案 9 :(得分:0)

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

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

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

但是提示#1:要分开各种测试是很难的。特别要确保将单元测试集合与集成测试分开。