2016-02-27 114 views
0

我正在構建一個識別測試類的程序,並向編碼員提供了一個想法,與實際的源代碼相比,他編寫了多少測試代碼。我的問題是,儘管已經使用過測試類型,我該如何讓程序識別測試類?你可能會在測試課中找到什麼主要信號?它是@Test表示法?如果是的話如何處理呢?識別測試類的最佳方法?

這是一塊一類的代碼,我做了識別測試類:

public void walk(String path) throws FileNotFoundException { 
    int countFiles = 0; 
    File root = new File(path); 
    File[] list = root.listFiles(); 
    if (list == null) { 
     return; 
    } 

    for (File f : list) { 
     if (f.isDirectory()) { 
      walk(f.getAbsolutePath()); 
     } 

     if (f.getName().endsWith(".java")) { 

      System.out.println("File:" + f.getName()); 
       Scanner sc2 = new Scanner(f); 

      while (sc2.hasNextLine()) { 

       count++; 

       String str = sc2.nextLine(); 

       for (int i = 0; i < str.length(); i++) { 
        if(str.equals("@Test")){ 
        System.out.println("this a test clsee!"); 
       } 

但不幸的是我的想法是行不通的。那麼我能做什麼?

+0

爲什麼不工作你的想法? – Idos

+0

我不知道我沒有得到任何結果,即使我有幾個測試類,if語句是錯誤的或者條件不是最好的? (str.equals( 「@測試」)); –

+0

*我不知道*很少是很好的答案。如果您希望爲您的問題得到有意義的答案,請提供[mcve](http://stackoverflow.com/help/mcve)。 – Idos

回答

0
  1. 不要使用str.equals( 「@測試」),使用str.contains( 「@測試」)
  2. 還不錯,如果你檢查str.contains( 「org.testng」),STR .contains(「org.junit」),str.contains(「org.easymock」),str.contains(「org.mockito」)等等。

UPD:。例如,而不是代碼:

Scanner sc2 = new Scanner(f); 

while (sc2.hasNextLine()) { 

    count++; 

    String str = sc2.nextLine(); 

    for (int i = 0; i < str.length(); i++) { 
     if(str.equals("@Test")){ 
     System.out.println("this a test clsee!"); 

你應該使用代碼:

Scanner sc2 = new Scanner(f); 
    boolean flag = false; 
    while (sc2.hasNextLine() && !flag) { 
     String str = sc2.nextLine(); 
     if(str.contains("@Test")){ 
      flag = true; 
     } 
    } 
    if(flag) { 
     System.out.println("this a test clsee!"); 
    } 
+0

嗨!你的想法很有效,但是有一個小問題,現在我有一個小問題。現在我正在使用此代碼if(str.contains(「@ Test」)){System.out.println(「this is a test class」); } 可以說一個類有4種測試方法換句話說,如果你有4次測試它的打印四次!我能做些什麼才能讓它只打印一次? –

+0

我更新了我的答案 –

1

我知道這可能不是正是你要尋找的答案,但是讓我給你兩個另外的想法。

  1. 如果您正在使用mavengradle作爲構建工具,你應該在src/test/java文件夾中所有 你的測試類,無論如何,因此很容易 從你的產品代碼區分(位於 src/main/java夾)。其他工具可能具有相似的結構。 如果你的不是,你可能要考慮切換。

    一旦你有你的測試代碼,並在不同的文件夾 你生產代碼,你可以簡單地計算所有*.java文件夾的那些結構 內(或寫一個bat /慶典/任何腳本來爲你做它)。

  2. 由於測試代碼的純量並沒有真正告訴你有關你的實際test coverage任何東西,你可能要尋找一個工具,可以幫助你衡量這個覆蓋範圍和重點質量而非量您的測試的

    如果您使用的是Eclipse, EclEmma(這可能不是唯一一個,也不是最好的一個,而只是我正在使用的那個)。它爲Eclipse添加了新的啓動模式,然後您可以在覆蓋範圍模式下啓動您的單元測試。在這種模式下,EclEmma會記錄測試運行時正在執行的生產代碼的哪一行,從而讓您很好地瞭解代碼的哪些部分經過測試,哪些不是。它還計算一些統計數據,包括覆蓋的線條或分支的百分比,以幫助您識別薄弱點。

(我們至少快速解決您的代碼:從理論上講你的方法應該工作。在實踐中,它看起來像你應該閱讀在java中的字符串比較。這可能是值得一擊,以取代你的str.equals("@Test")迴路與一個簡單的str.contains("@Test")。)

+0

您的回答非常感謝!但也有100%的測試覆蓋率不會保證一個無錯的程序?對吧?:) 這就是爲什麼我試圖在我的研究中做到這一點!我的一個研究問題是兩個開發人員編寫的5000行程序足夠多的測試代碼是多少? ,我會嘗試通過分析一定數量的開源程序源代碼和測試代碼來找到答案! 我真的很喜歡你的答案隨時提出更多的想法! –

+0

對。 a)100%的測試覆蓋率並不告訴你所有的分支_combinations_正常工作,b)一旦你的邏輯變得越來越複雜,那麼你的測試代碼或者不正確或者只是測試廢話的可能性就會增加。不過,不知道詢問「多少測試代碼對於代碼行就足夠了」的確能夠很好地覆蓋那個話題。 – Marvin

0

我不知道這是你在找什麼。獲取文件名後,請按照以下步驟操作。

Classfile.class.getMethods() 

通過迭代方法陣列和檢查註記類

method.getAnnotation(Test.class) 

正如其他人認爲它總是一個更好的做法不是俱樂部與企業代碼測試類。

我在這裏添加了完整的代碼片段。

公共類ClassFinder {

private static final char PKG_SEPARATOR = '.'; 

private static final char DIR_SEPARATOR = '/'; 

private static final String CLASS_FILE_SUFFIX = ".class"; 

private static final String BAD_PACKAGE_ERROR = "Unable to get resources from path '%s'. Are you sure the package '%s' exists?"; 

public static List<Class<?>> find(String scannedPackage) { 
    String scannedPath = scannedPackage.replace(PKG_SEPARATOR, DIR_SEPARATOR); 
    URL scannedUrl = Thread.currentThread().getContextClassLoader().getResource(scannedPath); 
    if (scannedUrl == null) { 
     throw new IllegalArgumentException(String.format(BAD_PACKAGE_ERROR, scannedPath, scannedPackage)); 
    } 
    File scannedDir = new File(scannedUrl.getFile()); 
    List<Class<?>> classes = new ArrayList<Class<?>>(); 
    for (File file : scannedDir.listFiles()) { 
     classes.addAll(find(file, scannedPackage)); 
    } 
    return classes; 
} 

private static List<Class<?>> find(File file, String scannedPackage) { 
    List<Class<?>> classes = new ArrayList<Class<?>>(); 
    String resource = scannedPackage + PKG_SEPARATOR + file.getName(); 
    if (file.isDirectory()) { 
     for (File child : file.listFiles()) { 
      classes.addAll(find(child, resource)); 
     } 
    } else if (resource.endsWith(CLASS_FILE_SUFFIX)) { 
     int endIndex = resource.length() - CLASS_FILE_SUFFIX.length(); 
     String className = resource.substring(0, endIndex); 
     try { 
      classes.add(Class.forName(className)); 
     } catch (ClassNotFoundException ignore) { 
     } 
    } 
    return classes; 
} 

public static void main(String[] args) { 
    List<Class<?>> classes = ClassFinder.find("com.vijay.junitapp4"); 
    Method[] methods = null; 
    for (Class<?> class1 : classes) { 
     methods = class1.getMethods(); 
     Test test = null; 
     for (int j = 0; j < methods.length; j++) { 
      test = methods[j].getAnnotation(Test.class); 
      if(null != test){ 
       System.out.println("we found a teat case"); 
       break; 
      } 
     } 
    } 
} 

}

+0

我真的不確定如果我得到你的想法,可能請描述更多? –

+0

你得到的文件名是字符串,因此將其轉換爲類文件,我需要使用Class.forName(「<類的完全限定名稱>」)。 我正在提供的代碼片段,我從http://stackoverflow.com/questions/15519626/how-to-get-all-classes-names-in-a-package 感謝作者。 –