[软件测试] - No.7 Junit4及Harmcrest使用详解

Junit是我们编写Java 测试用例时候常用的方式。Junit4为我们提供了非常方便的单元测试,参数化测试,以及组合单元测试。

Junit4安装:下载Junit4 jar包,导入项目

一、常用注解解释:

1. @Test注解

@Test注解是我们最常见的注解,用于标注一个函数是测试函数,如下所示:

	@Test
	public void test() {
		assertEquals(3,1+2);
	}

@Test提供两种参数,分别为expected和timeout

expected = XXX.class 表示希望测试函数抛出某个异常

@Test(expected = IndexOutOfBoundsException.class)
	public void test(){
		 new ArrayList<Object>().get(1);
	}

timeout = 1000 表示测试函数的最大运行时间是1000ms 超出这个时间则报错

@Test(timeout = 2000)
	public void test() throws InterruptedException{
		Thread.sleep(1000);  
	}
2. @BeforeClass,@Before,@After,@AfterClass

@Before 和 @After均是对于方法级别的注解

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}
对于每个使用了@Test注解注释的测试函数,都必须在函数运行开始和结束的时候分别运行上述的函数

@Before->@Test->@After

@BeforeClass和@AfterClass是对于类级别的注解

@BeforeClass
	public static void setUpBeforeClass() throws Exception {
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
	}

在类初始化的时候进行一些初始化的操作例如数据库建立之类的,方法对应的是static的静态方法

@BeforeClass->@Before->@Test->@After->@AfterClass

3. 

@Ignore 忽略一个测试方法或者测试类

@Ignore
	@Test(timeout = 2000)
	public void test() throws InterruptedException{
		Thread.sleep(1000);  
	}
4. @RunWith

设置Junit测试用例的启动器。Runner负责调用你的测试代码,每一个Runner都有各自的特殊功能,根据需要选择不同的Runner来运行测试代码。Junit4默认设置的是@RunWith(BlockJunit4ClassRunner.class) 。

但是当我们进行参数化测试和组合单元测试的时候,我们需要使用其他的启动器。这个在下面再说

5. @SuiteClasses({A.class,B.class})

用于组合单元测试时候

二、参数化测试

什么叫参数化测试呢?我们看下面一个小例子:

@Test
public void testCheckTriangle() {
	assertEquals(false,tri.checkTriangle(1,2,3));
	assertEquals(true,tri.checkTriangle(3,4,5));
	assertEquals(true,tri.checkTriangle(3,3,1));
	assertEquals(true,tri.checkTriangle(2,2,2));
}
比如,当我们希望测试判断三角形的这个函数的时候?我们有四个例子,所以需要些四个例子

所谓参数化测试,就是我们将数据存储在某个数据结构之中,然后这个测试用例会自动加载这个数据结构,然后一个一个取出其中的记录,进行多个测试

那么我们应该怎么编写我们的测试用例呢?

1.首先新建一个测试类这里为TriangleTest.java

public class TriangleTest {
	
}

2.声明成员变量:我们的三条边分别为a,b,c 我们期望的结果是result

public class TriangleTest {
	static Triangle tri;
	private int a,b,c;
	private boolean result;

}

3.编写构造函数:在构造函数中给四个成员变量赋值

public class TriangleTest {
	static Triangle tri;
	private int a,b,c;
	private boolean result;
	public TriangleTest(boolean result,int a,int b,int c)
	{
		this.result = result;
		this.a = a;
		this.b = b;
		this.c = c;
	}	

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		tri = new Triangle();
	}
}

4.编写加载数据的函数

@RunWith(Parameterized.class)
public class TriangleTest {
	static Triangle tri;
	private int a,b,c;
	private boolean result;
	public TriangleTest(boolean result,int a,int b,int c)
	{
		this.result = result;
		this.a = a;
		this.b = b;
		this.c = c;
	}
	

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		tri = new Triangle();
	}
	@Parameters
	public static Collection<Object[]> getData()
	{
		List<Object[]> list = new ArrayList<>();
		list.add(new Object[]{
				false,1,2,3
		});
		list.add(new Object[]{
				true,3,4,5
		});

		list.add(new Object[]{
				true,2,2,2
		});

		list.add(new Object[]{
				true,3,3,1
		});
		return list;
	}

}
这里解释一下这个加载数据的函数:首先,这个函数要声明为static静态函数,同时要返回一个容器例如数组,或者列表之类的。那么为什么这个容器的类型是Object[]呢?

Object [] 表示的是你的一条数据记录。例如我们有一个测试是测试三角形3,4,5,期望结果是true 那么这个记录应该表示为:

Object obj = new Object[]{ true,3,4,5 });
使用Object以适应任意类型

5.编写测试函数

@Test
public void testParameter()
{
assertEquals(result,tri.checkTriangle(a, b, c));
}

6.设置测试类为参数化测试

@RunWith(Parameterized.class)

测试结果:



三、组合单元测试:

我们编写两个简单的测试类testa和testb

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

public class testa {

	@Test
	public void test() {
		assertEquals(2,1+1);
	}

}
import static org.junit.Assert.*;

import java.util.ArrayList;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

public class testb {

	@Test
	public void test(){
		assertEquals(3,2+1);
	}

}
然后编写一个组合单元测试,设置组合类为组合测试启动,设置组合类的内容

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({testa.class,testb.class})
public class SuiteTest {

}



Harmcrest:在我测试的时候,使用的是junit-4.12+harmcrest-core-1.3+harmcrest-library-1.3。也可以使用harmcrest-all-1.3,相关jar在harmcrest官网下载

harmcrest为我们提供了以下常用的函数:

allOf - matches if all matchers match (short circuits)
anyOf - matches if any matchers match (short circuits)
not - matches if the wrapped matcher doesn't match and vice versa
equalTo - test object equality using the equals method
is - decorator for equalTo to improve readability
hasToString - test Object.toString
instanceOf, isCompatibleType - test type
notNullValue, nullValue - test for null
sameInstance - test object identity
hasEntry, hasKey, hasValue - test a map contains an entry, key or value
hasItem, hasItems - test a collection contains elements
hasItemInArray - test an array contains an element
closeTo - test floating point values are close to a given value
greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo - test ordering
equalToIgnoringCase - test string equality ignoring case
equalToIgnoringWhiteSpace - test string equality ignoring differences in runs of whitespace
containsString, endsWith, startsWith - test string matching

下面是使用harmcrest的一个例子:

import org.junit.Assert;
import static org.hamcrest.MatcherAssert.*;  
import static org.hamcrest.Matchers.*;  
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

public class testa {

	@Test
	public void test() {
		org.hamcrest.MatcherAssert.assertThat(40,allOf(greaterThan(20),lessThan(60)));
		org.hamcrest.MatcherAssert.assertThat("abcdefg",allOf(startsWith("abc"),endsWith("efg")));
			
	}

}
想要使用harmcrest的匹配函数,我们一般要引入如下库:

import static org.hamcrest.Matchers.*;  

否则,无法使用上述的匹配库中的函数。

同时,你会看到,我在使用assertThat的时候,显示声明使用org.hamcrest.MatcherAssert.assertThat,这是为了和junit中的assertThat区分开

如果你在使用harmcrest时遇到这样的问题:

java.lang.NoSuchMethodError: org.hamcrest.core.AnyOf.anyOf(Lorg/hamcrest/Matcher;Lorg/hamcrest/Matcher;)Lorg/hamcrest/core/AnyOf;

一般这样的情况,是由于你的junit和harmcrest引入的包的顺序不对。要把harmcrest放在junit的前边,这样每次调用allof的时候才会使用harmcrest中的函数。

更改引入顺序,删除相应的junit重新导入,或者更换一下junit版本

P.S.文章不妥之处还望指正



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值