繁体   English   中英

确定哪些测试用例涵盖了一种方法

[英]Determining which test cases covered a method

我正在从事的当前项目要求我编写一个工具,该工具可以在Web应用程序上运行功能测试,并输出方法覆盖率数据,记录哪个测试用例遍历了哪个方法。

详细信息:被测试的Web应用程序将是在servlet容器(例如Tomcat)中运行的Java EE应用程序。 功能测试将使用JUnit用Selenium编写。 一些方法将被注释,以便在部署到测试环境之前对其进行检测。 执行Selenium测试后,将记录带注释的方法的执行。

问题 :该项目的最大障碍是找到一种方法,将测试用例的执行与方法的遍历相关联,特别是测试和应用程序在不同的JVM上运行,并且无法传递测试的名称降低应用程序性能,并且无法使用线程信息将测试与代码执行相关联。

建议的解决方案:我的解决方案将包括执行时间:我扩展了JUnit框架以记录执行测试用例的时间,并且对应用程序进行检测,从而节省了遍历该方法的时间。 而且,我尝试使用相关性将测试案例与方法覆盖率关联起来。

预期的问题:此解决方案假定测试用例是按顺序执行的,并且一个测试用例在下一个测试用例开始之前已结束。 这个假设对JUnit合理吗?

问:简单地说,我是否可以就建议的解决方案提供您的意见,或者就如何改进大多数Java EE应用程序使其更健壮和更有效地提出建议? 还是导致已经实施的解决方案?

谢谢

编辑 :要添加更多要求,该工具应该能够在任何Java EE应用程序上运行,并且需要最少的配置或更改应用程序。 虽然我知道这不是一个现实的要求,但是该工具至少应该不需要对应用程序本身进行任何大的修改,例如添加类或代码行。

您是否看过现有的报道工具(Cobertura,Clover,Emma等)。 我不确定其中之一是否能够将coverage数据链接到测试用例,但是至少使用开源的Cobertura,您也许可以执行以下操作:

  • 与cobertura一起上课
  • 部署检测的Web应用
  • 开始测试套件
    • 每次测试后,调用Web应用程序上的URL,该URL将coverage数据保存到以刚刚运行的测试命名的文件中,并重置coverage数据
  • 在测试套件之后,为每个保存的文件生成一个cobertura报告。 每个报告将告诉测试已经运行了哪些代码

如果您需要合并的报告,我想使用cobertura API从保存的文件集生成报告应该不会太难。

您提出的解决方案似乎是一个合理的解决方案,除了提出的解决方案按时间将测试和请求相关联。 我以前尝试过做这种事情,并且它有效。 大多数时候。 除非您非常仔细地编写JUnit代码,否则,由于两台计算机之间的时间差异,或者如果您只有一台计算机,而一次匹配另一台计算机,则会遇到很多问题。

更好的解决方案是实现Tomcat Valve ,您可以将其插入Webapp的server.xml的生命周期中。 Valve的优势在于您可以在server.xml中定义它们,因此您完全不需要接触Web应用程序。

您将需要实现invoke()。 最好的起点可能是AccessLogValve 这是AccessLogValve中的实现:

/**
 * Log a message summarizing the specified request and response, according
 * to the format specified by the <code>pattern</code> property.
 *
 * @param request Request being processed
 * @param response Response being processed
 *
 * @exception IOException if an input/output error has occurred
 * @exception ServletException if a servlet error has occurred
 */
public void invoke(Request request, Response response) throws IOException,
        ServletException {

    if (started && getEnabled()) {                
        // Pass this request on to the next valve in our pipeline
        long t1 = System.currentTimeMillis();

        getNext().invoke(request, response);

        long t2 = System.currentTimeMillis();
        long time = t2 - t1;

        if (logElements == null || condition != null
                && null != request.getRequest().getAttribute(condition)) {
            return;
        }

        Date date = getDate();
        StringBuffer result = new StringBuffer(128);

        for (int i = 0; i < logElements.length; i++) {
            logElements[i].addElement(result, date, request, response, time);
        }

        log(result.toString());
    } else
        getNext().invoke(request, response);       
}

所有这一切都记录您已访问它的事实。

您将实施一个新的Valve。 对于您的请求,您传递唯一的ID作为URL的参数,该ID用于标识您正在运行的测试。 您的阀门将在invoke()之前和之后进行所有繁重的工作。 如果需要,可以删除删除getNext()。invoke()的唯一参数。

要衡量覆盖率,您可以根据传递的唯一ID,使用JB Nizet建议的覆盖率工具。

因此,如果您最初的电话是

@Test void testSomething() {
    selenium.open("http://localhost/foo.jsp?bar=14");
}

您可以将其更改为:

@Test void testSomething() {
    selenium.open("http://localhost/foo.jsp?bar=14&testId=testSomething");
}

然后,您将在阀中选取参数testId。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM