在介绍junit之前,把一些知识点提前了解一下
单元测试是一个对单一实体(类或方法)的测试。
测试用例(Test Case)是为某个特殊目标而编制的一组测试输入、执行条件以及预期结果,以便测试某个程序路径或核实是否满足某个特定需求。
测试套件:通常把一组相关的测试称为一个测试套件(test suite)。
通过测试套件,将服务于同一个测试目的或同一运行环境下的一系列测试用例有机的组合起来。测试套件是按照测试计划所定义的各个阶段的测试目标决定的,即先有测试计划,后面才有测试套件。
回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。
测试常识:
一个正式的编写好的单元测试用例的特点是:即在测试执行前就已知输入和预期输出。
每一项需求至少需要两个单元测试用例:一个正检验,一个负检验。如果一个需求有子需求,每一个子需求必须至少有正检验和负检验两个测试用例。
1 是什么?
JUnit 是一个 Java编程语言的单元测试框架。
2 使用方法(举例说明)测试用例类+运行类!!!
2.1 maven集成 junit 4.12
2.2 创建被测试类==== MessageUtil
public class MessageUtil { private String message; public MessageUtil(String message){ this.message = message; } public String printMessage(){ System.out.println(message); return message; } }
2.3 创建测试用例类====TestJunit
作用:测试用例类 顾名思义就是测试用例代码!!!
import static org.junit.Assert.assertEquals; import org.junit.Test; import util.MessageUtil; public class TestJunit { String message = "Hello World1"; MessageUtil messageUtil = new MessageUtil("hello"); @Test public void testPrintMessage() { assertEquals(message,messageUtil.printMessage()); } }
2.4 创建运行类 ====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()); } }
2.5 运行 在运行类文件页面 右击
2.6 运行结果 ===会提示错误的地方
看到上面例子,发现测试代码用了一些注解,现在介绍junit中的注解
3 注解
3.1 注解所在类
3.2 注解以及作用
注解 | 作用 |
@Test | 这个注释说明依附在 JUnit 的 public void 方法可以作为一个测试案例。 |
@Before | 有些测试在运行前需要创造几个相似的对象。在 public void 方法加该注释是因为该方法需要在 test 方法前运行。 |
@After | 如果你将外部资源在 Before 方法中分配,那么你需要在测试运行后释放他们。在 public void 方法加该注释是因为该方法需要在 test 方法后运行。 |
@BeforeClass | 在 public void 方法加该注释是因为该方法需要在类中所有方法前运行。 |
@AfterClass | 它将会使方法在所有测试结束后执行。这个可以用来进行清理活动。 |
@Ignore | 这个注释是用来忽略有关不需要执行的测试的。 |
@Rule | 略 |
3.3 示例代码
import static org.junit.Assert.assertEquals; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import util.MessageUtil; public class TestJunit {
//一定要静态 @BeforeClass public static void beforeClass() { System.out.println("正在执行beforeClass注解的方法"); } @Before public void before() { System.out.println("正在执行before注解的方法"); } @Test public void testPrintMessage() { System.out.println("正在执行test注解的方法"); }
@Test
public void testCase2() {
System.out.println("正在执行test注解的方法2");
}
@After public void after() { System.out.println("正在执行after注解的方法"); }
//一定要静态
@AfterClass public static void afterClass() {
System.out.println("正在执行afterClass注解的方法");
}
@Ignore public void ignore() {
System.out.println("正在执行ignore注解的方法");
}
}
到此,大家对junit有一个大概了解,但是junit进行单元测试,能测试哪些方面呢?
4 JUnit 能测试哪些方面呢?
4.1 断言
4.1.1 常用类以及方法
这个类里面有很多同名方法,作用一样,只是参数数据类型不一样,自己根据需要选用就可以了。每种功能选一个方法示范。都是静态void方法!
方法 | 描述 |
assertArrayEquals(byte[] expecteds, byte[] actuals) |
比较两个参数是否相等 |
assertFalse(boolean condition) 【相反的assertTrue】 |
判定参数(参数条件)是错的 |
assertNotNull(Object object) 【相反的assertNull】 |
判定对象不为空 |
assertNotSame(Object unexpected, Object actual) 【相反的assertSame】 |
检查两个相关对象是否指向同一个对象 |
assertThat(T actual, org.hamcrest.Matcher<T> matcher) |
判断actual是否符合matcher |
fail() |
测试失败 |
4.1.2 示例代码
略
4.2 执行过程
看注解部分
4.3 执行测试
测试用例是使用 JUnitCore 类来执行的。JUnitCore 是运行测试的外观类。它支持运行 JUnit 4 测试, JUnit 3.8.x 测试,或者他们的混合。
4.3.1 常用类
4.3.2 示例代码
4.4 套件测试
测试套件意味着捆绑几个单元测试用例并且一起执行他们。在 JUnit 中,@RunWith 和 @Suite 注释用来运行套件测试。
4.4.1 常用类
4.4.2 示例代码
测试用例类一
import static org.junit.Assert.assertEquals; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import util.MessageUtil; public class TestJunit1 { String message = "Hello World1"; MessageUtil messageUtil = new MessageUtil("Hello World1"); @Test public void testPrintMessage() { assertEquals(message,messageUtil.printMessage()); } }
测试用例类二
import static org.junit.Assert.assertEquals; import org.junit.Test; import util.MessageUtil; public class TestJunit2 { String message = "Hello World2"; MessageUtil messageUtil = new MessageUtil("Hello World2"); @Test public void testPrintMessage() { assertEquals(message,messageUtil.printMessage()); } }
套件类:
import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ TestJunit1.class, TestJunit2.class }) public class JunitTestSuite { }
执行类:
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()); } }
4.5 忽略测试
看@Ingore
4.6 时间测试
Junit 提供了一个暂停的方便选项。如果一个测试用例比起指定的毫秒数花费了更多的时间,那么 Junit 将自动将它标记为失败。timeout 参数和 @Test 注释一起使用。
4.6.1 常用类==@test的一个属性
4.6.2 示例代码
4.7 异常测试
unit 用代码处理提供了一个追踪异常的选项。你可以测试代码是否它抛出了想要得到的异常。expected 参数和 @Test 注释一起使用。现在让我们看看活动中的 @Test(expected)。
4.7.1 常用类 ==@test的一个属性
4.7.2 示例代码
4.8 参数化测试
Junit 4 引入了一个新的功能参数化测试。参数化测试允许开发人员使用不同的值反复运行同一个测试。
4.8.1 常用类
4.8.2 示例代码
被测试类
public class IFShuangShu { public Boolean validate(final Integer primeNumber) { for (int i = 2; i < (primeNumber / 2); i++) { if (primeNumber % i == 0) { return false; } } return true; } }
测试用例类
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.Collection; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import util.IFShuangShu; @RunWith(Parameterized.class) public class TestJunit { private Integer inputNumber; private Boolean expectedResult; private IFShuangShu ifs; @Before public void initialize() { System.out.println("初始化被测试类的实例!!!"); ifs = new IFShuangShu(); } public TestJunit(Integer inputNumber, Boolean expectedResult) { System.out.println("参数赋值!!!"); this.inputNumber = inputNumber; this.expectedResult = expectedResult; } @Parameterized.Parameters public static Collection primeNumbers() { System.out.println("定义参数组合!!!"); return Arrays.asList(new Object[][] { { 2, true }, { 6, false }, { 19, true }, { 22, false }, { 23, true } }); } @Test public void test() { System.out.println("断言方法!!!"); assertEquals(expectedResult, ifs.validate(inputNumber)); } }
执行类
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()); } }
4.9 JUnit 框架 扩展
名称 | 作用 |
Cactus |
Cactus 是一个简单框架用来测试服务器端的 Java 代码(Servlets, EJBs, Tag Libs, Filters)。Cactus 的设计意图是用来减小为服务器端代码写测试样例的成本。它使用 JUnit 并且在此基础上进行扩展。Cactus 实现了 in-container 的策略,意味着可以在容器内部执行测试。 |
JWebUnit |
JWebUnit 提供了一种高级别的 Java API 用来处理结合了一系列验证程序正确性的断言的 web 应用程序。这包括通过链接,表单的填写和提交,表格内容的验证和其他 web 应用程序典型的业务特征。 |
XMLUnit |
针对XML的测试 |
MockObject |
在一个单元测试中,虚拟对象可以模拟复杂的,真实的(非虚拟)对象的行为,因此当一个真实对象不现实或不可能包含进一个单元测试的时候非常有用。 |