软件测试主要分成5类,范围从小到大分别为:单元测试->集成测试->功能测试->压力测试->验收测试。此系列中我们只讨论单元测试。
>> 单元测试的3种类型:
* 逻辑单元测试:主要针对一个单独的方法来检查代码,可以通过mock object或者stub来控制某个特定的测试方法的边界。
* 集成单元测试:主要用来测试在真实环境或者真实环境的一部分中不同组件之间的相互作用。例如测试一段访问某个数据库的代码是否真正有效的调用了数据库
* 功能单元测试:已经超出了集成单元测试的边界,目的是为了确认一个刺激响应。例如如果一个网页只能登录才能看到,否则重定向到登录页面。这个时候可以变形一个功能单元测试,通过向这个网页发送一个HTTP请求,然后验证返回是否是一个重定向HTTP状态码302等。
注:严格来讲,功能单元测试并不是纯粹的单元测试,也不是纯粹的功能测试。它相对于纯粹的单元测试而言,更多的依赖外部环境,但它又不像纯粹的功能测试那样会测试一个完整的工作流。我们之所以把功能单元测试放入我们讨论范围,是因为它通常在开发环境中作为一系列测试中一部分是非常有用的。
>> Junit的几个核心对象:
* Assert:让你定义想测试的条件,条件成立时,assert方法保持沉默,但是不成立的时候就会抛出异常
* 测试:一个以@Test注解的方法定义了一个测试。为了运行这个方法,JUnit会创建一个包含该测试方法的测试类的新实例,然后再调用这个被注解的方法,也就是说一个测试方法就会new一个测试类。
* 测试类:一个测试类是@Test方法的容器
* Suite:Suite允许你将测试类归组
* Runner:Runner类用来运行测试,JUnit4向后兼容,可以运行JUnit3的测试
>> 运行参数化测试:
来看一个Runner实例,一个测试方法通过传多个参数去让它执行多次,Parameterized是JUnit多个测试运行器Runner中的一个而已:
@RunWith(Parameterized.class) public class CalculatorParameterizedTest { private double expected; private double valueOne; private double valueTwo; public CalculatorParameterizedTest( double expected, double valueOne, double valueTwo) { this.expected = expected; this.valueOne = valueOne; this.valueTwo = valueTwo; } @Parameters public static Collection<Object[]> getTestParameters() { List<Object[]> params = Arrays.asList(new Object[][]{ {2,1,1}, {3,2,1}, {4d,2d,2d} }); System.out.println(params.size()); return params; } @Test public void testSum() { Calculator calculator = new Calculator(); assertThat(calculator.add(valueOne, valueTwo), is(expected)); } }
>> Junit最佳实践:
* 一次只能单元测试一个对象。当一个对象与其他复杂对象交互时候,可以使用可预测的测试对象将被测试对象包围起来。
* 一个单元测试等于一个@Test方法,不要试图把多个测试塞进一个方法中,这样导致的结果就是测试方法变得更加复杂,难以阅读也难以理解。
* 让测试改善你的代码,应当根据测试时候发现的问题重构代码,使其更加易于使用。极限编程提倡不要过早的添加功能。
>> 测试异常:
使用expected的注解参数测试异常示例
@Test(expected = RuntimeException.class) public void testAddRequestDuplicateName() { SampleRequest request = new SampleRequest(); SampleHandler handler = new SampleHandler(); controller.addHandler(request, handler); }
>> 超时测试:
使用timeout注解参数测试超时示例,使用@Ignore注解跳过该测试
@Test(timeout = 130) @Ignore(value = "Skip for now") public void testProcessMultipleRequestsTimeout() { Request request; Response response = new SampleResponse(); RequestHandler handler = new SampleHandler(); for (int i = 0; i < 99999; i++) { ... } }
>> 引入Hamcrest匹配器
有时候junit的assert语句太复杂很难看懂,这个时候可以使用hamcrest框架的短语来简化assert语句。Hamcrest是一个库,包含了大量的匹配器对象(也称约束或者谓语),它可以被植入到其他几种开发语言比如java、C++、Objective-C、Python和PHP,请注意,Hamcrest本身不是一个测试框架,确切的说,它可以帮你通过声明方式指定简单的匹配规则,尤其适用于单元测试,不过也可以应用到其他领域。
@Test public void testWithHamcrest() { assertThat(values, hasItem(anyOf(equalTo("one"), equalTo("two"), equalTo("three")))); }
一些常用的Hamcrest匹配器:
anything | 绝对匹配,更加可读性 |
is | 仅用于改善可读性 |
allOf | 检查是否与所有包含的匹配器匹配(相对于&&) |
anyOf | 检查是否与任意包含的匹配器匹配(相对于||) |
not | 非(相对于!) |
instanceOf、isCompatibleType | 对象类型 |
sameInstance | 测试对象引用是否指向同一个对象 |
notNullValue、nullValue | null值或非null值 |
hasProperty | 测试JavaBean是否具有某属性 |
hasEntry、hasKey、hasValue | 测试Map |
hasItem、hasItems | 测试集合 |
closeTo、greaterThan、greaterThanOrEqual、 lessThan、lessThanOrEqual |
测试数字的大小 |
equalToIgnoringCase | 测试字符串相同与否,忽略大小写 |
equalToIgnoringWhiteSpace | 测试字符串相同与否,忽略空白 |
containsString、endsWith、startWith | 测试字符串包含、结尾、开头 |
相关推荐
《Junit4 入门详解》 JUnit 是一个用于Java编程语言的单元测试框架,而Junit4作为其第四代版本,引入了许多新特性和改进,使得测试...同时,不断探索Junit4的高级特性,你会发现它能为你的软件开发带来无尽的便利。
《JUnit实战(第2版)》从认识JUnit、不同的测试策略、JUnit与构建过程、JUnit扩展4个方面,由浅入深、由易到难地对JUnit展开了系统的讲解,包括探索JUnit的核心、软件测试原则、测试覆盖率与开发、使用stub进行粗...
《深入理解JUnit:Java单元测试框架的探索与实践》 JUnit是Java编程语言中最流行的单元测试框架之一,它为开发者提供了简洁、高效的测试工具,帮助确保代码的质量和可靠性。本篇文章将围绕“junit-master.zip”这个...
JUnit的核心概念包括: 1. 测试类:通常包含一组测试方法的Java类。 2. 测试方法:用`@Test`注解标识的方法,它们执行特定的验证逻辑。 3. 断言(Assertion):如`assertEquals`或`assertTrue`,用于检查代码预期的...
本书从认识JUnit、不同的测试策略、JUnit与构建过程、JUnit扩展4个方面,由浅入深、由易到难地对JUnit展开了系统的讲解,包括探索JUnit的核心、软件测试原则、测试覆盖率与开发、使用stub进行粗粒度测试、使用mock...
《Spring3与JUnit4深度解析》 在Java开发领域,Spring框架和JUnit测试工具是不可或缺的重要组成部分。Spring3.2.8是Spring框架的一个稳定版本,它提供了丰富的功能,包括依赖注入、AOP(面向切面编程)、MVC(模型-...
第二章“探索JUnit”则着重于JUnit的内部机制和高级特性。读者将学习如何使用核心JUnit类进行编写测试,这些类包括断言类(Assert类)、测试套件(TestSuite类)、以及测试运行器(TestRunner类)等。此外,本章还...
【深入JUnit4.x】—— 探索Java单元测试框架的核心 JUnit是Java开发中最常用的单元测试框架,尤其在JUnit4.x版本中,它引入了许多改进和特性,使得测试更加灵活和强大。这篇深入的文章将围绕JUnit4.x的核心概念、...
- **第2章:探索JUnit**:深入探讨JUnit的核心功能和高级特性。 - **第3章:软件测试原则**:讲解软件测试的基本原理,帮助读者建立正确的测试观念。 - **第4章:最佳实践**:分享提高测试效果的方法和技巧。 - *...
《深入解析JUnit4:探索开源测试框架的精髓》 JUnit4是Java开发中广泛使用的单元测试框架,它的开源性质使得开发者能够深入理解其内部机制,从而更好地利用它进行测试驱动开发(TDD)。本篇文章将从`junit4-example...
总之,《JUnit A Cook’s Tour》这本书会带领读者逐步探索JUnit的各个方面,从基本的测试编写到高级特性的应用,提升你的测试技能,确保代码的质量和可靠性。通过学习和实践,你将在Java开发过程中更加得心应手。
本篇将深入讲解JUnit4的核心概念及常用功能。 1. **注解驱动的测试** JUnit4引入了注解(Annotation)的概念,这使得测试类和方法的声明更加简洁。例如,`@Test`注解标记测试方法,`@Before`和`@After`注解分别...
在JUnit 4.9中,`@Test`注解是最核心的部分,它标识了一个方法为测试用例。你可以在这个注解上添加`expected`属性来指定一个预期的异常,如果测试方法没有抛出这个异常,那么测试就会失败。此外,`@Test`还可以与`@...
JUnit框架的核心组件包括测试类、测试方法和断言。测试类是包含测试方法的普通Java类,而测试方法则是标记为@Test的公共无参方法。断言是用来检查代码预期结果的工具,如assertEquals()用于比较实际值和期望值是否...