Junit基础注解
@BeforeClass注解
在运行JUnit测试类时,其常常为第一个执行的方法,他会在@Before注解之前运行,其与@Before的另一个不同是,@BeforeClass是全局只执行一次的,这代表着,@BeforeClass注释方法是被static修饰的。
@Before注释
@Before注解常常也是在测试类@Test注释之前运行的,所以这种方法常常被用于初始化@Test注解方法中所需的资源进行初始化,而且,与@BeforeClass注释方法不同,@Before是可以执行多次的,每次当有@Test注释方法运行时,@Before都会被调用一次,并且是测试类中的任意一个@Test注释方法被调用时,都会执行。
@Test注释
在测试类中,@Test注释包含了真正的测试代码。并且测试方法必须使用public void进行修饰。
@After注释
与@Before测试类类似,@After注释方法会在任意的@Test方法执行后进行运行,即使被@Test 或 @Before修饰的测试方法抛出异常。与@Before配套,所以常常被用于关闭在@Before中初始化的资源。
@AfterClass注释
与@BeforeClass测试类类似,@AfterClass注解也是全局唯一的方法,因而也需要使用static来修饰,并且在全局代码中仅仅执行一次。它是在全局中最后一个被运行的注释方法。
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;
public class WtTest {
@BeforeClass
// 代表这方法最先开始执行
public static void setUpBeforeClass() throws Exception {
System.out.println("买菜...");
}
@AfterClass
// 代表这方法最后执行
public static void tearDownAfterClass() throws Exception {
System.out.println("走走...");
}
@Before
// 代表这方法会在Test方法前执行
public void setUp() throws Exception {
System.out.println("做饭...");
}
@After
// 代表这方法会在Test方法后执行
public void tearDown() throws Exception {
System.out.println("洗碗...");
}
@Test
public void test() {
System.out.println("吃饭...");
}
}
Junit assert断言方法
assertEquals 判断两个数值是否相等
assertArrayEquals 判断两个数组是否相等
assertNotEquals 判断两个数值是否不相等
assertTrue 查看运行结果是否为true
assertFalse 查看运行结果是否为false
import static org.junit.Assert.*;
public class WtTest {
String t1="hello";
String t2="world";
int num1=1;
int num2=2;
int[] arr1=new int[] {1,2,3};
int[] arr2=new int[] {1,2,3};
double dum1=1.0;
double dum2=2.0;
Object ob1=null;
Object ob2="hahaha";
@Test
public void testAssertEqual( ) {
assertEquals(num1, num2); // 判断两个数值是否相等
assertArrayEquals(arr1, arr2); // 判断两个数组是否相等
assertNotEquals(num1, num2); // 判断两个数值是否不相等
assertTrue(true); // 查看运行结果是否为true
assertFalse(false); // 查看运行结果是否为false
}
}
Junit assertThat 一般匹配符断言
import static org.junit.Assert.*;
import org.hamcrest.core.AllOf;
import static org.hamcrest.Matchers.*;
public class WtTest {
String t1="hello";
String t2="world";
int num1=1;
int num2=2;
int[] arr1=new int[] {1,2,3};
int[] arr2=new int[] {1,2,3};
double dum1=1.0;
double dum2=2.0;
Object ob1=null;
Object ob2="hahaha";
@Test
public void testAssertEqual( ) {
// 一般匹配符
assertThat(num1, allOf(greaterThan(8),lessThan(16))); // allOf相当于“与”,两个条件都成立才能通过
assertThat(num1, anyOf(greaterThan(8),lessThan(16))); // anyOf相当于“或”,两个条件其中一个成立才能通过
assertThat(num1, anything()); // anything表明无论什么条件,永远为true
assertThat(num1, is(1)); // 表明如果前面待测的object等于后面给出的object,则测试通过
assertThat(num1, not(1)); // 表明如果前面待测的object不等于后面给出的object,则测试通过
}
}
Junit assertThat 数值相关匹配符断言
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
public class WtTest {
String t1="hello";
String t2="world";
int num1=1;
int num2=2;
int[] arr1=new int[] {1,2,3};
int[] arr2=new int[] {1,2,3};
double dum1=1.0;
double dum2=2.0;
Object ob1=null;
Object ob2="hahaha";
@Test
public void testAssertEqual( ) {
//数值相关匹配符
assertThat(dum1,closeTo(1.0, 0.5)); // 表明如果所测试的浮点型数在1.0±0.5范围之内则测试通过
assertThat(dum1,greaterThan(16.0)); // 表明如果所测试的数值大于16.0则测试通过
assertThat(dum1, lessThan(16.0)); // 表明如果所测试的数值小于16.0则测试通过
assertThat(dum1, greaterThanOrEqualTo(16.0)); // 表明如果所测试的数值大于等于16.0则测试通过
assertThat(dum1, lessThanOrEqualTo(16.0)); // 表明如果所测试的数值小于等于16.0则测试通过
}
}
Junit assertThat 字符串相关匹配符断言
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
public class WtTest {
String t1="hello";
String t2="world";
int num1=1;
int num2=2;
int[] arr1=new int[] {1,2,3};
int[] arr2=new int[] {1,2,3};
double dum1=1.0;
double dum2=2.0;
Object ob1=null;
Object ob2="hahaha";
@Test
public void testAssertEqual( ) {
// 字符串相关匹配符
assertThat(t1, containsString("hell")); // 表明如果测试的字符串(hello)包含子字符串(hell)则测试通过
assertThat(t1, endsWith("llo")); // 表明如果测试的字符串(hello)包含子字符串(llo)结尾则测试通过
assertThat(t1, startsWith("he")); // 表明如果测试的字符串(hello)包含子字符串(he)开头则测试通过
assertThat(t1, equalTo("hello")); // 表明如果测试的字符串等于后面的字符串,则测试通过。equalTo可以测试数值之间,字符串之间和对象之间是否相等
assertThat(t1, equalToIgnoringCase("HELLO")); // 表明如果测试的字符串在忽略大小写的情况下等于后面的字符串则测试通过
assertThat(t1, equalToIgnoringWhiteSpace(" hello")); // 表明如果测试的字符串在忽略头尾的任意个空格的情况下等于后面的字符串则测试通过
}
}
Junit assertThat 集合相关匹配符断言
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.Matchers.*;
public class WtTest {
String t1="hello";
String t2="world";
int num1=1;
int num2=2;
int[] arr1=new int[] {1,2,3};
int[] arr2=new int[] {1,2,3};
double dum1=1.0;
double dum2=2.0;
Object ob1=null;
Object ob2="hahaha";
@Test
public void testAssertEqual( ) {
// 集合相关匹配符
Map<Integer,String> userMap = new HashMap<Integer,String>();
userMap.put(1, "hahaha");
userMap.put(2, "lalala");
assertThat(userMap, hasEntry(1, "hahaha")); // 表明如果测试的map对象userMap含有一个键值对为“1”对应元素值为“hahaha”则表示测试通过
assertThat(userMap,hasKey(1)); // 表明如果测试对象Map对象userMap含有键值“1”则测试通过
assertThat(userMap,hasValue("hahaha")); // 表明如果测试对象Map对象hasValue含有元素值“hahaha”则测试通过
ArrayList<Integer> userList = new ArrayList<Integer>();
userList.add(1);
userList.add(2);
assertThat(userList,hasItem(1)); // 表明如果测试的迭代对象userList含有元素“1”则测试通过
}
}
Junit 参数化设置
1.更改默认的测试运行器为RunWith(Parameterized.class)
2.声明变量来存放预期值 和结果值
3.声明一个返回值 为Collection的公共静态方法,并使用@Parameters进行修饰
import static org.junit.Assert.*;
import java.util.Collection;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class ParameterTest {
int expected = 0;
int input1 = 0;
int input2 = 0;
@Parameters
public static Collection<Object[]> t(){
return Arrays.asList(new Object[][] {{3,1,2},{4,2,2}});
}
public ParameterTest(int expecetd, int input1, int input2){
this.expected = expecetd;
this.input1 = input1;
this.input2 = input2;
}
@Test
public void testAdd() {
assertEquals(expected, input1+input2);
}
}
Junit 测试套件
在实际项目中,随着项目进度的开展,单元测试类会越来越多,可是直到现在我们还只会一个一个的单独运行测试类,这在实际项目实践中肯定是不可行的。为了解决这个问题,JUnit 提供了一种批量运行测试类的方法,叫做测试套件。
这样,每次需要验证系统功能正确性时,只执行一个或几个测试套件便可以了。测试套件的写法非常简单,我们需要遵循以下规则:
1. 创建一个空类作为测试套件的入口。
2. 使用注解 org.junit.runner.RunWith 和 org.junit.runners.Suite.SuiteClasses 修饰这个空类。
3. 将 org.junit.runners.Suite 作为参数传入注解 RunWith,以提示 JUnit 为此类使用套件运行器执行。
4. 将需要放入此测试套件的测试类组成数组作为注解 SuiteClasses 的参数。
5. 保证这个空类使用 public 修饰,而且存在公开的不带有任何参数的构造函数。
现在OK了,我们来写代码,这里我写2个测试类,然后让这2个类形成一个测试套件,来一起被测试:
测试类1
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.hamcrest.core.AllOf;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.hamcrest.Matchers.*;
public class WtTest {
String t1="hello";
String t2="world";
int num1=1;
int num2=2;
int[] arr1=new int[] {1,2,3};
int[] arr2=new int[] {1,2,3};
double dum1=1.0;
double dum2=2.0;
Object ob1=null;
Object ob2="hahaha";
@BeforeClass
// 代表这方法最先开始执行
public static void setUpBeforeClass() throws Exception {
System.out.println("买菜...");
}
@AfterClass
// 代表这方法最后执行
public static void tearDownAfterClass() throws Exception {
System.out.println("走走...");
}
@Before
// 代表这方法会在Test方法前执行
public void setUp() throws Exception {
System.out.println("做饭...");
}
@After
// 黛比哦啊哦这方法会在Test方法后执行
public void tearDown() throws Exception {
System.out.println("洗碗...");
}
@Test
public void test() {
System.out.println("吃饭...");
}
@Test
public void testAssertEqual( ) {
assertEquals(num1, num2); // 判断两个数值是否相等
assertArrayEquals(arr1, arr2); // 判断两个数组是否相等
assertNotEquals(num1, num2); // 判断两个数值是否不相等
assertTrue(true); // 查看运行结果是否为true
assertFalse(false); // 查看运行结果是否为false
// 一般匹配符
assertThat(num1, allOf(greaterThan(8),lessThan(16))); // allOf相当于“与”,两个条件都成立才能通过
assertThat(num1, anyOf(greaterThan(8),lessThan(16))); // anyOf相当于“或”,两个条件其中一个成立才能通过
assertThat(num1, anything()); // anything表明无论什么条件,永远为true
assertThat(num1, is(1)); // 表明如果前面待测的object等于后面给出的object,则测试通过
assertThat(num1, not(1)); // 表明如果前面待测的object不等于后面给出的object,则测试通过
//数值相关匹配符
assertThat(dum1,closeTo(1.0, 0.5)); // 表明如果所测试的浮点型数在1.0±0.5范围之内则测试通过
assertThat(dum1,greaterThan(16.0)); // 表明如果所测试的数值大于16.0则测试通过
assertThat(dum1, lessThan(16.0)); // 表明如果所测试的数值小于16.0则测试通过
assertThat(dum1, greaterThanOrEqualTo(16.0)); // 表明如果所测试的数值大于等于16.0则测试通过
assertThat(dum1, lessThanOrEqualTo(16.0)); // 表明如果所测试的数值小于等于16.0则测试通过
// 字符串相关匹配符
assertThat(t1, containsString("hell")); // 表明如果测试的字符串(hello)包含子字符串(hell)则测试通过
assertThat(t1, endsWith("llo")); // 表明如果测试的字符串(hello)包含子字符串(llo)结尾则测试通过
assertThat(t1, startsWith("he")); // 表明如果测试的字符串(hello)包含子字符串(he)开头则测试通过
assertThat(t1, equalTo("hello")); // 表明如果测试的字符串等于后面的字符串,则测试通过。equalTo可以测试数值之间,字符串之间和对象之间是否相等
assertThat(t1, equalToIgnoringCase("HELLO")); // 表明如果测试的字符串在忽略大小写的情况下等于后面的字符串则测试通过
assertThat(t1, equalToIgnoringWhiteSpace(" hello")); // 表明如果测试的字符串在忽略头尾的任意个空格的情况下等于后面的字符串则测试通过
// 集合相关匹配符
Map<Integer,String> userMap = new HashMap<Integer,String>();
userMap.put(1, "hahaha");
userMap.put(2, "lalala");
assertThat(userMap, hasEntry(1, "hahaha")); // 表明如果测试的map对象userMap含有一个键值对为“1”对应元素值为“hahaha”则表示测试通过
assertThat(userMap,hasKey(1)); // 表明如果测试对象Map对象userMap含有键值“1”则测试通过
assertThat(userMap,hasValue("hahaha")); // 表明如果测试对象Map对象hasValue含有元素值“hahaha”则测试通过
ArrayList<Integer> userList = new ArrayList<Integer>();
userList.add(1);
userList.add(2);
assertThat(userList,hasItem(1)); // 表明如果测试的迭代对象userList含有元素“1”则测试通过
}
}
测试类2
import static org.junit.Assert.*;
import java.util.Collection;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class ParameterTest {
int expected = 0;
int input1 = 0;
int input2 = 0;
@Parameters
public static Collection<Object[]> t(){
return Arrays.asList(new Object[][] {{3,1,2},{4,2,2}});
}
public ParameterTest(int expecetd, int input1, int input2){
this.expected = expecetd;
this.input1 = input1;
this.input2 = input2;
}
@Test
public void testAdd() {
assertEquals(expected, input1+input2);
}
}
测试套件
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({WtTest.class,ParameterTest.class})
public class WtTest2 {
@Test
public void test() {
fail("Not yet implemented");
}
}
Junit 测试优先级顺序
- MethodSorters.JVM
Leaves the test methods in the order returned by the JVM. Note that the order from the JVM may vary from run to run (按照JVM得到的方法顺序,也就是代码中定义的方法顺序)
import static org.junit.Assert.*;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
@FixMethodOrder(MethodSorters.JVM)
public class JVMTest {
@Test
public void maicai() {
System.out.println("买菜...");
}
@Test
public void zouzou() {
System.out.println("走走...");
}
@Test
public void zuofan() {
System.out.println("做饭...");
}
@Test
public void xiwan() {
System.out.println("洗碗...");
}
@Test
public void chifan() {
System.out.println("吃饭...");
}
}
运行结果:
买菜...
走走...
洗碗...
吃饭...
做饭...
- MethodSorters.DEFAULT(默认的顺序)
Sorts the test methods in a deterministic, but not predictable, order() (以确定但不可预期的顺序执行)
import static org.junit.Assert.*;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
@FixMethodOrder(MethodSorters.DEFAULT)
public class JVMTest {
@Test
public void maicai() {
System.out.println("买菜...");
}
@Test
public void zouzou() {
System.out.println("走走...");
}
@Test
public void zuofan() {
System.out.println("做饭...");
}
@Test
public void xiwan() {
System.out.println("洗碗...");
}
@Test
public void chifan() {
System.out.println("吃饭...");
}
}
运行结果:
吃饭...
买菜...
走走...
做饭...
洗碗...
- MethodSorters.NAME_ASCENDING
Sorts the test methods by the method name, in lexicographic order, with Method.toString() used as a tiebreaker (按方法名字母顺序执行)
import static org.junit.Assert.*;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class JVMTest {
@Test
public void maicai() {
System.out.println("买菜...");
}
@Test
public void zouzou() {
System.out.println("走走...");
}
@Test
public void zuofan() {
System.out.println("做饭...");
}
@Test
public void xiwan() {
System.out.println("洗碗...");
}
@Test
public void chifan() {
System.out.println("吃饭...");
}
}
运行结果:
吃饭...
买菜...
洗碗...
走走...
做饭...
Junit TestRunner使用
import static org.junit.Assert.*;
import org.junit.Test;
public class Calcaute {
public int ride(int a, int b) {
return a * b;
}
}
import static org.junit.Assert.*;
import java.awt.List;
import java.util.ArrayList;
import java.util.Collection;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import junit.extensions.TestSetup;
@RunWith(value = Parameterized.class)
public class TestCalcaute {
private Calcaute calcaute = null;
private int expected;
private int valueOne;
private int valueTwo;
@Parameters
public static Collection<Integer[]> getTestParmeters(){
ArrayList<Integer[]> list = new ArrayList<Integer[]>();
list.add(new Integer[] {20,4,5});
list.add(new Integer[] {-20,-4,5});
list.add(new Integer[] {0,0,5});
return list;
}
public TestCalcaute(int expected, int valueOne, int valueTwo) {
this.expected = expected;
this.valueOne = valueOne;
this.valueTwo = valueTwo;
// TODO Auto-generated constructor stub
}
@Before
public void Setup() {
calcaute = new Calcaute();
}
@Test
public void testAdd() {
int result = calcaute.ride(valueOne, valueTwo);
System.out.println(result);
assertEquals(expected, result);
}
}
ok,功能实现了,但是,在此我们要说明几个必须:
1、实现参数化测试运行器,该类必须加上@RunWith(value=Parameterized.class)注解!否则运行Junit报java.lang.Exception: Test class should have exactly one public zero-argument constructor异常
2、必须把测试的期望结果、以及测试参数声明为全局的、私有的!
3、必须创建一个带期望结果、测试参数的构造方法!
4、必须创建一个返回若干个测试参数、期望结果组的静态方法,返回类型为Collection<Integer[]>,并且该方法加以@Parameters( org.junit.runners.Parameterized.Parameters)注解!
Junit 内置Rule 中的TestName使用
TestName(获取当前执行的测试方法的名称
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
public class TestNameRuleTest {
@Rule
public TestName name = new TestName();
@Test
public void test() {
System.out.println("method name = " + name.getMethodName());
assertEquals("test", name.getMethodName());
}
}
TemporaryFolder(创建临时文件或文件夹)
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class HasTempFolder {
@Rule
public final TemporaryFolder folder = new TemporaryFolder();
@Test
public void testUsingTemFolder() throws IOException{
// 创建一个随机名称的文件
File createdFile = folder.newFile("myfile.txt");
// 创建一个随机名称的文件夹
File createdFolder = folder.newFile("subfolder");
}
}