簡體   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