代码之家  ›  专栏  ›  技术社区  ›  corgrath

如何在Java应用程序内部运行JUnit测试?

  •  48
  • corgrath  · 技术社区  · 16 年前

    从Java应用程序内部运行JUnit测试是可能的吗?

    有没有可以使用的测试框架(比如junit.jar?),还是强制我自己查找测试文件、调用方法和跟踪异常?

    我之所以问这个问题,是因为我的应用程序需要很多工作才能启动(很多依赖项和配置等),而使用外部测试工具(如junit ant task)则需要很多工作才能设置。

    更容易启动应用程序,然后在应用程序内部运行我的测试。

    是否有一个简单的测试框架来运行Java应用程序内部的测试和输出结果,或者我被迫编写自己的框架吗?

    6 回复  |  直到 7 年前
        1
  •  81
  •   kopper    16 年前

    是的,你可以。我在生产系统中运行了几次诊断/烟雾测试。这是调用junit的代码的关键部分:

    JUnitCore junit = new JUnitCore();
    Result result = junit.run(testClasses);
    

    不要使用 JUnit.main 在应用程序内部,它调用 System.exit 测试完成后,它可能会停止jvm进程。

    您可能想要捕获junit的“常规”控制台输出(dots和simple report)。这可以通过注册轻松完成 TextListener (这个类提供这个简单的报告)。

    请注意使用这种方法的几种并发症:

    1. 测试任何“测试框架”,包括这么小的一个,虽然很简单,但可能会令人困惑。例如,如果您想测试“测试框架”是否在其中一个测试失败时返回失败结果,您可以(应该?)创建总是失败的示例junit测试,并使用“测试框架”执行该测试。在这种情况下,失败的测试用例实际上是测试数据,不应该作为“普通”junit执行。对于此类测试的示例,可以参考junit的内部测试用例。

    2. 如果您想准备/显示自定义报表,您应该注册自己的报表 RunListener ,因为JUnit返回的结果不包含(直接)关于通过的测试和测试方法的信息(它只是作为测试的一部分“硬编码 Description )

        2
  •  13
  •   Tomislav Nakic-Alfirevic    16 年前

    如junit中所述 FAQ :

    public static void main(String args[]) {
      org.junit.runner.JUnitCore.main("junitfaq.SimpleTest");
    }
    
        3
  •  10
  •   seanhodges    16 年前

    我问的原因是 申请需要做很多工作 开始启动(许多依赖项和 配置等)并使用 外部测试工具(如junit ant 任务)将需要大量的工作 设置。

    您需要从正在测试的代码中删除这些依赖项。在编写测试框架时,依赖项和配置正是您试图避免的。对于每个测试,您应该针对应用程序中最小的可测试部分。

    例如,如果需要数据库连接来执行类中的某个进程,则尝试测试-将数据库处理对象与类分离,通过构造函数或setter方法将其传入,并在测试中使用jmock(或编写存根类)之类的工具来构建假数据库。处理对象。这样您就可以确保测试不依赖于特定的数据库配置,并且只测试您感兴趣的代码的一小部分,而不是整个数据库处理层。

    一开始看起来可能需要做很多工作,但这种重构正是您的测试框架应该充实的内容。您可能会发现,获得一本关于软件测试的书作为分离依赖关系的参考很有用。它的回报将远远超过试图从运行中的应用程序内部引导junit。

        4
  •  3
  •   makson    8 年前

    在JUnit5中你可以使用 Launcher API 为了这个目标。

        final LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
                .selectors(
                        selectPackage("path_to_folder_with_tests")
                )
                .build();
    
        final Launcher launcher = LauncherFactory.create();
    
        final boolean pathContainsTests = launcher.discover(request).containsTests()
        if (!pathContainsTests) {
            System.out.println("This path is invalid or folder doesn't consist tests");
        }
    
        final SummaryGeneratingListener listener = new SummaryGeneratingListener();
    
        launcher.execute(request, listener);
    
        final TestExecutionSummary summary = listener.getSummary();
    
        final long containersFoundCount = summary.getContainersFoundCount();
        System.out.println("containers Found Count  " + containersFoundCount);
    
        final long containersSkippedCount = summary.getContainersSkippedCount();
        System.out.println("containers Skipped Count  " + containersSkippedCount);
    
        final long testsFoundCount = summary.getTestsFoundCount();
        System.out.println("tests Found Count  " + testsFoundCount);
    
        final long testsSkippedCount = summary.getTestsSkippedCount();
        System.out.println("tests Skipped Count  " + testsSkippedCount);
    
        5
  •  2
  •   corgrath    16 年前

    根据JUnit API,JUnitCore有几种在Java内部执行测试的方法。

    感谢汤米斯拉夫·纳基克·阿尔菲雷维奇的指点。

    http://junit.sourceforge.net/javadoc/org/junit/runner/JUnitCore.html

        6
  •  1
  •   Raffi Khatchadourian    7 年前