2014-04-19 55 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也不介意。