天天看點

單元測試方法探索單元測試

單元測試

  • 單元測試
    • 單元測試和自動化測試
    • 單元測試和黑盒白盒測試
    • 單元測試用例設計方法介紹
    • 測試程式設計
      • TestNG
        • 通過 easymock來測試
        • 通過僞造http連結進行測試
        • Selenium 在ui層面上進行單元測試
        • TestNGSelenium 測試代碼示例
        • 測試結果展示
      • TestNG和Junit對比

單元測試和自動化測試

單元測試:隻針對單個函數/小功能所進行的測試,它針對單個函數、小功能的輸入輸出、邏輯等進行測試。

自動化測試:針對于手工測試提出。是指已可重複運作的形式進行的測試。

單元測試是在開發過程中提出的概念。

自動化測試是針對測試方法提出的概念。

單元測試的自動化有兩個含義:

1. 自動化執行的環境:一般意義上的可持續內建環境。用相關內建工具進行相關的自動化配置,到相應位置取出測試代碼和源代碼,自動執行驗證。

2. 用例本身是可以自動化執行的,其表現形式是可重複運作的代碼。

隻談第二部分。

單元測試和黑盒、白盒測試

見相關筆記《用例設計方法》

單元測試用例設計方法介紹

見相關筆記《用例設計方法》

測試程式設計

單元測試通用示例:

Class TestCase1(Input 1,Input2…){

準備測試資料;

調用被測函數/功能;

驗證被測函數/功能;

輸出結果;}

TestNG

參考目錄

1. TestNG官網

2. TestNG 入門教程

6. easyMock

8. selenium java api 文檔

通過 easymock來測試

用于模拟虛拟對象,用于測試接口、函數等。可以在依賴對象未實作前測試已經實作的部分。

步驟:

1. 建立一個mock

2. Have it set to the tested class

3. Record what we expect the mock to do

4. Tell all mocks we are now doing the actual testing

5. Test

6. Make sure everything that was supposed to be called was called

/*mock the param sent in*/

     /*HttpServletRequest request= (HttpServletRequest)EasyMock.createMock(HttpServletRequest.class);
      Map<String, String[]> requestMap = new HashMap<String, String[]>();
      String[] str1={userName};
      String[] str2={password};
      requestMap.put("username",str1);
      requestMap.put("password", str2);
      EasyMock.expect(request.getParameterMap()).andReturn(requestMap).once(); 
      UserController tmp= new UserController();
      System.out.println(tmp.userLogin(request));//the expect result is a challenge,private userService null pointer*/
           

通過僞造http連結進行測試

多用于協定接口,略

Selenium 在ui層面上進行單元測試

檢視連結Selenium and TestNG,上面的代碼是基于selenium 1.0版本的代碼,已過時,隻做示例說明。現已更新至3.4版本。

TestNG+Selenium 測試代碼示例

基于Selenium3.X

package UnitTest;

import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.AfterTest;
import org.testng.annotations.DataProvider;
import org.openqa.selenium.*;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.chrome.*;

public class UnitTest {

  @DataProvider(name="user_psw")//參數化測試
  public Object[][] Users(){
      return new Object[][]{//定義使用者登入的三組測試資料
              {"administrator","123456"},
              {"cnblogs.com", "tankxiao"},
              {"tank","xiao"}
      };
  }


 //測試用例1_使用者登入
  @Test(dataProvider="user_psw")
  public void TestCase001(String userName, String password) throws Exception {    
      /*selenium test,not method test */

      System.setProperty("webdriver.chrome.driver",
                "C:\\Users\\Administrator\\Desktop\\ydy_web\\easymock-3.4\\chromedriver.exe");
      DesiredCapabilities chromeCapabilities = DesiredCapabilities.chrome();
     WebDriver driver = new ChromeDriver(chromeCapabilities);
     driver.get("http://localhost:8080");
     Thread.sleep();
     (driver.findElement(By.id("user_name"))).sendKeys(userName);//輸入使用者名
     (driver.findElement(By.id("pass_word"))).sendKeys(password);//輸入密碼
    try{
        (driver.findElement(By.xpath("//*[@id=\"login-form\"]/div//*//div/a"))).click();//點選登入按鈕
         Thread.sleep();//wait for the page load
         // assert the result
         assert(driver.getCurrentUrl().contains("pages/index"));//檢驗執行結果
    }
    finally{
     driver.close();
    }     
  }

  //測試用例2
  @Test
  public void TestCase002() {
      System.out.println("TestCase002");
  }

  @BeforeClass//測試Class之前應執行的代碼
  public void beforeClass() {
      System.out.println("beforeClass");
  }

  @AfterClass//測試Class之後執行的代碼
  public void afterClass() {
      System.out.println("afterClass");
  }

  @BeforeTest//在所有測試開始時執行的代碼
  public void beforeTest() {
      System.out.println("beforeTest");
  }

  @AfterTest//在所有測試執行之後執行的代碼
  public void afterTest() {
      System.out.println("afterTest");
  }

}
           

測試結果展示

console輸出:

beforeTest
beforeClass
Starting ChromeDriver ……
TestCase002
afterClass
afterTest
PASSED: TestCase001("resonadministrator", "123456")
PASSED: TestCase002
FAILED: TestCase001("cnblogs.com", "tankxiao")
java.lang.AssertionError
    ……

FAILED: TestCase001("tank", "xiao")
java.lang.AssertionError
    ……
===============================================
    Default test
    Tests run: 4, Failures: 2, Skips: 0
===============================================


===============================================
Default suite
Total tests run: 4, Failures: 2, Skips: 0
===============================================
           

TestNG将結果輸出在test-output檔案夾中:

單元測試方法探索單元測試

TestNG和Junit對比

參考目錄

1. JUnit 4 Vs TestNG – Comparison

2. Junit和testNG的對比

3. JUnit 4 與 TestNG 對比

4. 追求代碼品質 JUnit 4 與 TestNG 的對比

支援功能對比:

單元測試方法探索單元測試

- Annotation:[中]注釋、注解;在測試用例是按注解的固定格式寫- 成,支援的注解越多,支援的測試方式就越多。

- Exception: 測試中程式中抛出的合理異常;

- Ignore: 在測試過程中可以忽略的代碼;

- timeout: 給測試時間做一個限定,超過限定,測試失敗;

- suite: 将單元測試用例組合成一個子產品來進行測試。JUnit4通過注解來實作,用例間強依賴。TestNG通過xml檔案實作,引入了組的概念,代碼更為靈活、重用性更高;

- group: 測試用例集合。JUnit4沒有測試組的概念,TestNG有組的概念,便于內建測試;

- 參數化:JUnit4固定聲明方式、構造方式、傳回參數類型固定。TestNG聲明方式多樣,參數類型不限制:用XML檔案或者@DataProvider注解來提供測試參數,XML檔案方式實作資料和用例分離;

- 依賴測試:說明用例之間的依賴關系,用例B的執行的前提是:用例A執行成功,若A執行失敗,那麼B就沒必要檢測。JUnit不支援,TestNG支援。

特性對比:

對比類目 JUnit4 TestNG 備注
Annotation support Y Y 相似,TestNG更豐富,見下表
單元測試 支援 支援
功能測試 N Y 都針對JAVA
內建測試 N Y 使用dependsOnMethods進行用例組合
額外配置.xml檔案 不需要 需要 testng.xml補充說明檔案
運作方式 指令行,ant,ide ide
用例間依賴關系 強依賴 通過屬性值來控制,較為靈活 TestNG更優
代碼重用性 多組合參數,需要寫多個用例 參數和代碼分離,一個用例即可 TestNG更優
失敗用例處理 重新執行所有用例 隻補充測試失敗用例 TestNG更優
測試結果表現方式 Green/Red bar Green/Red bar,console,檔案輸出 TestNG”test-output” 目錄

TestNG總體優于JUnit4,而且提供JUnit4遷移的方法。

Annotation support:

Annotation support JUnit 4 TestNG
測試注解 @Test @Test
測試套件在執行之前需要執行的 @BeforeSuite
測試套件在執行之後需要執行的 @AfterSuite
在測試之前需要執行的 @BeforeTest
在測試之後需要執行的 @AfterTest
在一個測試方法所屬于的任意一個組的第一個方法被調用之前執行 @BeforeGroups
在一個測試方法所屬于的任意一個組的最後一個方法被調用之後執行 @AfterGroups
在目前類的第一個測試方法調用之前執行 @BeforeClass @BeforeClass
在目前類的最後一個測試方法調用之後執行 @AfterClass @AfterClass
每個測試方法之前需要執行 @Before @BeforeMethod
每個測試方法之後需要執行 @After @AfterMethod
忽略 @ignore @Test(enbale=false)
預期異常 @Test(expected=ArithmeticException.class)
逾時 @Test(timeout = 1000) @Test(timeout = 1000)

建議使用TestNG+Selenium的方式進行測試。

繼續閱讀