2014-04-22 26 views
1

我有一個自定義測試運行器,用於運行我的一部分測試,以便我可以在不同的jenkins節點上分發測試。如果我所有的集成測試都運行了,則需要一個小時。所以我有三臺服務器運行三分之一的測試,這隻需要20分鐘。這裏是我的浴室外觀:當我有一個使用@RunWith的測試套件時,如何獲得更多的日誌記錄反饋?

import junit.framework.JUnit4TestAdapter; 
import junit.framework.TestSuite; 
import org.junit.Ignore; 
import org.junit.extensions.cpsuite.ClassesFinder; 
import org.junit.extensions.cpsuite.ClasspathFinderFactory; 
import org.junit.extensions.cpsuite.SuiteType; 
import org.junit.runner.RunWith; 
import org.junit.runners.AllTests; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.List; 

@RunWith(AllTests.class) 
public class DistributedIntegrationTestRunner { 

    private static Logger log = LoggerFactory.getLogger(DistributedIntegrationTestRunner.class); 

    public static TestSuite suite() { 
     TestSuite suite = new TestSuite(); 

     ClassesFinder classesFinder = new ClasspathFinderFactory().create(true, 
       new String[]{".*IntegrationTest.*"}, 
       new SuiteType[]{SuiteType.TEST_CLASSES}, 
       new Class[]{Object.class}, 
       new Class[]{}, 
       "java.class.path"); 

     int nodeNumber = systemPropertyInteger("node.number", "0"); 
     int totalNodes = systemPropertyInteger("total.nodes", "1"); 

     List<Class<?>> allTestsSorted = getAllTestsSorted(classesFinder); 
     allTestsSorted = filterIgnoredTests(allTestsSorted); 
     List<Class<?>> myTests = getMyTests(allTestsSorted, nodeNumber, totalNodes); 
     log.info("There are " + allTestsSorted.size() + " tests to choose from and I'm going to run " + myTests.size() + " of them."); 
     for (Class<?> myTest : myTests) { 
      log.info("I will run " + myTest.getName()); 
      suite.addTest(new JUnit4TestAdapter(myTest)); 
     } 

     return suite; 
    } 

    private static int systemPropertyInteger(String propertyKey, String defaultValue) { 
     String slaveNumberString = System.getProperty(propertyKey, defaultValue); 
     return Integer.parseInt(slaveNumberString); 
    } 

    private static List<Class<?>> filterIgnoredTests(List<Class<?>> allTestsSorted) { 
     ArrayList<Class<?>> filteredTests = new ArrayList<Class<?>>(); 
     for (Class<?> aTest : allTestsSorted) { 
      if (aTest.getAnnotation(Ignore.class) == null) { 
       filteredTests.add(aTest); 
      } 
     } 
     return filteredTests; 
    } 

    /* 
    TODO: make this algorithm less naive. Sort each test by run duration as described here: http://blog.tradeshift.com/just-add-servers/ 
    */ 
    private static List<Class<?>> getAllTestsSorted(ClassesFinder classesFinder) { 
     List<Class<?>> allTests = classesFinder.find(); 
     Collections.sort(allTests, new Comparator<Class<?>>() { 
      @Override 
      public int compare(Class<?> o1, Class<?> o2) { 
       return o1.getSimpleName().compareTo(o2.getSimpleName()); 
      } 
     }); 
     return allTests; 
    } 

    private static List<Class<?>> getMyTests(List<Class<?>> allTests, int nodeNumber, int totalNodes) { 
     List<Class<?>> myTests = new ArrayList<Class<?>>(); 

     for (int i = 0; i < allTests.size(); i++) { 
      Class<?> thisTest = allTests.get(i); 
      if (i % totalNodes == nodeNumber) { 
       myTests.add(thisTest); 
      } 
     } 

     return myTests; 
    } 
} 

這種類型的作品,除了當我嘗試在不同的模塊使用多DistibutedIntegrationTestRunners和一次,「事情不工作」運行它們。通常情況下,我不會在SO上張貼含糊不清的投訴,但很難找出更多,因爲此代碼沒有給出太多反饋。這是唯一的記錄,我得到:

 log.info("There are " + allTestsSorted.size() + " tests to choose from and I'm going to run " + myTests.size() + " of them."); 
     for (Class<?> myTest : myTests) { 
      log.info("I will run " + myTest.getName()); 

出現這種情況的運行測試的任何之前。如果我能得到更多的日誌記錄,這將是非常有用的。例如,如果我可以在測試運行之前打印出「我即將運行FooTest」右邊,這將非常有用。有沒有辦法做到這一點?

我已經瀏覽了源代碼並看到在org.junit.internal.runners.JUnit38ClassRunner中有一個名爲private final RunNotifier fNotifier;的字段,但我不確定如何掛鉤,或者如果我要朝正確的方向行進。

我正在使用JUnit 4.10,但我可以根據需要進行升級。

+0

之前運行 - 這聽起來像方面的工作.. –

+0

@LeosLiterak我不明白你想告訴我什麼。 –

+0

縱橫技術可以幫助你完成這項任務嗎? –

回答

0

這對我來說看起來像一個XY問題。

日誌文件不用於測試。它們用於監視調試。一旦你有一個失敗的測試案例,你需要從思考測試轉向考慮調試。這意味着單獨運行失敗的測試用例,也許使用調試器。

如果您的測試失敗並顯示無用的失敗消息,則表明您的低級測試覆蓋率較差,或者測試用例的診斷消息較差。

+0

它們*僅*在由測試運行器運行時失敗。這些測試從客戶端運行到服務器。出於安全原因,服務器不給我堆棧跟蹤。 –

相關問題