天天看点

单元测试方法探索单元测试

单元测试

  • 单元测试
    • 单元测试和自动化测试
    • 单元测试和黑盒白盒测试
    • 单元测试用例设计方法介绍
    • 测试编程
      • 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的方式进行测试。

继续阅读