单元测试方法探索

单元测试


单元测试和自动化测试

单元测试:只针对单个函数/小功能所进行的测试,它针对单个函数、小功能的输入输出、逻辑等进行测试。
自动化测试:针对于手工测试提出。是指已可重复运行的形式进行的测试。

单元测试是在开发过程中提出的概念。
自动化测试是针对测试方法提出的概念。

单元测试的自动化有两个含义:
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(1000);
     (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(1000);//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支持。

特性对比:

对比类目JUnit4TestNG备注
Annotation supportYY相似,TestNG更丰富,见下表
单元测试支持支持
功能测试NY都针对JAVA
集成测试NY使用dependsOnMethods进行用例组合
额外配置.xml文件不需要需要testng.xml补充说明文件
运行方式命令行,ant,ideide
用例间依赖关系强依赖通过属性值来控制,较为灵活TestNG更优
代码重用性多组合参数,需要写多个用例参数和代码分离,一个用例即可TestNG更优
失败用例处理重新执行所有用例只补充测试失败用例TestNG更优
测试结果表现方式Green/Red barGreen/Red bar,console,文件输出TestNG”test-output” 目录

TestNG总体优于JUnit4,而且提供JUnit4迁移的方法。

Annotation support:

Annotation supportJUnit 4TestNG
测试注解@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的方式进行测试。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值