2014-04-19 54 views
1

我有一個java類,它包含一些關於整數數組中二分搜索的方法。 現在我應該創建一個新類來驗證這些方法的正確性,用不同的數組和不同的元素來測試這些方法。 現在,我以「標準」方式完成了這個新的測試類,但我知道我可以使用JUnit。 我在網上搜索了一些簡單的指南,但我並沒有太多瞭解。關於JUnit的疑問和建議

例如,如果我的班 「主力」 BinarySearch.java這樣製成:

public class BinarySearch { 

    private BinarySearch() { } 

    public static int find(int x, int[] a) { 
     int i = 0; 
     int inf = 0; 
     int sup = a.length - 1; 
     if(sup == -1 || x < a[0] || x > a[sup]) 
      return -1; 
     while(inf <= sup) { 
      i = (inf + sup) >>> 1; 
      if(x < a[i]) 
       sup = i - 1; 
      else if(x > a[i]) 
       inf = i + 1; 
      else 
       return i; 
     } 
     return -1; 
    } 

    public static boolean isPresent(int x, int[] a) { 
     int i = 0; 
     int inf = 0; 
     int sup = a.length - 1; 
     if(sup == -1 || x < a[0] || x > a[sup]) 
      return false;  
     while(inf <= sup) { 
      i = (inf + sup) >>> 1; 
      if(x < a[i]) 
       sup = i - 1; 
      else if (x > a[i]) 
       inf = i + 1; 
      else 
       return true; 
     } 
     return false; 
    } 

    public static void sort(int[] a) { 
     int b, c; 
     int temp; 
     int s = a.length - 1; 
     for(b = 0; b < s; ++b) { 
      for(c = 0; c < s; ++c) { 
       if(a[c] < a[c + 1]) { 
        temp = a[c]; 
        a[c] = a[c + 1]; 
        a[c + 1] = temp; 
       } 
      } 
     } 
    } 


    public static boolean isSorted(int[] a) { 
     for(int i = 0; i < a.length-1; i++) { 
      if(a[i] > a[i + 1]) { 
       return false; 
      } 
     } 
     return true;   
    } 

    public static void isort(int a[]) { 
     for(int i = 1; i < a.length; i++){ 
      int j = i; 
      int b = a[i]; 
      while(j > 0 && a[j - 1] > b) { 
       a[j] = a[j - 1]; 
       j--; 
      } 
      a[j] = b; 
     } 
    }  

} 

測試類 「標準」 是:

public class BinarySearchTestSuite { 

    private BinarySearchTestSuite() {} 

    static int tot = 0; 
    static int pass = 0; 
    static int nonPass = 0; 
    static int ecc = 0; 

    public static void main(String[] args) { 

     int[] a1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
     int[] a2 = {}; 

     int x1 = 5; 
     int x2 = 0; 
     int x3 = 10; 

     System.out.println(); 
     System.out.println("---- Test method find ----"); 

     //Test n.1  
     try { 
      tot++; 
      System.out.print("Test n.1 - Array: [ "); 
      for(int i = 0; i < a1.length; i++) 
       System.out.print(a1[i] + " "); 
      System.out.println("]. Element to find: " + x1 + "."); 
      if(a1[BinarySearch.find(x1, a1)] == x1) { 
       System.out.println(x1 + " is in position " + BinarySearch.find(x1, a1) + "."); 
       System.out.println("Test OK."); 
       pass++; 
      } 
      else if(BinarySearch.find(x1, a1) == -1) { 
       System.out.println(x1 + " is not present in array"); 
       System.out.println("TTest OK."); 
       pass++; 
      } 
      else { 
       System.out.println("Test FAIL."); 
       nonPass++; 
      } 
     } catch(Exception eccezione) { 
      System.out.println("Test FAIL."); 
      ecc++; 
     } 
     System.out.println(); 

     //Test n.2 
     try { 
      tot++; 
      System.out.print("Test n.2 - Array: [ "); 
      for(int i = 0; i < a1.length; i++) 
       System.out.print(a1[i] + " "); 
      System.out.println("]. Element to find: " + x2 + "."); 
      if(a1[BinarySearch.find(x2, a1)] == x2) { 
       System.out.println(x2 + " is in position " + BinarySearch.find(x2, a1) + "."); 
       System.out.println("Test OK."); 
       pass++; 
      } 
      else if(BinarySearch.find(x1, a1) == -1) { 
       System.out.println(x1 + " is not present in array"); 
       System.out.println("Test OK."); 
       pass++; 
      } 
      else { 
       System.out.println("Test FAIL."); 
       nonPass++; 
      } 
     } catch(Exception eccezione) { 
      System.out.println("Test FAIL."); 
      ecc++; 
     } 
     System.out.println(); 

     //RESULT 
     System.out.println();  
     System.out.println("Test totali: " + tot); 
     System.out.println("Test andati a buon fine: " + pass); 
     System.out.println("Test falliti: " + nonPass); 
     System.out.println("Test falliti con lancio di una eccezione: " + ecc);   

    } 
} 

如何創建一個測試類與JUnit? 我需要一些簡單的例子。

我知道,在測試類我必須寫這樣的代碼:

private final ByteArrayOutputStream outBuffer = new ByteArrayOutputStream(); 
private final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream(); 

@Before 
public void setupOutputStreams() { 
    System.setOut(new PrintStream(outBuffer)); 
    System.setErr(new PrintStream(errBuffer)); 
} 

@After 
public void cleanupOutputStreams() { 
    System.setOut(null); 
    System.setErr(null); 
} 

此代碼後,我怎麼寫了單獨測試的代碼? 然後我通常編譯並運行這個文件(BinarySearchTest.java)?或者有另一種方法可以做到這一點? 我有點困惑...

謝謝!

感謝

+0

大概檢查您用於Junit集成的IDE。基本上,你不會編寫自己的程序來運行Junit測試,但是你可以用@Test擴展一個類並註釋測試方法,讓Junit爲你做好準備。 – TeTeT

+0

[如何編寫單元測試?]的可能重複(http://stackoverflow.com/questions/8751553/how-to-write-a-unit-test) – Joe

回答

1

編寫單元測試很容易在JUnit4:編寫使用你的代碼的一些小方法,用JUnit assertions以確保您的代碼產生你期待的答案。

@RunWith(JUnit4.class) // JUnit4.class is a "runner". 
public class BinarySearchTest { 
    // By convention, the test for class Foo is named FooTest. You can name the 
    // test anything you'd like, though, especially if you split your test for 
    // Foo into more than one file. 

    @Test public void isSortedShouldReturnTrueWhenSorted() { // Same with methods. 
    assertTrue(BinarySearch.isSorted(new int[] { 2, 4, 6 })); 
    } 

    @Test public void isSortedShouldReturnFalseWhenUnsorted() { 
    assertFalse(BinarySearch.isSorted(new int[] { 4, 2, 6 })); 
    } 

    @Test public void isSortedShouldReturnTrueWhenEmpty() { 
    assertTrue(BinarySearch.isSorted(new int[] {})); 
    } 

    // Write more tests here! 
} 

雖然many IDEs have built-in ways of running JUnit tests,你也可以run tests from the command line。您不必編寫main方法,或計算通過和失敗的測試,或打印錯誤消息; JUnit將自行處理。相反,你運行JUnit,你告訴它在哪裏可以找到你的測試用例,然後JUnit運行它。

java -cp /usr/share/java/junit.jar org.junit.runner.JUnitCore your.package.BinarySearchTest 
# ^classpath includes JUnit ^you're running JUnitCore^on your test class 

對於你,對於每一個你@Test註釋方法,JUnit會創建測試類的新實例,運行每@Before -annotated方法,運行@Test -annotated的方法,每個類,然後運行每@After -annotated方法。對於簡單的測試,您可能沒有註釋方法@Before@After,這很好。

您的測試案例的組織大部分由您決定。有些人更喜歡編寫一個單獨的測試方法,其中包含許多assertTrueassertEquals語句(等等),而其他人則傾向於編寫許多微小的測試用例,每個測試用例都處理不同的方面(如上所述)。這取決於你,但請記住,在第一個斷言失敗或引發任何異常之後,JUnit將停止測試任何給定的方法,因此使用許多較小的方法可能會讓你更好地瞭解究竟是什麼錯誤。沿着這些路線,具體的方法名稱是有幫助的:你永遠不會自己調用它們,並且讓JUnit報告isSortedShouldReturnFalseWhenUnsorted失敗可能比追蹤爲什麼isSortedWorks可能失敗要容易得多。

  • 您可以查看org.junit.Assert文檔頁面上的所有聲明。請注意,他們是different than the assert keyword。您也可以編寫自己的代碼來引發錯誤的異常。
  • 不用擔心setOutsetErr。雖然重定向這些將在測試寫入stdout和stderr的模塊時產生更清晰的測試輸出,但默認情況下,您並不這樣做,JUnit也不介意。