1 Junit概述
JUnit是Java编程语言的单元测试框架。 JUnit在开发测试驱动开发方面一直非常重要,xUnit的单元测试框架系列之一就源于JUnit。
本教程解释了在使用Java时使用JUnit进行项目单元测试的过程。 完成本教程后,您将获得足够的使用JUnit测试框架的知识,从那里您可以将自己带到下一个级别。
测试是检查应用程序的功能以确保其按照要求运行的过程。 单元测试在开发人员的层面出现; 它是对单个实体(类或方法)的测试。 单元测试在帮助软件公司向客户提供高质量产品方面发挥着关键作用。
单元测试可以通过两种方式完成 - 手动测试和自动测试。
手动测试(Manual Testing) | 自动测试(Automated Testing) |
无需任何工具支持手动执行测试用例称为手动测试。 | 采用工具支持并使用自动化工具执行测试用例称为自动化测试。 |
费时费力 - 由于测试用例是由人力资源执行的,因此它非常缓慢且乏味。 | 快速 - 自动化运行测试用例的速度明显快于人力资源。 |
巨大的人力资源投资 - 由于测试用例需要手动执行,所以需要更多测试人员进行手动测试。 | 减少对人力资源的投资 - 测试案例使用自动化工具执行,因此自动化测试需要的测试人员数量较少。 |
不太可靠 - 手动测试不太可靠,因为它必须考虑到人为错误。 | 更可靠 - 自动化测试精确可靠。 |
不可编程 - 编写程序无法编写复杂的测试来获取隐藏的信息。 | 可编程 - 测试人员可以编制复杂的测试来显示隐藏的信息。 |
1、Junit是什么
JUnit是Java编程语言的单元测试框架。 它在测试驱动开发中发挥着至关重要的作用,并且是统称为xUnit的单元测试框架系列。
JUnit提出了“首先测试然后编码”(first testing then coding)的概念,它强调为一段可以先测试然后实现的代码设置测试数据。 这种方法就像“测试一点,编码一点,测试一点,编码一点”。 它提高了程序员的生产力和程序代码的稳定性,从而减少了程序员的压力和调试时间。
2.Junit的特性
JUnit是一个开源框架,用于编写和运行测试。
提供注释以识别测试方法。
提供测试预期结果的断言。
为运行测试提供测试运行程序。
JUnit测试允许您更快地编写代码,从而提高质量。
JUnit非常简单。 它不那么复杂,花费的时间也更少。
JUnit测试可以自动运行,并检查自己的结果并提供即时反馈。 无需手动梳理测试结果报告。
JUnit测试可以组织到包含测试用例甚至其他测试套件的测试套件中。
如果测试运行平稳,JUnit将在条形图中显示测试进度,当测试失败时,它会变为红色。
3、什么是单元测试用例
单元测试用例是代码的一部分,它确保代码(方法)的另一部分按预期工作。 为了快速达到预期的结果,需要一个测试框架。 JUnit是Java编程语言的完美单元测试框架。
正式的书面单元测试用例的特点是已知的输入和预期的输出,在测试执行之前计算出来。 已知输入应测试前提条件,预期输出应测试后置条件。
对于每个要求必须至少有两个单元测试用例 - 一个是正面测试和一个是否定测试。 如果需求具有子要求,则每个子要求必须至少有两个测试用例,分别是正面和负面。
2 环境设置
本地环境设置
JUnit是Java的框架,所以首要的要求是在你的机器上安装JDK。
系统需求:
JDK:1.5或者更高。
第1步:验证您的计算机中的Java安装
OS | Task | Command |
Windows | Open Command Console | c:\> java -version |
Linux | Open Command Terminal | $ java -version |
Mac | Open Terminal | machine:~ joseph$ java -version |
如果您的系统上未安装Java,请从以下链接https://www.oracle.com下载Java软件开发工具包(SDK)。 我们假设Java 1.8.0_101为本教程的安装版本。
第2步:配置Java环境变量
将JAVA_HOME环境变量设置为指向计算机上安装Java的基本目录位置。 例如。
OS | Output |
Windows | Set the environment variable JAVA_HOME to C:\Program Files\Java\jdk1.8.0_101 |
Linux | export JAVA_HOME = /usr/local/java-current |
Mac | export JAVA_HOME = /Library/Java/Home |
将Java编译器位置追加到系统路径。
OS | Output |
Windows | Append the string C:\Program Files\Java\jdk1.8.0_101\binat the end of the system variable, Path. |
Linux | export PATH = $PATH:$JAVA_HOME/bin/ |
Mac | not required |
如上所述,使用命令java -version验证Java安装。
第3步:下载JUnit
从http://www.junit.org下载最新版本的JUnit jar文件。 在编写本教程时,我们已经下载了Junit-4.12.jar并将其复制到C:\> JUnit文件夹中。
OS | Archive name |
Windows | junit4.12.jar |
Linux | junit4.12.jar |
Mac | junit4.12.jar |
第4步:设置JUnit环境
将JUNIT_HOME环境变量设置为指向计算机上存储JUNIT JAR的基本目录位置。 假设我们已经在JUNIT文件夹中存储了junit4.12.jar。
Sr.No | OS & Description |
1 | Windows Set the environment variable JUNIT_HOME to C:\JUNIT |
2 | Linux export JUNIT_HOME = /usr/local/JUNIT |
3 | Mac export JUNIT_HOME = /Library/JUNIT |
第5步:设置CLASSPATH变量
将CLASSPATH环境变量设置为指向JUNIT jar位置。
Sr.No | OS & Description |
1 | Windows Set the environment variable CLASSPATH to %CLASSPATH%;%JUNIT_HOME%\junit4.12.jar;.; |
2 | Linux export CLASSPATH = $CLASSPATH:$JUNIT_HOME/junit4.12.jar:. |
3 | Mac export CLASSPATH = $CLASSPATH:$JUNIT_HOME/junit4.12.jar:. |
第6步:测试JUnit安装程序
在C:\> JUNIT_WORKSPACE中创建一个java类文件名TestJunit
import org.junit.Test; import static org.junit.Assert.assertEquals; public class TestJunit { @Test public void testAdd() { String str = "Junit is working fine"; assertEquals("Junit is working fine",str); } } |
在C:\> JUNIT_WORKSPACE中创建一个Java类文件名TestRunner来执行测试用例。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure; public class TestRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(TestJunit.class); for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); } System.out.println(result.wasSuccessful()); } } |
第7步:验证结果
使用javac编译器编译类如下 -
C:\JUNIT_WORKSPACE>javac TestJunit.java TestRunner.java |
现在运行Test Runner来查看结果如下 -
C:\JUNIT_WORKSPACE>java TestRunner |
验证输出。
true |
3、测试框架
JUnit是一个回归测试框架,由开发人员用Java实现单元测试,并加快编程速度并提高代码质量。 JUnit Framework可以很容易地与以下任何一种集成 -
Eclipse、Ant、Maven、Idea。
单元测试框架的特性
JUnit测试框架提供了以下重要功能 -
赛程(Fixtures)
测试套件(Test suites)
试跑者(Test runner)
JUnit类(Junit classes)
Fixtures
Fixtures是一组对象的固定状态,用作运行测试的基准。 测试夹具的目的是确保有一个众所周知的固定环境,在该环境中运行测试,以便结果可重复使用。 它包括 -
setUp()方法,它在每次测试调用之前运行。
tearDown()方法,它在每个测试方法之后运行。
让我们来看一个例子 -
import junit.framework.*;
public class JavaTest extends TestCase { protected int value1, value2;
// assigning the values protected void setUp(){ value1 = 3; value2 = 3; }
// test method to add two values public void testAdd(){ double result = value1 + value2; assertTrue(result == 6); } } |
Test suites
测试套件捆绑了几个单元测试用例并将它们一起运行。 在JUnit中,@RunWith和@Suite注释都用于运行套件测试。 下面给出的是使用TestJunit1&TestJunit2测试类的示例。
import org.junit.runner.RunWith; import org.junit.runners.Suite;
//JUnit Suite Test @RunWith(Suite.class)
@Suite.SuiteClasses({ TestJunit1.class ,TestJunit2.class })
public class JunitTestSuite { } |
import org.junit.Test; import org.junit.Ignore; import static org.junit.Assert.assertEquals;
public class TestJunit1 {
String message = "Robert"; MessageUtil messageUtil = new MessageUtil(message);
@Test public void testPrintMessage() { System.out.println("Inside testPrintMessage()"); assertEquals(message, messageUtil.printMessage()); } } |
import org.junit.Test; import org.junit.Ignore; import static org.junit.Assert.assertEquals;
public class TestJunit2 {
String message = "Robert"; MessageUtil messageUtil = new MessageUtil(message);
@Test public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()"); message = "Hi!" + "Robert"; assertEquals(message,messageUtil.salutationMessage()); } } |
Test Runners
测试运行器用于执行测试用例。 这里是一个假设测试类TestJunit已经存在的例子。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
Junit Classes
JUnit类是重要的类,用于编写和测试JUnit。 一些重要的课程是 -
Assert - 包含一组断言方法。
TestCase - 包含一个测试用例,用于定义运行多个测试的灯具。
TestResult - 包含收集执行测试用例结果的方法。
4、基本用法
现在让我们有一个基本示例来演示使用JUnit的分步过程。
1、创建一个类
创建一个要测试的Java类,例如C:\> JUNIT_WORKSPACE中的MessageUtil.java。
/* * This class prints the given message on console. */
public class MessageUtil {
private String message;
//Constructor //@param message to be printed
public MessageUtil(String message){ this.message = message; }
// prints the message public String printMessage(){ System.out.println(message); return message; } } |
2、创建测试用例类
创建一个java测试类,比如TestJunit.java。
将测试方法testPrintMessage()添加到您的测试类。
向方法testPrintMessage()添加Annotaion @Test。
实现测试条件并使用JUnit的assertEquals API检查条件。
在C:\> JUNIT_WORKSPACE中创建一个java类文件名TestJunit.java。
import org.junit.Test; import static org.junit.Assert.assertEquals;
public class TestJunit {
String message = "Hello World"; MessageUtil messageUtil = new MessageUtil(message);
@Test public void testPrintMessage() { assertEquals(message,messageUtil.printMessage()); } } |
3、创建Test Runner类
创建一个TestRunner java类。
使用JUnitCore类的runClasses方法运行上面创建的测试类的测试用例。
获取Result Object中运行的测试用例的结果。
使用Result对象的getFailures()方法获取失败。
使用Result对象的wasSuccessful()方法获取成功结果。
在C:\> JUNIT_WORKSPACE中创建一个名为TestRunner.java的java类文件来执行测试用例。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
使用javac编译MessageUtil,测试用例和测试运行器类。
C:\JUNIT_WORKSPACE>javac MessageUtil.java TestJunit.java TestRunner.java |
现在运行Test Runner,它将运行提供的Test Case类中定义的测试用例。
C:\JUNIT_WORKSPACE>java TestRunner |
验证输出
Hello World true |
现在更新C:\> JUNIT_WORKSPACE中的TestJunit,以便测试失败。 更改消息字符串。
import org.junit.Test; import static org.junit.Assert.assertEquals;
public class TestJunit {
String message = "Hello World"; MessageUtil messageUtil = new MessageUtil(message);
@Test public void testPrintMessage() { message = "New Word"; assertEquals(message,messageUtil.printMessage()); } } |
让我们按照原样保留其余的类,并尝试运行相同的测试运行器。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) { Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
现在运行Test Runner,它将运行提供的Test Case类中定义的测试用例。
C:\JUNIT_WORKSPACE>java TestRunner |
验证输出
Hello World testPrintMessage(TestJunit): expected:<[New Wor]d> but was:<[Hello Worl]d> false |
5 Junit API
JUnit中最重要的包是junit.framework,它包含所有核心类。 一些重要的课程如下 -
Sr.No. | Class Name | Functionality |
1 | Assert | 一组断言方法. |
2 | TestCase | 测试用例定义了运行多个测试的赛程(fixture). |
3 | TestResult | TestResult收集执行测试用例的结果. |
4 | TestSuite | TestSuite是测试的组合。 |
1、Assert Class
以下是org.junit.Assert类的声明 -
public class Assert extends java.lang.Object |
该类提供了一组用于编写测试的断言方法。 只记录失败的断言。 Assert类的一些重要方法如下 -
Sr.No. | Methods & Description |
1 | void assertEquals(boolean expected, boolean actual) 检查两个基元/对象是否相等。 |
2 | void assertFalse(boolean condition) 检查条件是否为假。 |
3 | void assertNotNull(Object object) 检查一个对象不为null。 |
4 | void assertNull(Object object) 检查一个对象为null。 |
5 | void assertTrue(boolean condition) 检查条件是否为真。 |
6 | void fail() 没有消息的测试失败。 |
在示例中,我们使用一些上述方法。 在C:\> JUNIT_WORKSPACE中创建一个名为TestJunit1.java的java类文件。
import org.junit.Test; import static org.junit.Assert.*;
public class TestJunit1 { @Test public void testAdd() { //test data int num = 5; String temp = null; String str = "Junit is working fine";
//check for equality assertEquals("Junit is working fine", str);
//check for false condition assertFalse(num > 6);
//check for not null value assertNotNull(str); } } |
接下来,在C:\> JUNIT_WORKSPACE中创建一个名为TestRunner1.java的java类文件来执行测试用例。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner1 { public static void main(String[] args) { Result result = JUnitCore.runClasses(TestJunit1.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
使用javac编译测试用例和测试运行器类。
C:\JUNIT_WORKSPACE>javac TestJunit1.java TestRunner1.java |
现在运行Test Runner,它将运行提供的Test Case类中定义的测试用例。
C:\JUNIT_WORKSPACE>java TestRunner1 |
验证输出
true |
2、TestCase类
以下是org.junit.TestCase类的声明 -
public abstract class TestCase extends Assert implements Test |
测试用例定义了灯具运行多个测试。 TestCase类的一些重要方法如下 -
Sr.No. | Methods & Description |
1 | int countTestCases() 统计run运行的测试用例的数量(TestResult结果)。 |
2 | TestResult createResult() 创建一个默认的TestResult对象。 |
3 | String getName() 获取TestCase的名称。 |
4 | TestResult run() 运行此测试的便捷方法,使用默认的TestResult对象收集结果。 |
5 | void run(TestResult result) 运行测试用例并在TestResult中收集结果。 |
6 | void setName(String name) 设置TestCase的名称。 |
7 | void setUp() 设置夹具,例如打开网络连接。 |
8 | void tearDown() 例如,关闭网络连接就可以拆卸夹具。 |
9 | String toString() 返回测试用例的字符串表示形式。 |
在示例中,我们使用一些上述方法。 在C:\> JUNIT_WORKSPACE中创建一个名为TestJunit2.java的java类文件。
import junit.framework.TestCase; import org.junit.Before; import org.junit.Test;
public class TestJunit2 extends TestCase { protected double fValue1; protected double fValue2;
@Before public void setUp() { fValue1 = 2.0; fValue2 = 3.0; }
@Test public void testAdd() { //count the number of test cases System.out.println("No of Test Case = "+ this.countTestCases());
//test getName String name = this.getName(); System.out.println("Test Case Name = "+ name);
//test setName this.setName("testNewAdd"); String newName = this.getName(); System.out.println("Updated Test Case Name = "+ newName); }
//tearDown used to close the connection or clean up activities public void tearDown( ) { } } |
接下来,在C:\> JUNIT_WORKSPACE中创建一个名为TestRunner2.java的java类文件来执行测试用例。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner2 { public static void main(String[] args) { Result result = JUnitCore.runClasses(TestJunit2.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
使用javac编译测试用例和测试运行器类。
C:\JUNIT_WORKSPACE>javac TestJunit2.java TestRunner2.java |
现在运行Test Runner,它将运行提供的Test Case类中定义的测试用例。
C:\JUNIT_WORKSPACE>java TestRunner2 |
验证输出
No of Test Case = 1 Test Case Name = testAdd Updated Test Case Name = testNewAdd true |
3、TestResult类
以下是org.junit.TestResult类的声明 -
public class TestResult extends Object |
TestResult收集执行测试用例的结果。 它是收集参数模式的一个实例。 测试框架区分故障和错误。 预测失败并通过断言进行检查。 错误是无法预料的问题,例如ArrayIndexOutOfBoundsException。 TestResult类的一些重要方法如下 -
Sr.No. | Methods & Description |
1 | void addError(Test test, Throwable t) 将错误添加到错误列表。 |
2 | void addFailure(Test test, AssertionFailedError t) 将故障添加到故障列表。 |
3 | void endTest(Test test) 通知测试已完成的结果。 |
4 | int errorCount() 获取检测到的错误数。 |
5 | Enumeration<TestFailure> errors() 返回错误的枚举。 |
6 | int failureCount() 获取检测到的失败次数。 |
7 | void run(TestCase test) 运行一个TestCase。 |
8 | int runCount() 获取运行测试的数量。 |
9 | void startTest(Test test) 通知测试将开始的结果。 |
10 | void stop() 标志着测试运行应该停止。 |
在C:\> JUNIT_WORKSPACE中创建一个名为TestJunit3.java的java类文件。
import org.junit.Test; import junit.framework.AssertionFailedError; import junit.framework.TestResult;
public class TestJunit3 extends TestResult { // add the error public synchronized void addError(Test test, Throwable t) { super.addError((junit.framework.Test) test, t); }
// add the failure public synchronized void addFailure(Test test, AssertionFailedError t) { super.addFailure((junit.framework.Test) test, t); }
@Test public void testAdd() { // add any test }
// Marks that the test run should stop. public synchronized void stop() { //stop the test here } } |
接下来,在C:\> JUNIT_WORKSPACE中创建一个名为TestRunner3.java的java类文件来执行测试用例。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner3 { public static void main(String[] args) { Result result = JUnitCore.runClasses(TestJunit3.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
使用javac编译测试用例和测试运行器类。
C:\JUNIT_WORKSPACE>javac TestJunit3.java TestRunner3.java |
现在运行Test Runner,它将运行提供的Test Case类中定义的测试用例。
C:\JUNIT_WORKSPACE>java TestRunner3 |
验证输出
true |
4、TestSuite类
以下是org.junit.TestSuite类的声明:
public class TestSuite extends Object implements Test |
TestSuite是测试的综合。 它运行一系列测试用例。 TestSuite类的一些重要方法如下 -
Sr.No. | Methods & Description |
1 | void addTest(Test test) 向套件添加测试。 |
2 | void addTestSuite(Class<? extends TestCase> testClass) 将给定类中的测试添加到套件中。 |
3 | int countTestCases() 计算将由此测试运行的测试用例的数量。 |
4 | String getName() 返回套件的名称。 |
5 | void run(TestResult result) 运行测试并将其结果收集到TestResult中。 |
6 | void setName(String name) 设置套件的名称。 |
7 | Test testAt(int index) 返回给定索引处的测试。 |
8 | int testCount() 返回此套件中的测试数量。 |
9 | static Test warning(String message) 返回将失败的测试并记录警告消息。 |
在C:\> JUNIT_WORKSPACE中创建一个名为JunitTestSuite.java的Java类文件来创建测试套件。
import junit.framework.*;
public class JunitTestSuite { public static void main(String[] a) { // add the test's in the suite TestSuite suite = new TestSuite(TestJunit1.class, TestJunit2.class, TestJunit3.class ); TestResult result = new TestResult(); suite.run(result); System.out.println("Number of test cases = " + result.runCount()); } } |
使用javac编译测试套件类。
C:\JUNIT_WORKSPACE>javac JunitTestSuite.java |
现在运行测试套件。
C:\JUNIT_WORKSPACE>java JunitTestSuite |
验证输出
No of Test Case = 1 Test Case Name = testAdd Updated Test Case Name = testNewAdd Number of test cases = 3 |
6 测试类
在这里,我们将看到使用POJO类,业务逻辑类和测试类的JUnit测试的一个完整示例,它将由测试运行器运行。
在C:\> JUNIT_WORKSPACE中创建EmployeeDetails.java,这是一个POJO类。
public class EmployeeDetails {
private String name; private double monthlySalary; private int age;
/** * @return the name */
public String getName() { return name; }
/** * @param name the name to set */
public void setName(String name) { this.name = name; }
/** * @return the monthlySalary */
public double getMonthlySalary() { return monthlySalary; }
/** * @param monthlySalary the monthlySalary to set */
public void setMonthlySalary(double monthlySalary) { this.monthlySalary = monthlySalary; }
/** * @return the age */ public int getAge() { return age; }
/** * @param age the age to set */ public void setAge(int age) { this.age = age; } } |
EmployeeDetails类用于 -
获取/设置员工姓名的值。
获取/设置员工月薪的值。
获取/设置员工年龄的值。
在C:\> JUNIT_WORKSPACE中创建一个名为EmpBusinessLogic.java的文件,其中包含业务逻辑。
public class EmpBusinessLogic { // Calculate the yearly salary of employee public double calculateYearlySalary(EmployeeDetails employeeDetails) { double yearlySalary = 0; yearlySalary = employeeDetails.getMonthlySalary() * 12; return yearlySalary; }
// Calculate the appraisal amount of employee public double calculateAppraisal(EmployeeDetails employeeDetails) { double appraisal = 0;
if(employeeDetails.getMonthlySalary() < 10000){ appraisal = 500; }else{ appraisal = 1000; }
return appraisal; } } |
EmpBusinessLogic类用于计算 -
雇员的年薪。
员工的评估金额。
在C:\> JUNIT_WORKSPACE中创建一个名为TestEmployeeDetails.java的文件,该文件包含要测试的测试用例。
import org.junit.Test; import static org.junit.Assert.assertEquals;
public class TestEmployeeDetails { EmpBusinessLogic empBusinessLogic = new EmpBusinessLogic(); EmployeeDetails employee = new EmployeeDetails();
//test to check appraisal @Test public void testCalculateAppriasal() { employee.setName("Rajeev"); employee.setAge(25); employee.setMonthlySalary(8000);
double appraisal = empBusinessLogic.calculateAppraisal(employee); assertEquals(500, appraisal, 0.0); }
// test to check yearly salary @Test public void testCalculateYearlySalary() { employee.setName("Rajeev"); employee.setAge(25); employee.setMonthlySalary(8000);
double salary = empBusinessLogic.calculateYearlySalary(employee); assertEquals(96000, salary, 0.0); } } |
TestEmployeeDetails类用于测试EmpBusinessLogic类的方法。 它
测试员工的年薪。
测试员工的评估数量。
接下来,在C:\> JUNIT_WORKSPACE中创建一个名为TestRunner.java的java类文件来执行测试用例。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(TestEmployeeDetails.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
使用javac编译测试用例和测试运行器类。
C:\JUNIT_WORKSPACE>javac EmployeeDetails.java EmpBusinessLogic.java TestEmployeeDetails.java TestRunner.java |
现在运行Test Runner,它将运行提供的Test Case类中定义的测试用例。
C:\JUNIT_WORKSPACE>java TestRunner |
验证输出
true |
7 使用断言
1、Assertion
所有的断言都在Assert类中。
public class Assert extends java.lang.Object |
这个类提供了一组断言方法,对编写测试有用。 只记录失败的断言。 Assert类的一些重要方法如下 -
Sr.No. | Methods & Description |
1 | void assertEquals(boolean expected, boolean actual) 检查两个基元/对象是否相等。 |
2 | void assertTrue(boolean condition) 检查条件是否成立。 |
3 | void assertFalse(boolean condition) 检查条件是否为假。 |
4 | void assertNotNull(Object object) 检查一个对象是否为空。 |
5 | void assertNull(Object object) 检查一个对象是否为空。 |
6 | void assertSame(object1, object2) assertSame()方法测试两个对象引用是否指向同一个对象。 |
7 | void assertNotSame(object1, object2) assertNotSame()方法测试两个对象引用是否不指向同一个对象。 |
8 | void assertArrayEquals(expectedArray, resultArray); assertArrayEquals()方法将测试两个数组是否彼此相等。 |
在示例中,我们使用一些上述方法。 在C:\> JUNIT_WORKSPACE中创建一个名为TestAssertions.java的java类文件。
import org.junit.Test; import static org.junit.Assert.*;
public class TestAssertions {
@Test public void testAssertions() { //test data String str1 = new String ("abc"); String str2 = new String ("abc"); String str3 = null; String str4 = "abc"; String str5 = "abc";
int val1 = 5; int val2 = 6;
String[] expectedArray = {"one", "two", "three"}; String[] resultArray = {"one", "two", "three"};
//Check that two objects are equal assertEquals(str1, str2);
//Check that a condition is true assertTrue (val1 < val2);
//Check that a condition is false assertFalse(val1 > val2);
//Check that an object isn't null assertNotNull(str1);
//Check that an object is null assertNull(str3);
//Check if two object references point to the same object assertSame(str4,str5);
//Check if two object references not point to the same object assertNotSame(str1,str3);
//Check whether two arrays are equal to each other. assertArrayEquals(expectedArray, resultArray); } } |
接下来,在C:\> JUNIT_WORKSPACE中创建一个名为TestRunner.java的java类文件来执行测试用例。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner2 { public static void main(String[] args) { Result result = JUnitCore.runClasses(TestAssertions.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
使用javac编译测试用例和测试运行器类。
C:\JUNIT_WORKSPACE>javac TestAssertions.java TestRunner.java |
现在运行Test Runner,它将运行提供的Test Case类中定义的测试用例。
C:\JUNIT_WORKSPACE>java TestRunner |
验证输出
true |
2、Annotation(注解)
注解就像元标签一样,您可以将其添加到代码中,并将其应用于方法或类中。 JUnit中的这些注释提供了有关测试方法的以下信息 -
哪些方法将在测试方法之前和之后运行。
哪些方法在所有方法之前和之后运行,以及。
在执行过程中哪些方法或类将被忽略。
下表提供了JUnit中的注解列表及其含义 -
Sr.No. | Annotation & Description |
1 | @Test Test注解告诉JUnit它所连接的public void方法可以作为测试用例运行。 |
2 | @Before 几个测试需要在运行之前创建类似的对象。 使用@Before注释一个公共无效方法会导致该方法在每个Test方法之前运行。 |
3 | @After 如果您在Before方法中分配外部资源,则需要在测试运行后释放它们。 使用@After注释一个公共无效方法会导致该方法在Test方法之后运行。 |
4 | @BeforeClass 使用@BeforeClass注释公共静态void方法会导致它在该类中的任何测试方法之前运行一次。 |
5 | @AfterClass 这将在所有测试完成后执行该方法。 这可以用来执行清理活动。 |
6 | @Ignore Ignore注释用于忽略测试,并且该测试不会执行。 |
在C:\> JUNIT_WORKSPACE中创建一个名为JunitAnnotation.java的java类文件来测试注释。
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 JunitAnnotation {
//execute before class @BeforeClass public static void beforeClass() { System.out.println("in before class"); }
//execute after class @AfterClass public static void afterClass() { System.out.println("in after class"); }
//execute before test @Before public void before() { System.out.println("in before"); }
//execute after test @After public void after() { System.out.println("in after"); }
//test case @Test public void test() { System.out.println("in test"); }
//test case ignore and will not execute @Ignore public void ignoreTest() { System.out.println("in ignore test"); } } |
接下来,在C:\> JUNIT_WORKSPACE中创建一个名为TestRunner.java的java类文件来执行注释。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(JunitAnnotation.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
使用javac编译测试用例和测试运行器类。
C:\JUNIT_WORKSPACE>javac JunitAnnotation.java TestRunner.java |
现在运行Test Runner,它将运行提供的Test Case类中定义的测试用例。
C:\JUNIT_WORKSPACE>java TestRunner |
验证输出
in before class in before in test in after in after class true |
8、执行过程
本章介绍JUnit中方法的执行过程,它定义了调用方法的顺序。 以下讨论的是以示例为例的JUnit测试API方法的执行过程。
在C:\> JUNIT_WORKSPACE中创建一个名为ExecutionProcedureJunit.java的java类文件来测试注释。
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 ExecutionProcedureJunit {
//execute only once, in the starting @BeforeClass public static void beforeClass() { System.out.println("in before class"); }
//execute only once, in the end @AfterClass public static void afterClass() { System.out.println("in after class"); }
//execute for each test, before executing test @Before public void before() { System.out.println("in before"); }
//execute for each test, after executing test @After public void after() { System.out.println("in after"); }
//test case 1 @Test public void testCase1() { System.out.println("in test case 1"); }
//test case 2 @Test public void testCase2() { System.out.println("in test case 2"); } } |
接下来,在C:\> JUNIT_WORKSPACE中创建一个名为TestRunner.java的java类文件来执行注释。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(ExecutionProcedureJunit.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
使用javac编译测试用例和测试运行器类。
C:\JUNIT_WORKSPACE>javac ExecutionProcedureJunit.java TestRunner.java |
现在运行Test Runner,它将运行提供的Test Case类中定义的测试用例。
C:\JUNIT_WORKSPACE>java TestRunner |
验证输出
in before class in before in test case 1 in after in before in test case 2 in after in after class |
看到上面的输出。 执行程序如下 -
首先,beforeClass()方法只执行一次。
afterClass()方法只执行一次。
before()方法针对每个测试用例执行,但在执行测试用例之前执行。
after()方法针对每个测试用例执行,但在执行测试用例之后执行。
在before()和after()之间,执行每个测试用例。
9 执行测试
测试用例使用JUnitCore类来执行。 JUnitCore是用于运行测试的外观。 它支持运行JUnit 4测试,JUnit 3.8.x测试和混合。 要从命令行运行测试,请运行java org.junit.runner.JUnitCore <TestClass>。 对于一次性测试运行,请使用静态方法runClasses(Class [])。
以下是org.junit.runner.JUnitCore类的声明:
public class JUnitCore extends java.lang.Object |
这里我们将看到如何在JUnitCore的帮助下执行测试。
1、创建一个类
在C:\> JUNIT_WORKSPACE中创建一个要测试的Java类,例如MessageUtil.java。
/* * This class prints the given message on console. */
public class MessageUtil {
private String message;
//Constructor //@param message to be printed public MessageUtil(String message){ this.message = message; }
// prints the message public String printMessage(){ System.out.println(message); return message; }
} |
2、创建测试用例类
创建一个java测试类,比如TestJunit.java。
将测试方法testPrintMessage()添加到您的测试类。
在方法testPrintMessage()中添加Annotaion @Test。
实现测试条件并使用JUnit的assertEquals API检查条件。
在C:\> JUNIT_WORKSPACE中创建一个名为TestJunit.java的java类文件。
import org.junit.Test; import static org.junit.Assert.assertEquals;
public class TestJunit {
String message = "Hello World"; MessageUtil messageUtil = new MessageUtil(message);
@Test public void testPrintMessage() { assertEquals(message,messageUtil.printMessage()); } } |
3、创建一个Test Runner类
现在在C:\> JUNIT_WORKSPACE中创建一个名为TestRunner.java的java类文件来执行测试用例。 它导入JUnitCore类并使用将测试类名称作为其参数的runClasses()方法。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
使用javac编译测试用例和测试运行器类。
C:\JUNIT_WORKSPACE>javac MessageUtil.java TestJunit.java TestRunner.java |
现在运行Test Runner,它将运行提供的Test Case类中定义的测试用例。
C:\JUNIT_WORKSPACE>java TestRunner |
验证输出
Hello World true |
10、套件测试
测试套件用于捆绑几个单元测试用例并将它们一起运行。 在JUnit中,@RunWith和@Suite注释都用于运行套件测试。 本章举例说明了使用Test Suite一起运行的两个测试类TestJunit1和TestJunit2。
1、创建一个类
创建一个要测试的Java类,例如C:\> JUNIT_WORKSPACE中的MessageUtil.java。
/* * This class prints the given message on console. */
public class MessageUtil {
private String message;
//Constructor //@param message to be printed public MessageUtil(String message){ this.message = message; }
// prints the message public String printMessage(){ System.out.println(message); return message; }
// add "Hi!" to the message public String salutationMessage(){ message = "Hi!" + message; System.out.println(message); return message; } } |
2、创建测试用例类
在C:\> JUNIT_WORKSPACE中创建一个名为TestJunit1.java的java类文件。
import org.junit.Test; import org.junit.Ignore; import static org.junit.Assert.assertEquals;
public class TestJunit1 {
String message = "Robert"; MessageUtil messageUtil = new MessageUtil(message);
@Test public void testPrintMessage() { System.out.println("Inside testPrintMessage()"); assertEquals(message, messageUtil.printMessage()); } } |
在C:\> JUNIT_WORKSPACE中创建一个名为TestJunit2.java的java类文件。
import org.junit.Test; import org.junit.Ignore; import static org.junit.Assert.assertEquals;
public class TestJunit2 {
String message = "Robert"; MessageUtil messageUtil = new MessageUtil(message);
@Test public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()"); message = "Hi!" + "Robert"; assertEquals(message,messageUtil.salutationMessage()); } } |
3、创建测试套件类
创建一个java类。
附加@RunWith(Suite.class)注解与类。
使用@SuiteSuiteClasses注释添加对JUnit测试类的引用。
在C:\> JUNIT_WORKSPACE中创建一个名为TestSuite.java的java类文件来执行测试用例。
import org.junit.runner.RunWith; import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({ TestJunit1.class, TestJunit2.class })
public class JunitTestSuite { } |
4、创建Test Runner类
在C:\> JUNIT_WORKSPACE中创建一个名为TestRunner.java的java类文件来执行测试用例。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(JunitTestSuite.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
使用javac编译所有的java类。
C:\JUNIT_WORKSPACE>javac MessageUtil.java TestJunit1.java TestJunit2.java JunitTestSuite.java TestRunner.java |
现在运行Test Runner,它将运行提供的Test Case类中定义的测试用例。
C:\JUNIT_WORKSPACE>java TestRunner |
验证输出
Inside testPrintMessage() Robert Inside testSalutationMessage() Hi Robert true |
11 忽略测试
有时会发生我们的代码在运行测试用例时没有完全准备好的情况。 结果,测试用例失败。 @Ignore注释有助于在这种情况下。
用@Ignore注释的测试方法将不会执行。
如果一个测试类用@Ignore注释,那么它的测试方法都不会被执行。
现在让我们看看@Ignore的行动。
1、创建一个类
创建一个要测试的Java类,例如C:\> JUNIT_WORKSPACE中的MessageUtil.java。
/* * This class prints the given message on console. */
public class MessageUtil {
private String message;
//Constructor //@param message to be printed public MessageUtil(String message){ this.message = message; }
// prints the message public String printMessage(){ System.out.println(message); return message; }
// add "Hi!" to the message public String salutationMessage(){ message = "Hi!" + message; System.out.println(message); return message; }
} |
2、创建一个测试类
创建一个java测试类,比如TestJunit.java。
将测试方法testPrintMessage()或testSalutationMessage()添加到您的测试类。
将方法testPrintMessage()添加Annotaion @Ignore。
在C:\ JUNIT_WORKSPACE中创建一个名为TestJunit.java的java类文件。
import org.junit.Test; import org.junit.Ignore; import static org.junit.Assert.assertEquals;
public class TestJunit {
String message = "Robert"; MessageUtil messageUtil = new MessageUtil(message);
@Ignore @Test public void testPrintMessage() { System.out.println("Inside testPrintMessage()"); message = "Robert"; assertEquals(message,messageUtil.printMessage()); }
@Test public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()"); message = "Hi!" + "Robert"; assertEquals(message,messageUtil.salutationMessage()); }
} |
3、创建Test Runner类
在C:\> JUNIT_WORKSPACE中创建一个名为TestRunner.java的java类文件来执行测试用例。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
使用javac编译MessageUtil,测试用例和测试运行器类。
C:\JUNIT_WORKSPACE>javac MessageUtil.java TestJunit.java TestRunner.java |
现在运行Test Runner,它不会运行提供的Test Case类中定义的testPrintMessage()测试用例。
C:\JUNIT_WORKSPACE>java TestRunner |
验证输出。 testPrintMessage()测试用例未经测试。
Inside testSalutationMessage() Hi!Robert true |
现在,更新C:\> JUNIT_WORKSPACE中的TestJunit以忽略所有测试用例。 在课堂级添加@Ignore。
import org.junit.Test; import org.junit.Ignore; import static org.junit.Assert.assertEquals;
@Ignore public class TestJunit {
String message = "Robert"; MessageUtil messageUtil = new MessageUtil(message);
@Test public void testPrintMessage() { System.out.println("Inside testPrintMessage()"); message = "Robert"; assertEquals(message,messageUtil.printMessage()); }
@Test public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()"); message = "Hi!" + "Robert"; assertEquals(message,messageUtil.salutationMessage()); }
} |
使用javac编译测试用例。
C:\JUNIT_WORKSPACE>javac TestJunit.java |
保持你的测试运行如下 -
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
现在运行Test Runner,它不会运行提供的Test Case类中定义的任何测试用例。
C:\JUNIT_WORKSPACE>java TestRunner |
验证输出。 没有测试案例进行测试。
true |
12 时间测试
JUnit提供了Timeout的方便选项。 如果测试用例需要的时间超过指定的毫秒数,那么JUnit会自动将其标记为失败。 timeout参数与@Test注释一起使用。 让我们看看@Test(超时)的行动。
1、创建一个类
创建一个要测试的Java类,例如C:\> JUNIT_WORKSPACE中的MessageUtil.java。
在printMessage()方法内添加一个无限循环。
/* * This class prints the given message on console. */
public class MessageUtil {
private String message;
//Constructor //@param message to be printed public MessageUtil(String message){ this.message = message; }
// prints the message public void printMessage(){ System.out.println(message); while(true); }
// add "Hi!" to the message public String salutationMessage(){ message = "Hi!" + message; System.out.println(message); return message; } } |
2、创建测试用例类
创建一个java测试类,比如TestJunit.java。 向testPrintMessage()测试用例添加1000的超时值。
在C:\> JUNIT_WORKSPACE中创建一个名为TestJunit.java的java类文件。
import org.junit.Test; import org.junit.Ignore; import static org.junit.Assert.assertEquals;
public class TestJunit {
String message = "Robert"; MessageUtil messageUtil = new MessageUtil(message);
@Test(timeout = 1000) public void testPrintMessage() { System.out.println("Inside testPrintMessage()"); messageUtil.printMessage(); }
@Test public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()"); message = "Hi!" + "Robert"; assertEquals(message,messageUtil.salutationMessage()); } } |
3、创建Test Runner类
在C:\> JUNIT_WORKSPACE中创建一个名为TestRunner.java的java类文件来执行测试用例。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
使用javac编译MessageUtil,测试用例和测试运行器类。
C:\JUNIT_WORKSPACE>javac MessageUtil.java TestJunit.java TestRunner.java |
现在运行Test Runner,它将运行提供的Test Case类中定义的测试用例。
C:\JUNIT_WORKSPACE>java TestRunner |
验证输出。 testPrintMessage()测试用例会标记单元测试失败。
Inside testPrintMessage() Robert Inside testSalutationMessage() Hi!Robert testPrintMessage(TestJunit): test timed out after 1000 milliseconds false |
13 异常测试
JUnit提供了一个跟踪代码异常处理的选项。 您可以测试代码是否引发期望的异常。 期望的参数与@Test注释一起使用。 让我们看看@Test(预期)的行动。
1、创建一个类
创建一个要测试的Java类,例如C:\> JUNIT_WORKSPACE中的MessageUtil.java。
在printMessage()方法中添加一个错误条件。
/* * This class prints the given message on console. */
public class MessageUtil {
private String message;
//Constructor //@param message to be printed public MessageUtil(String message){ this.message = message; }
// prints the message public void printMessage(){ System.out.println(message); int a = 0; int b = 1/a; }
// add "Hi!" to the message public String salutationMessage(){ message = "Hi!" + message; System.out.println(message); return message; } } |
2、创建测试用例类
创建一个名为TestJunit.java的java测试类。 将预期的异常ArithmeticException添加到testPrintMessage()测试用例。
在C:\> JUNIT_WORKSPACE中创建一个名为TestJunit.java的java类文件。
import org.junit.Test; import org.junit.Ignore; import static org.junit.Assert.assertEquals;
public class TestJunit {
String message = "Robert"; MessageUtil messageUtil = new MessageUtil(message);
@Test(expected = ArithmeticException.class) public void testPrintMessage() { System.out.println("Inside testPrintMessage()"); messageUtil.printMessage(); }
@Test public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()"); message = "Hi!" + "Robert"; assertEquals(message,messageUtil.salutationMessage()); } } |
3、创建Test Runner类
在C:\> JUNIT_WORKSPACE中创建一个名为TestRunner.java的java类文件来执行测试用例。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
使用javac编译MessageUtil,测试用例和测试运行器类。
C:\JUNIT_WORKSPACE>javac MessageUtil.java TestJunit.java TestRunner.java |
现在运行Test Runner,它将运行提供的Test Case类中定义的测试用例。
C:\JUNIT_WORKSPACE>java TestRunner |
验证输出。 testPrintMessage()测试用例将被传递。
Inside testPrintMessage() Robert Inside testSalutationMessage() Hi!Robert true |
14 参数化测试
JUnit 4引入了一个名为参数化测试的新功能。 参数化测试允许开发人员使用不同的值反复运行相同的测试。 有五个步骤需要遵循以创建参数化测试。
用@RunWith(Parameterized.class)注释测试类。
创建一个使用@Parameters注释的公共静态方法,该方法返回对象集合(作为数组)作为测试数据集。
创建一个公共构造函数,它接受相当于一行“测试数据”的内容。
为测试数据的每个“列”创建一个实例变量。
使用实例变量创建测试用例作为测试数据的来源。
测试用例将针对每一行数据调用一次。 让我们看看参数化测试的实际应用。
1、创建一个类
在C:\> JUNIT_WORKSPACE中创建一个要测试的Java类,例如PrimeNumberChecker.java。
public class PrimeNumberChecker { public Boolean validate(final Integer primeNumber) { for (int i = 2; i < (primeNumber / 2); i++) { if (primeNumber % i == 0) { return false; } } return true; } } |
2、创建参数化测试用例类
创建一个java测试类,例如PrimeNumberCheckerTest.java。 在C:\> JUNIT_WORKSPACE中创建一个名为PrimeNumberCheckerTest.java的java类文件。
import java.util.Arrays; import java.util.Collection;
import org.junit.Test; import org.junit.Before;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import org.junit.runner.RunWith; import static org.junit.Assert.assertEquals;
@RunWith(Parameterized.class) public class PrimeNumberCheckerTest { private Integer inputNumber; private Boolean expectedResult; private PrimeNumberChecker primeNumberChecker;
@Before public void initialize() { primeNumberChecker = new PrimeNumberChecker(); }
// Each parameter should be placed as an argument here // Every time runner triggers, it will pass the arguments // from parameters we defined in primeNumbers() method
public PrimeNumberCheckerTest(Integer inputNumber, Boolean expectedResult) { this.inputNumber = inputNumber; this.expectedResult = expectedResult; }
@Parameterized.Parameters public static Collection primeNumbers() { return Arrays.asList(new Object[][] { { 2, true }, { 6, false }, { 19, true }, { 22, false }, { 23, true } }); }
// This test will run 4 times since we have 5 parameters defined @Test public void testPrimeNumberChecker() { System.out.println("Parameterized Number is : " + inputNumber); assertEquals(expectedResult, primeNumberChecker.validate(inputNumber)); } } |
3、创建Test Runner类
在C:\> JUNIT_WORKSPACE中创建一个名为TestRunner.java的java类文件来执行测试用例。
import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure;
public class TestRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(PrimeNumberCheckerTest.class);
for (Failure failure : result.getFailures()) { System.out.println(failure.toString()); }
System.out.println(result.wasSuccessful()); } } |
使用javac编译PrimeNumberChecker,PrimeNumberCheckerTest和Test Runner类。
C:\JUNIT_WORKSPACE>javac PrimeNumberChecker.java PrimeNumberCheckerTest.java TestRunner.java |
现在运行Test Runner,它将运行提供的Test Case类中定义的测试用例。
C:\JUNIT_WORKSPACE>java TestRunner |
验证输出
Parameterized Number is : 2 Parameterized Number is : 6 Parameterized Number is : 19 Parameterized Number is : 22 Parameterized Number is : 23 true |
15 Ant插件
我们将举一个例子演示如何使用ANT运行JUnit。 按照下面给出的步骤。
第1步:下载Apache Ant
根据您正在使用的操作系统下载Apache Ant。
OS | Archive Name |
Windows | apache-ant-1.8.4-bin.zip |
Linux | apache-ant-1.8.4-bin.tar.gz |
Mac | apache-ant-1.8.4-bin.tar.gz |
第2步:设置Ant环境
将ANT_HOME环境变量设置为指向基本目录位置,ANT库存储在您的计算机上。 让我们假设Ant库存储在文件夹apache-ant-1.8.4中。
Sr.No. | OS & Description |
1 | Windows Set the environment variable ANT_HOME to C:\Program Files\Apache Software Foundation\apache-ant-1.8.4 |
2 | Linux export ANT_HOME = /usr/local/apache-ant-1.8.4 |
3 | Mac export ANT_HOME = /Library/apache-ant-1.8.4 |
将Ant编译器位置附加到系统路径,如下所示 -
OS | Output |
Windows | Append the string %ANT_HOME\bin at the end of the system variable, Path. |
Linux | export PATH = $PATH:$ANT_HOME/bin/ |
Mac | not required |
第3步:下载JUnit
下载适合您的操作系统的JUnit存档。
OS | Archive Name |
Windows | junit4.10.jar |
Linux | junit4.10.jar |
Mac | junit4.10.jar |
第4步:创建项目结构
在C:\> JUNIT_WORKSPACE中创建一个文件夹TestJunitWithAnt。
在C:\> JUNIT_WORKSPACE> TestJunitWithAnt中创建一个文件夹src。
在C:\> JUNIT_WORKSPACE> TestJunitWithAnt中创建一个文件夹test。
在C:\> JUNIT_WORKSPACE> TestJunitWithAnt中创建一个文件夹lib。
在C:\> JUNIT_WORKSPACE> TestJunitWithAnt> srcfolder中创建MessageUtil类。
/* * This class prints the given message on console. */
public class MessageUtil {
private String message;
//Constructor //@param message to be printed public MessageUtil(String message){ this.message = message; }
// prints the message public String printMessage(){ System.out.println(message); return message; }
// add "Hi!" to the message public String salutationMessage(){ message = "Hi!" + message; System.out.println(message); return message; } } |
在文件夹C:\> JUNIT_WORKSPACE> TestJunitWithAnt> src中创建TestMessageUtil类。
import org.junit.Test; import org.junit.Ignore; import static org.junit.Assert.assertEquals;
public class TestMessageUtil {
String message = "Robert"; MessageUtil messageUtil = new MessageUtil(message);
@Test public void testPrintMessage() { System.out.println("Inside testPrintMessage()"); assertEquals(message,messageUtil.printMessage()); }
@Test public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()"); message = "Hi!" + "Robert"; assertEquals(message,messageUtil.salutationMessage()); } } |
将junit-4.10.jar复制到文件夹C:\> JUNIT_WORKSPACE> TestJunitWithAnt> lib。
创建Ant的Build.xml文件
我们将在Ant中使用<junit>任务来执行我们的JUnit测试用例。
<project name = "JunitTest" default = "test" basedir = "."> <property name = "testdir" location = "test" /> <property name = "srcdir" location = "src" /> <property name = "full-compile" value = "true" />
<path id = "classpath.base"/>
<path id = "classpath.test"> <pathelement location = "lib/junit-4.10.jar" /> <pathelement location = "${testdir}" /> <pathelement location = "${srcdir}" /> <path refid = "classpath.base" /> </path>
<target name = "clean" > <delete verbose = "${full-compile}"> <fileset dir = "${testdir}" includes = "**/*.class" /> </delete> </target>
<target name = "compile" depends = "clean"> <javac srcdir = "${srcdir}" destdir = "${testdir}" verbose = "${full-compile}"> <classpath refid = "classpath.test"/> </javac> </target>
<target name = "test" depends = "compile"> <junit> <classpath refid = "classpath.test" /> <formatter type = "brief" usefile = "false" /> <test name = "TestMessageUtil" /> </junit> </target>
</project> |
运行以下Ant命令。
C:\JUNIT_WORKSPACE\TestJunitWithAnt>ant |
验证输出
Buildfile: C:\JUNIT_WORKSPACE\TestJunitWithAnt\build.xml
clean:
compile: [javac] Compiling 2 source files to C:\JUNIT_WORKSPACE\TestJunitWithAnt\test [javac] [parsing started C:\JUNIT_WORKSPACE\TestJunitWithAnt\src\ MessageUtil.java] [javac] [parsing completed 18ms] [javac] [parsing started C:\JUNIT_WORKSPACE\TestJunitWithAnt\src\ TestMessageUtil.java] [javac] [parsing completed 2ms] [javac] [search path for source files: C:\JUNIT_WORKSPACE\ TestJunitWithAnt\src] [javac] [loading java\lang\Object.class(java\lang:Object.class)] [javac] [loading java\lang\String.class(java\lang:String.class)] [javac] [loading org\junit\Test.class(org\junit:Test.class)] [javac] [loading org\junit\Ignore.class(org\junit:Ignore.class)] [javac] [loading org\junit\Assert.class(org\junit:Assert.class)] [javac] [loading java\lang\annotation\Retention.class (java\lang\annotation:Retention.class)] [javac] [loading java\lang\annotation\RetentionPolicy.class (java\lang\annotation:RetentionPolicy.class)] [javac] [loading java\lang\annotation\Target.class (java\lang\annotation:Target.class)] [javac] [loading java\lang\annotation\ElementType.class (java\lang\annotation:ElementType.class)] [javac] [loading java\lang\annotation\Annotation.class (java\lang\annotation:Annotation.class)] [javac] [checking MessageUtil] [javac] [loading java\lang\System.class(java\lang:System.class)] [javac] [loading java\io\PrintStream.class(java\io:PrintStream.class)] [javac] [loading java\io\FilterOutputStream.class (java\io:FilterOutputStream.class)] [javac] [loading java\io\OutputStream.class(java\io:OutputStream.class)] [javac] [loading java\lang\StringBuilder.class (java\lang:StringBuilder.class)] [javac] [loading java\lang\AbstractStringBuilder.class (java\lang:AbstractStringBuilder.class)] [javac] [loading java\lang\CharSequence.class(java\lang:CharSequence.class)] [javac] [loading java\io\Serializable.class(java\io:Serializable.class)] [javac] [loading java\lang\Comparable.class(java\lang:Comparable.class)] [javac] [loading java\lang\StringBuffer.class(java\lang:StringBuffer.class)] [javac] [wrote C:\JUNIT_WORKSPACE\TestJunitWithAnt\test\MessageUtil.class] [javac] [checking TestMessageUtil] [javac] [wrote C:\JUNIT_WORKSPACE\TestJunitWithAnt\test\TestMessageUtil.class] [javac] [total 281ms]
test: [junit] Testsuite: TestMessageUtil [junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.008 sec [junit] [junit] ------------- Standard Output --------------- [junit] Inside testPrintMessage() [junit] Robert [junit] Inside testSalutationMessage() [junit] Hi!Robert [junit] ------------- ---------------- ---------------
BUILD SUCCESSFUL Total time: 0 seconds |
16 扩展
以下是JUnit扩展 -
Cactus
JWebUnit
XMLUnit
MockObject
Cactus
Cactus是一个简单的测试框架,用于单元测试服务器端Java代码(Servlets,EJBs,Tag Libs,Filters)。 Cactus的目的是降低编写服务器端代码测试的成本。 它使用JUnit并对其进行扩展。 Cactus实现了容器内的策略,在容器内执行测试。
Cactus生态系统由几个组件组成 -
Cactus框架是Cactus的核心。 它是提供API来编写Cactus测试的引擎。
Cactus集成模块是前端和框架,提供使用Cactus框架(Ant脚本,Eclipse插件和Maven插件)的简单方法。
以下代码演示了如何使用Cactus。
import org.apache.cactus.*; import junit.framework.*;
public class TestSampleServlet extends ServletTestCase { @Test public void testServlet() { // Initialize class to test SampleServlet servlet = new SampleServlet();
// Set a variable in session as the doSomething() // method that we are testing session.setAttribute("name", "value");
// Call the method to test, passing an // HttpServletRequest object (for example) String result = servlet.doSomething(request);
// Perform verification that test was successful assertEquals("something", result); assertEquals("otherValue", session.getAttribute("otherName")); } } |
JWebUnit
JWebUnit是一个基于Java的Web应用程序测试框架。 它使用统一的简单测试界面来包装HtmlUnit和Selenium等现有测试框架,以测试Web应用程序的正确性。
JWebUnit提供了一个高级Java API,用于浏览与一组断言相结合的Web应用程序,以验证应用程序的正确性。 这包括通过链接导航,表单输入和提交,表格内容验证以及其他典型的商业Web应用程序功能。
简单的导航方法和准备使用的断言允许比仅使用JUnit或HtmlUnit更快的测试创建。 如果您想从HtmlUnit切换到其他插件(如Selenium)(即将推出),则无需重新编写测试。
这是一个示例代码。
import junit.framework.TestCase; import net.sourceforge.jwebunit.WebTester;
public class ExampleWebTestCase extends TestCase { private WebTester tester;
public ExampleWebTestCase(String name) { super(name); tester = new WebTester(); }
//set base url public void setUp() throws Exception { getTestContext().setBaseUrl("http://myserver:8080/myapp"); }
// test base info @Test public void testInfoPage() { beginAt("/info.html"); } } |
XMLUnit
XMLUnit提供了一个JUnit扩展类,XMLTestCase和一组允许断言的支持类 -
两段XML之间的区别(通过Diff和DetailedDiff类)。
一段XML的有效性(通过Validator类)。
使用XSLT转换一段XML的结果(通过Transform类)。
在一段XML上评估XPath表达式(通过实现XpathEngine接口的类)。
由DOM Traversal公开的一段XML中的单个节点(通过NodeTest类)。
让我们假设我们有两段我们希望比较的XML,并断言它们是平等的。 我们可以写这样一个简单的测试课程 -
import org.custommonkey.xmlunit.XMLTestCase;
public class MyXMLTestCase extends XMLTestCase {
// this test method compare two pieces of the XML @Test public void testForXMLEquality() throws Exception { String myControlXML = "<msg><uuid>0x00435A8C</uuid></msg>"; String myTestXML = "<msg><localId>2376</localId></msg>"; assertXMLEqual("Comparing test xml to control xml", myControlXML, myTestXML); } } |
MockObject
在单元测试中,模拟对象可以模拟复杂的真实(非模拟)对象的行为,因此当真实对象不可能或不可能并入单元测试时非常有用。
用于模拟对象测试的通用编码风格是 -
创建模拟对象的实例。
在模拟对象中设置状态和期望。
以模拟对象作为参数调用域代码。
验证模拟对象的一致性。
下面给出的是使用Jmock的MockObject的一个例子。
import org.jmock.Mockery; import org.jmock.Expectations;
class PubTest extends TestCase { Mockery context = new Mockery(); public void testSubReceivesMessage() { // set up final Sub sub = context.mock(Sub.class);
Pub pub = new Pub(); pub.add(sub);
final String message = "message";
// expectations context.checking(new Expectations() { oneOf (sub).receive(message); });
// execute pub.publish(message);
// verify context.assertIsSatisfied(); } } |