Java Junit 基礎筆記

Junit

1. 概念

JUnit是一個Java語言的單元測試框架。
單元測試:單元測試(英語:Unit Testing)又稱爲模塊測試, 是針對程序模塊(軟件設計的最小單位)來進行正確性檢驗的測試工做。程序單元是應用的最小可測試部件。在過程化編程中,一個單元就是單個程序、函數、過程等;對於面向對象編程,最小單元就是方法,包括基類(超類)、抽象類、或者派生類(子類)中的方法。java

2. Junit特性

  • 測試工具
  • 測試套件
  • 測試運行器
  • 測試分類

3. API

註解

序號 註釋 描述
1 @Test 依附在Junit的public void方法上,做爲一個測試用例。
2 @Before 表示必須在每個測試以前執行,以便執行測試某些必要的先決條件。
3 @BeforeClass 依附在靜態方法上,在類的全部測以前必須執行。通常是測試計算共享配置方法(鏈接到數據庫)。
4 @After 表示在每個測試後執行,如執行每個測試後重置或刪除某些變量。
5 @AfterClass 在全部測試用例後執行,可用於清理創建方法,如斷開數據庫鏈接。和@BeforeClass同樣附着的方法必須是靜態。
6 @Ignore 當想暫時禁用特定的測試執行的時候可使用,被註解爲@Ignore的方法將不被執行。
  • 代碼示例:數據庫

    import org.junit.*;
    
    /**
    * Created by Administrator on 2017/11/1 0001.
    */
    public class TestAnnotation {
    
        //指出這是附着在靜態方法必須執行一次並在類的全部測試以前。
        // 發生這種狀況時通常是測試計算共享配置方法(如鏈接到數據庫)
        @BeforeClass
        public static void beforeClass(){
            System.out.println("execute beforeClass");
        }
    
        //當須要執行全部的測試在JUnit測試用例類後執行,AfterClass註解可使用以清理創建方法,
        // (從數據庫如斷開鏈接)。注意:附有此批註(相似於BeforeClass)的方法必須定義爲靜態。
        @AfterClass
        public static void afterClass(){
            System.out.println("execute afterClass");
        }
    
    
        //Before註釋表示,該方法必須在類中的每一個測試以前執行,以便執行測試某些必要的先決條件。
        @Before
        public void before(){
            System.out.println("execute before");
        }
    
        //After 註釋指示,該方法在執行每項測試後執行(如執行每個測試後重置某些變量,刪除臨時變量等)
        @After
        public void after(){
            System.out.println("execute after");
        }
    
        //測試註釋指示該公共無效方法它所附着能夠做爲一個測試用例。
        @Test
        public void test(){
            System.out.println("execute test");
        }
    
        @Test
        public void test1(){
            System.out.println("execute test1");
        }
    
        //當想暫時禁用特定的測試執行可使用忽略註釋。每一個被註解爲@Ignore的方法將不被執行。
        @Ignore
        public void ignoreTest(){
            System.out.println();
        }
    }
    import org.junit.runner.JUnitCore;
    import org.junit.runner.Result;
    import org.junit.runner.notification.Failure;
    
    /**
    * Created by Administrator on 2017/11/1 0001.
    */
    public class TestRunner2 {
        public static void main(String[] args) {
            Result result= JUnitCore.runClasses(TestAnnotation.class);
            for (Failure failure:result.getFailures()){
                System.out.println(failure.toString());
            }
            System.out.println(result.wasSuccessful());
        }
    }
  • 運行結果:編程

    execute beforeClass
    execute before
    execute test
    execute after
    execute before
    execute test1
    execute after
    execute afterClass
    true
  • junit的執行過程
    • beforeClass首先執行,只執行一次
    • afterClass最後執行,只執行一次
    • before在每次測試以前執行
    • after在每次測試以後執行
    • 每一個test在after和before之間執行

斷言

序號 方法 描述
1 assertEquals(boolean expected, boolean actual) 檢查兩個變量或者等式是否平衡
2 assertTrue(boolean expected, boolean actual) 檢查條件是否爲真
3 assertFalse(boolean condition) 檢查條件是否爲假
4 assertNotNull(Object object) 檢查變量是否不爲空
5 assertNull(Object object) 檢查變量是否爲空
6 assertSame(Object expected, Object actual) 檢查兩個引用是否指向同一個對象
7 assertNotSame(Object expected, Object actual) 檢查兩個引用是否不指向同一個對象
8 assertArrayEquals(expectedArray, resultArray) 檢查兩個數組是否相等
  • 代碼示例api

    import org.junit.Test;
    
    import static org.junit.Assert.*;
    
    public class TestAssertions {
    
        @Test
        public void testAssertions(){
            String str1=new String("abc");
            String str2=new String("abc");
            String str3=null;
            String str4="abc";
            String str5="abc";
            int val1=5;
            int val2=6;
            String[] expectedArray={"one","two","three"};
            String[] resultArray={"one","two","three"};
    
            assertEquals(str1,str2);
    
            assertTrue(val1<val2);
    
            assertFalse(val1>val2);
    
            assertNotNull(str1);
    
            assertNull(str3);
    
            assertSame(str4,str5);
    
            assertNotSame(str1,str3);
    
            assertArrayEquals(expectedArray,resultArray);
    
        }
    }

4. 執行測試

測試用例經過JUnitCore類來執行,它是Junit運行測試的外觀類。對於只有一次的測試運行,可使用靜態方法:runClasses(Class[])數組

5. 套件測試

意思就是捆綁幾個單元測試用例並一塊兒執行。@RunWith@Suite可一塊兒用於運行套件測試框架

  • 代碼示例ide

    /**
    * Created by Administrator on 2017/11/1 0001.
    * 被測試類
    */
    public class MessageUtil {
    
        private String message;
    
        public MessageUtil(String message){
            this.message=message;
        }
    
        public String printMessage(){
            System.out.println(message);
            return message;
        }
    
        public String salutationMessage(){
            message="Hi!"+message;
            System.out.println(message);
            return message;
        }
    }
    import org.junit.Assert;
    import org.junit.Test;
    
    /**
    * Created by Administrator on 2017/11/1 0001.
    */
    public class TestJunit {
    
        String message="Robert";
        MessageUtil messageUtil=new MessageUtil(message);
    
        @Test
        public void testPrintMessage(){
    //        message="New Word";
            System.out.println("Inside testPrintMessage()");
            Assert.assertEquals(message,messageUtil.printMessage());
        }
    }
    import org.junit.Assert;
    import org.junit.Test;
    
    /**
    * Created by Administrator on 2017/11/1 0001.
    */
    public class TestJunit1 {
    
        String message = "Robert";
        MessageUtil messageUtil=new MessageUtil(message);
    
        @Test
        public void testSalutationMessage(){
            System.out.println("Inside testSalutationMessage()");
            message="Hi!"+"Robert";
            Assert.assertEquals(message,messageUtil.salutationMessage());
        }
    }

測試執行類:函數

```
    import org.junit.runner.JUnitCore;
    import org.junit.runner.Result;
    import org.junit.runner.notification.Failure;

    /**
    * Created by Administrator on 2017/11/1 0001.
    */
    public class TestRunner2 {
        public static void main(String[] args) {
            Result result= JUnitCore.runClasses(JunitTestSuite.class);
            for (Failure failure:result.getFailures()){
                System.out.println(failure.toString());
            }
            System.out.println(result.wasSuccessful());
        }
    }
```
  • 運行結果
    Inside testPrintMessage() Robert Inside testSalutationMessage() Hi!Robert true

6. 忽略測試

  • 一個含有@Ignore 註釋的測試方法不會被執行
  • 若是一個測試類有@Ignore註釋,則它的測試方法將不會被執行

7. 時間測試

  • timeout參數與@Test註釋一塊兒使用,當一個測試用例比指定毫秒數花費更多時間,那麼Junit將會自動將它標記爲失敗。
  • 代碼示例:工具

    /**
    * Created by Administrator on 2017/11/1 0001.
    */
    public class MessageUtil {
    
        private String message;
    
        public MessageUtil(String message){
            this.message=message;
        }
    
        public void printMessage(){
            System.out.println(message);
            while (true);
        }
    
        public String salutationMessage(){
            message="Hi!"+message;
            System.out.println(message);
            return message;
        }
    }
    import org.junit.Assert;
    import org.junit.Test;
    
    /**
    * Created by Administrator on 2017/11/1 0001.
    */
    public class TestJunit4 {
    
        String message = "Robert";
        MessageUtil messageUtil=new MessageUtil(message);
    
    
        @Test(timeout = 1000)
        public void testPrintMessage(){
            System.out.println("Inside testPrintMessage");
            messageUtil.printMessage();
        }
    
        @Test
        public void testSalutationMessage(){
            System.out.println("Inside testSalutationMessage");
            message="Hi!"+"Robert";
            Assert.assertEquals(message,messageUtil.salutationMessage());
        }
    }
    import org.junit.runner.JUnitCore;
    import org.junit.runner.Result;
    import org.junit.runner.notification.Failure;
    
    /**
    * Created by Administrator on 2017/11/1 0001.
    */
    public class TestRunner2 {
        public static void main(String[] args) {
            Result result= JUnitCore.runClasses(TestJunit4.class);
            for (Failure failure:result.getFailures()){
                System.out.println(failure.toString());
            }
            System.out.println(result.wasSuccessful());
        }
    }
  • 運行結果單元測試

    Inside testSalutationMessage
    Hi!Robert
    Inside testPrintMessage
    Robert
    testPrintMessage(TestJunit4): test timed out after 1000 milliseconds
    false

8. 異常測試

  • expected參數與@Test註釋一塊兒使用,能夠測試代碼是否拋出你想要獲得的異常。

  • 代碼示例

    /**
    * Created by Administrator on 2017/11/1 0001.
    */
    public class MessageUtil {
    
        private String message;
    
        public MessageUtil(String message){
            this.message=message;
        }
    
        public void printMessage(){
            System.out.println(message);
    //        return message;
    //        while (true);
            int a=0;
            int b=1/a;
        }
    
        public String salutationMessage(){
            message="Hi!"+message;
            System.out.println(message);
            return message;
        }
    }
    import org.junit.Assert;
    import org.junit.Test;
    
    /**
    * Created by Administrator on 2017/11/1 0001.
    */
    public class TestJunit5 {
    
        String message = "Robert";
        MessageUtil messageUtil=new MessageUtil(message);
    
        @Test(expected = ArithmeticException.class)
        public void testPrintMessage(){
            System.out.println("Inside testPrintMessage");
            messageUtil.printMessage();
        }
    
        @Test
        public void testSalutationMessage(){
            System.out.println("Inside testSalutationMessage");
            message="Hi!"+"Robert";
            Assert.assertEquals(message,messageUtil.salutationMessage());
        }
    }
  • 運行結果
    Inside testSalutationMessage Hi!Robert Inside testPrintMessage Robert true

9. 參數化測試

  • 參數化測試容許開發人員使用不一樣的值反覆運行同一個測試用例。
    • @RunWith(Parameterized.class)來註釋test類
    • 建立一個由@Parameterized.Parameters註釋的公共靜態方法,返回一個對象的集合(數組)來做爲測試數據集合。
    • 建立一個公共構造函數,用來接收和存儲測試數據。
    • 用例會反覆運行,爲每一組測試數據建立一個實例變量
    • 用實例變量做爲測試數據的來源來建立你的測試用例
  • 代碼示例
    判斷是否是素數:

    public class PrimeNumberChecker {
    
        public Boolean validate(final Integer primeNumber){
            for (int i = 2; i < (primeNumber / 2); i++) {
                if (primeNumber%i==0){
                    return false;
                }
            }
            return true;
        }
    }
    import org.junit.Assert;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.junit.runners.Parameterized;
    
    import java.util.Arrays;
    import java.util.Collection;
    
    /**
    * Created by Administrator on 2017/11/1 0001.
    */
    
    @RunWith(Parameterized.class)
    public class PrimeNumberCheckerTest {
    
        private Integer inputNumber;
        private Boolean expectedResult;
        private PrimeNumberChecker primeNumberChecker;
    
        @Before
        public void initialize(){
            System.out.println("initialize");
            primeNumberChecker=new PrimeNumberChecker();
        }
    
        public PrimeNumberCheckerTest(Integer inputNumber,Boolean expectedResult){
            System.out.println("construct");
            this.inputNumber=inputNumber;
            this.expectedResult=expectedResult;
        }
    
        @Parameterized.Parameters
        public static Collection primeNumbers(){
            return Arrays.asList(new Object[][]{
                    {2,true},
                    {6,true},
                    {19,true},
                    {22,true},
                    {23,true}
            });
        }
    
        @Test
        public void testPrimeNumberChecker(){
            System.out.println("test");
            System.out.println("Parameterized Number is : " + inputNumber);
            Assert.assertEquals(expectedResult,
                    primeNumberChecker.validate(inputNumber));
        }
    }
    import org.junit.runner.JUnitCore;
    import org.junit.runner.Result;
    import org.junit.runner.notification.Failure;
    
    /**
    * Created by Administrator on 2017/11/1 0001.
    */
    public class TestRunner2 {
        public static void main(String[] args) {
            Result result= JUnitCore.runClasses(PrimeNumberCheckerTest.class);
            for (Failure failure:result.getFailures()){
                System.out.println(failure.toString());
            }
            System.out.println(result.wasSuccessful());
        }
    }
  • 運行結果

    construct
    initialize
    test
    Parameterized Number is : 2
    construct
    initialize
    test
    Parameterized Number is : 6
    construct
    initialize
    test
    Parameterized Number is : 19
    construct
    initialize
    test
    Parameterized Number is : 22
    construct
    initialize
    test
    Parameterized Number is : 23
    testPrimeNumberChecker[1](PrimeNumberCheckerTest): expected:<true> but was:<false>
    testPrimeNumberChecker[3](PrimeNumberCheckerTest): expected:<true> but was:<false>
    false
相關文章
相關標籤/搜索