JUnit学习笔记(一):基本用法

JUnit学习笔记(一):基本用法




    JUnit是Java的单元测试框架。JUnit提倡“先测试后编码”的理念,强调建立测试数据的代码,可以先测试,再应用。

框架的特点
    JUnit是
开放的资源框架,用于编写和运行测试;
    提供注释来识别测试的方法;
    提供断言来测试预期结果;
    提供测试运行来运行测试;

单元测试用例的特点
    预期输入和预期输出。预期输入需要有测试的前置条件,预期输出需要有测试的后置条件;
    每一项需求至少需要两个单元测试用例:一个正向验证(是否做了该做的事),一个负向验证(是否做了不该做的事)。
    若一个需求有子需求,每一个子需求必须至少有正向验证和负向验证两个测试用例。负向用例可以有多个;

API
    官网API地址:http://junit.org/junit4/javadoc/latest/index.html
    核心包junit.frameworkjunit.runner。Framework包-->整个测试对象的构架,Runner-->测试驱动;
    JUnit的四个核心类:TestCaseTestSuiteTestRunnerTestResult

TestResult: 测试结果。收集TestCase所执行的结果,将结果分为两类,可预测的Failure和没有预测的Error。同时将测试结果
                     转发到TestListener(该接口由TestRunner继承)处理;
TestRunner: 测试运行器。对象调用的起始点,对整个测试流程的跟踪。能显示返回的测试结果,并且报告测试的进度;
TestSuite: 测试集合。包装和运行所有的TestCase;
TestCase: 测试用例。测试类所要继承的类,测试时对被测试类进行初始化,及测试方法调用;


重要的接口:Test和TestListener
    Test的主要方法:run()和countTestCases();
    TestListener的主要方法:addError()、addFailure()、startTest()和endTest();

基本的测试过程
        TestClass.class(被测试类)-->TestCase(测试用例)-->TestSuite(测试用例集合)-->TestRunner(测试运行器) -->TestResult(测试结果)

例子:
public class Message { //被测试类

	private String message = null;
	public boolean isPrint = false;

	public Message(String message) {
		this.message = message;
	}

	public String printMessage() { // method1-->case1
		System.out.println(message);
		this.isPrint = true;
		System.out.println(this.isPrint + "...");
		return this.message;
	}

	public String changeMessage(String str) { // method2-->case2
		this.message += str;
		return this.message;
	}

	public String handleMessage(String str){ // method3-->case3
		int a = str.length();
		if(a>=5){
		  this.message = str.substring(0, 5);	
		}
		
		return this.message;
	}
}


public class MessageTestCase1 { //测试用例1

	String info = "new String";
	Message m = new Message(info);

	@Test
	public void test1() {
		m.printMessage();
		assertEquals(true, m.isPrint);
	}

	@Test
	public void test2() {
		m.printMessage();
		assertEquals(false, m.isPrint);
	}
}


public class MessageTestCase2 { //测试用例2
	
	String s = "aa";
	Message m = new Message(s);
	
	@Test
	public void test1(){
		String str = "aazz";
		assertEquals(str,m.changeMessage("zz"));
	}
	
	@Test
	public void test2(){
		String str = "asdf";
		assertEquals(str,m.changeMessage(str));
	}
}


public class MessageTestCase3 { //测试用例3
	
	String str = "abcdefgh";
	Message m = new Message("a");
	
	@Test
	public void test1(){
		assertEquals(5,m.handleMessage(str).length());
	}
	
	@Test
	public void test2(){
		assertEquals(4,m.handleMessage(str).length());
	}
	
	@Test
	public void test3(){
		assertEquals(6,m.handleMessage(str).length());
	}
}


@RunWith(Suite.class)
@Suite.SuiteClasses({ MessageTestCase1.class, MessageTestCase2.class,
		              MessageTestCase3.class })

public class MessageTestSuite {  //测试用例集

//	public static void main(String[] args) {
//
//		TestSuite suite = new TestSuite(MessageTestCase1.class,
//				MessageTestCase2.class,MessageTestCase3.class);
//		
//		TestResult result = new TestResult();
//		suite.run(result);
//		
//	}	
}


public class MessageTestRunner { //测试执行器

	public static void main(String[] args) {

		Result result = JUnitCore.runClasses(MessageTestSuite.class);
		for (Failure failure : result.getFailures()) {
			System.out.println(failure.toString());
		}
		System.out.println("TestResult:" + result.wasSuccessful());
	}
}




Ignoring Tests
    含有@Ignore注释的测试方法将不会被执行;
    用@Ignore注释的测试类,它的测试方法将不会执行;

例子:
@Ignore("冗余测试用例")
	@Test
	public void test3(){
		assertEquals(6,m.handleMessage(str).length());
	}


Timeout for Tests
   设置超时时间,对用例执行时间进行控制。
   第一种用法:
	@Test(timeout=10000)
	public void test2(){
		assertEquals(4,m.handleMessage(str).length());
	}

    第二种用法(设置超时规则。写在测试类中,测试类中的所有测试方法均遵守此规则):
@Rule
    public Timeout globalTimeout = Timeout.seconds(10);


Exception Testing
    测试代码是否抛出预想的异常。
例子:
Class.forName("jdbc.mysql.Driver");

@Test(expected = ClassNotFoundException.class) 
public void test1() { 
    Class.forName("jdbc.mysql.Driver");
}


Parameterized Tests

    参数化测试允许使用不同的值反复运行同一个测试。可以按照以下步骤来创建参数化测试:
用 @RunWith(Parameterized.class) 来注释 test 类;
创建一个由 @Parameters 注释的公共的静态方法,它返回一个对象的集合(数组)来作为测试数据集合;
创建一个公共的构造函数,它接受和一行测试数据相等同的东西;
为每一列测试数据创建一个实例变量;
用实例变量作为测试数据的来源来创建你的测试用例;


例子:
public class Test123 { //被测试类

	private Integer a;
	private Integer b;

	public int add(int a, int b) { //
		return a + b;
	}
}

@RunWith(Parameterized.class)
public class TestCase { //使用参数化的 测试用例

	private Integer input1;
	private Integer input2;
	private Integer result;

	public TestCase(Integer a, Integer b, Integer c) {
		this.input1 = a;
		this.input2 = b;
		this.result = c;
	}

	@Parameters
	public static Collection addNumbers() {
		return Arrays.asList(new Object[][] { { 1, 2, 3 }, { -6, -3, -9 },
				{ 1, -6, -5 }, { 2, 0, 6 }, { 99, 9, 108 } });
	}

	@Test
	public void test1() {

		Test123 t =new Test123();
		assertEquals(result.intValue(), t.add(input1, input2));
	}
}




Rules
@ClassRule
public static Service service = Service.getInstance(); //必须是静态的

@Rule
public Service tmp = service;

@ClassRule:set up the external resource in your example.
@Rule:resetting the resource in that example.














    
参考:
          http://wiki.jikexueyuan.com/project/junit/
          http://junit.org/junit4/
          http://stackoverflow.com/questions/20767486/combining-classrule-and-rule-in-junit-4-11

注:



猜你喜欢

转载自blog.csdn.net/ggf123456789/article/details/61200635
今日推荐