单元测试及测试覆盖率报告生成
一般在开发中我们建议对于新写的业务逻辑进行单元测试,而不是将所有代码都写完之后再进行测试,这样既不能保证代码的可用性而且后续测试也会比较困难,因此掌握基本的测试API对于开发人员来说也是非常重要的,下面将简单的讲解一下我们开发中可能会用到的一些测试方面的知识。
junit5驱动和断言
和Junit4相比,Junit5框架更多在向测试平台演进。其核心组成也从以前的一个Junit的jar包更换成由多个模块组成。本文所需要依赖模块如下:
- junit-jupiter-engine: Junit的核心测试引擎
- junit-jupiter-params: 编写参数化测试所需要的依赖包
- junit-platform-launcher: 从IDE(InteliJ/Eclipses)等运行时所需要的启动器
依赖引入
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
驱动&断言
对被测对象的执行过程称为驱动driver,而验证结果是否正确则称之为断言。可以简单理解为执行被测对象是驱动,验证结果是断言。
以下为常见的单元测试注解:
| 方法名 | 描述 |
|---|---|
| @BeforeAll | 只执行一次,在所有测试和@BeforeEach注解方法之前执行 |
| @BeforeEach | 在每个测试执行之前执行 |
| @AfterEach | 在每个测试执行之后执行 |
| @AfterAll | 只执行一次,在所有测试和@AfterEach注解方法之后执行 |
注意:在测试执行前后会进行一些初始化和销毁的操作,因为框架会为每个测试创建一个单独的实例,所以在**@BeforeAll/@AfterAll方法执行时尚无任何测试实例诞生。因此,这两个方法必须定义为静态方法**。
数据驱动
使用@ParameterizedTest注解来实现数据驱动测试,通过一个用例的多组数据从而快速实现
/**
* 数据驱动使用
* @author lilei
*/
public class DataDriverTest {
/**
* 基础数据数据结构驱动
*
* @param words 单词
*/
@ParameterizedTest
@ValueSource(strings = {
"Radar", "Rotor", "Tenet", "Madam", "Racecar"})
void multiNameTest(String words) {
System.out.println(words);
}
/**
* CSV数据结构驱动
*
* @param startDate 开始日期
* @param endDate 结束日期
*/
@ParameterizedTest
@CsvSource(
{
"2017-06-01,2018-10-15",
"2017-05-01,2018-10-15",
"2017-06-01,2018-11-16"}
)
void shouldCreateValidDateRange(LocalDate startDate, LocalDate endDate) {
System.out.println(startDate + "|" + endDate);
}
/**
* 读取csv文件实现数据驱动
* @param country 国家
* @param reference 关联行数
*/
@ParameterizedTest
@CsvFileSource(resources = "/country.csv",numLinesToSkip = 1)
void CsvFileSourceTest(String country,String reference) {
System.out.println(country+"-"+reference);
}
/**
* 方法数据源
* @param fruitName 水果
* @param num 数字
* @param list 集合
*/
@ParameterizedTest
@MethodSource("stringIntAndListProvider")
void testWithMultiArgMethodSource(String fruitName, int num, List<String> list) {
assertEquals(5, fruitName.length());
assertTrue(num >=1 && num <=2);
assertEquals(2, list.size());
}
static Stream<Arguments> stringIntAndListProvider() {
return Stream.of(
arguments("apple", 1, Arrays.asList("a", "b")),
arguments("lemon", 2, Arrays.asList("x", "y"))
);
}
}

基于Spring的单元测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
"classpath:config-init.xml"})
public class SpringTest {
@Autowired
MsgSendLogMapper msgSendLogMapper;
@Test
public void springConfigTest() {
// do something....
}
}
基于SpringtBoot的单元测试
Service测试
@SpringBootTest
public class UserServiceImplTest {
@Resource
private UserService userService;
@Test
@Transactional
@Rollback(false) //是否进行回滚
void test1</


8577

被折叠的 条评论
为什么被折叠?



