一.测试概述

1.软件测试
  • 瀑布式开发模型
  • 基于敏捷式的开发
  • 软件测试三个阶段:单元测试/集成测试/系统测试
  • 压力测试:验证系统的稳定性与承载能力
  • 用户测试
2.什么是JUnit
  • Java单元测试必备工具
  • 简单的单元测试工具
  • 自动化测试工具

二.JUnit使用

1.示例代码1
  • 使用@Test,JUnit就会调用对应的方法
  • 使用assertEquals()等断言的方式判断结果值
  • 使用@Ignore跳过对应测试部分
  • 针对于异常的测试,在@Test参数中定义期望的异常,当抛出异常的时候就认为代码是通过的
  • 针对于死循环的测试,在@Test的参数中给定超时时长,timeout=1000表示如果超过1秒还没有结束就失,timeout通常是在被测试的程序的逻辑非常复杂,不清楚会不会存在问题,还要在一定时间内执行完,则添加
  • 被测试的代码
public class Calculator {
	private static int result;
	public void add(int n){
		result=result+n;
	}
	public void substract(int n){
		result=result-1;
	}
	public void multiply(int n){} //未处理乘逻辑
	public void divide(int n)throws Exception{
		if(n==0)
			throw new Exception("除数不能为0);
		result=result/n;
	}
	public void square(int n){
		result=n*n;
	}
	public void squareRoot(int   n){
		for(;;); //死循环
	}
	public void clear(){
		result=0;
	}
    public int getResult() {
        return result;
    }
}
  • 用于测试的JUnit代码
public class CalculatorTest {
    // 创建测试对象实例
    public static Calculator c= new Calculator();
    @Before
    public void setUp() throws Exception {}
    @Test
	public void addTest(int n){
        c.add(2);
        c.add(2);
        assertEquals(4,c.getResult());//使用断言的形式判断结果值
	}
    @Test
	public void substractTest(int n){
	    c.substract(2);
       assertEquals(2,c.getResult());//使用断言的形式判断结果值
	}
    // 由于还没有编写multiply方法内容,可以使用@Ignore注解跳过此测试
    @Ignore
	public void multiplyTest(int n){}
    // 针对于异常的测试,在@Test参数中定义期望的异常,当抛出异常的时候就认为代码是通过的
    @Test(expected=Exception.class)
	public void divideTest(int n)throws Exception{
		c.divide(0);
	}
    // 针对于死循环的测试,在@Test的参数中给定超时时长,timeout=1000表示如果超过1秒还没有结束就失
    // timeout通常是在被测试的程序的逻辑非常复杂,不清楚会不会存在问题,还要在一定时间内执行完,则添加
    @Test(timeout=1000)
	public void squareRootTest(int n){
		c.squareRoot(9);//由于是死循环,传递任何内容都会是死循环状态
    }
    @Test
	public void squareTest(int n){
		result=n*n;
	}
    @Test
	public void clearTest(){
		result=0;
	}
}
2.示例代码2
  • 执行对数据库操作的TestCase
  • 测试方法执行的先后顺序是根据JVM判断的,我们可以通过@FixMethodOrder注解自行进行顺序的设定
  • 使用@Before@After定义在任何一个测试场景执行之前之后要执行的内容
  • 被测试的代码
public class Demo {
	Connection conn=null;
	public static void main(String[] args){
		Demo d=new Demo();
		Map param=new HashMap();
		param.put("id",5);
		param.put("name","amy");
		param.put("password","123456");
		d.insert(param);
		d.getAll();
		d.close();
	}

    // 创建DB连接
	public void createDb(){
		String url="jdbc:mysql://localhost:3306/test1";
		String name="com.mysql.jdbc.Driver";
		String user="root";
		String password="root";
		try {
			Class.forName(name);// 指定连接类型
           conn = DriverManager.getConnection(url, user,password);
		    //pst=conn.prepareStatement(sql);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch(SQLException e){
			e.printStackTrace();
		}
	}

    // 插入数据
	public int insert(Map param){
		this.createDb();
		int i=0;
		String sql="INSERT INTO user(id,username,password) VALUES(?,?,?)";
		PreparedStatement pstmt;
		try{
			pstmt=this.conn.prepareStatement(sql);
			pstmt.setString(1,(String)param.get("id"));
			pstmt.setString(2,(String)param.get("name"));
			pstmt.setString(3,(String)param.get("password"));
			i=pstmt.executeUpdate();
			pstmt.close();
		}catch(SQLException e){
			e.printStackTrace();
		}
		return i;
	}

    // 获得数据库数据信息
	public void getAll(){
		String sql="select * from user";
		PreparedStatement pstmt=null;
		try{
			pstmt=this.conn.prepareStatement(sql);
			ResultSet rs=pstmt.executeQuery();
			int col=rs.getMetaData().getColumnCount();
			System.out.println("=========================");
			while(rs.next()){
				for(int i=1;i<=col;i++){
					System.out.print(rs.getString(i)+"\t");
					if((i==2)&&(rs.getString(i).length()<8)){
						System.out.print("\t");
					}
				}
				System.out.println("");
			}
			System.out.println("=========================");
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	public void close(){}
}
  • JUnit测试代码
@FixMethodOrder(MethodSorters.JVM)//通过此注解告诉JVM执行测试方法的顺序
public class DemoTest {
    // 创建被测试的对象
    public static Demo d = new Demo();
    // 在任何一个测试场景执行之前都要创建数据库连接
    @Before
    public void testCreateDb() {
        d.createDb();
    }
    // 测试数据库插入
    @Test
    public void testInsert() {
        Map param=new HashMap();
	    param.put("id",5);
	    param.put("name","amy");
	    param.put("password","123456");
	    d.insert(param);
    }
    // 测试查询数据库
    @Test
    public void testGetAll() {
        d.getAll();
    }
    // 测试创建数据库
    @Test
    public void testCreateDb() {
    
    }
    // 在任何一个测试场景执行之后都要关闭数据库
    @After
    public void testClose() {
        d.close();
    }
}
3.定义JUnit测试的TestSuite
  • 通过@Suite.SuiteClasses()注解定义所有要执行的TestCase从而一起运行
  • 示例代码
@RunWith(Suite.class)
@Suite.SuiteClasses({
    CalculatorTest.class,
    DemoTest.class
    })
public class TestAllForJunit() {}
4.针对于指定JUnit测试方法执行顺序的查阅
  • 当我们对数据库执行插入后的查询操作,或需要指定执行顺序的操作时,需要通过@FixMethodOrder注解来控制测试方法的执行顺序
  • @FixMethodOrder注解的参数是org.junit.runners.MethodSorters对象,在枚举类org.junit.runners.MethodSorters中定义了如下三种顺序类型:
    • MethodSorters.JVM:按照JVM得到的方法顺序,也就是代码中定义的方法顺序
    • MethodSorters.DEFAULT(默认的顺序):以确定但不可预期的顺序执行
    • MethodSorters.NAME_ASCENDING:按方法名字母顺序执行
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐