Junit4单元测试
一、简介Junit4单元测试
1.1 Junit
①JUnit是用于编写可复用测试集的简单框架,是xUnit的一个子集。xUnit是一套基于测试驱动开发的测试框架,有PythonUnit、CppUnit、JUnit等。
②Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(What)的功能。
③多数Java的开发环境都已经集成了JUnit作为单元测试的工具,比如IDEA,Eclipse等等。
1.2 单元测试
①单元测试又称模块测试,属于白盒测试,是最小单位的测试。
②模块分为程序模块和功能模块。功能模块指实现了一个完整功能的模块(单元),一个完整的程序单元具备输入、加工和输出三个环节。
③每个程序单元都应该有正规的规格说明,使之对其输入、加工和输出的关系做出名明确的描述。
1.3 Junit4单元测试好处
①测试框架可以帮助我们对编写的程序进行有目的地测试,帮助我们最大限度地避免代码中的bug,以保证系统的正确性和稳定性。
②很多人对自己写的代码,测试时就简单写main,然后sysout输出控制台观察结果。这样非常枯燥繁琐,不规范。缺点:测试方法不能一起运行,测试结果要程序猿自己观察才可以判断程序逻辑是否正确。
③JUnit的断言机制,可以直接将我们的预期结果和程序运行的结果进行一个比对,确保对结果的可预知性。
1.4 测试覆盖及代码覆盖率
- 测试覆盖:评测测试过程中已经执行的代码的多少
- 代码覆盖率:代码的覆盖程度,一种度量方式。
- 针对代码的测试覆盖率有许多种度量方式:
-
语句覆盖( StatementCoverage ):也称为行覆盖( lin EC overage ) ,段覆盖(segmentcoverage)和基本块覆盖(bASicblockcoverage)。它度量每一个可执行语句是否被执行到了。
-
判定覆盖(DecisionCoverage):也被称为分支覆盖(branchcoverage),所有边界覆盖(alledgescoverage),
基本路径覆盖( basispathcoverage ),
判定路径覆盖(decisiondecisionpath或DDPtesting)。它度量是否每个 BOOL 型的表达式取值true 和
false 在控制结构中都被测试到了。 -
条件覆盖(ConDItionCoverage): 它独立的度量每一个子表达式,报告每一个子表达式的结果的 true 或
false。这个度量和判定覆盖(decisioncoverage)相似,但是对控制流更敏感。不过,完全的条件覆盖并不能保证完全的判定覆盖。 -
路径覆盖(PathCoverage):也称为断言覆盖(prEDIcatecoverage),它度量了是否函数的每一个可能的分支都被执行了。路径覆盖的一个好处是:需要彻底的测试。但有两个缺点:一是,路径是以分支的指数级别增加的,例如:一个函数包含
10个 IF 语句,就有 1024 个路径要测试。如果加入一个 IF 语句,路径数就达到 2048;二是,许多路径不可能与执行的数据无关。 -
循环覆盖(LOOPCoverage):这个度量报告你是否执行了每个循环体零次、只有一次还是多余一次(连续地)。对于
dowhile循环,循环覆盖报告你是否执行了每个循环体只有一次还是多余一次(连续地)。这个度量的有价值的方面是确定是否对于 while
循环和 for 循环执行了多于一次,这个信息在其它的覆盖率报告中是没有的。
-
二、使用Junit4单元测试(IDEA)
2.1 配置
- 覆盖率查看设置
2.2 新建test目录
首先需要新建test目录,并通过右键Make Directory as -> Test Source Root将其设定为测试根目录
2.3 IDEA自动生成测试类
- 首先选中需要测试的类,按下快捷键:Alt + Enter,选择 Create Test:
- Testing library 选择 Junit4,Member 中勾选想要测试的方法即可。
- 自动生成
三、测试类的编写(SSM)
3.1 Dao类(Mapper类)
// 解决WebApplicationContext无法注入问题
@WebAppConfiguration
//配置spring和junit整合,这样junit在启动时就会加载spring容器 固定写法
@RunWith(SpringJUnit4ClassRunner.class)
//告诉junit spring的配置文件
@ContextConfiguration({"classpath:spring/ApplicationContext.xml","classpath:spring/ApplicationContext-mvc.xml"})
public class UserDaoTest {
@Autowired
protected WebApplicationContext wac;
//注入需要测试的Service或Mapper,直接调用方法测试即可
@Autowired
private UserDao userDao;
@Before
public void setUp() throws Exception {
System.out.println("begin test UserDao");
assertNotNull(wac);
assertNotNull(userDao);
}
@After
public void tearDown() throws Exception {
System.out.println("end test UserDao");
}
@Test
public void getUser() {
System.out.println("test UserDao.getUser()");
User user=userDao.getUser("liu","123456");
assertEquals("liu",user.getAccount());
}
}
3.2 Service类
// 解决WebApplicationContext无法注入问题
@WebAppConfiguration
//配置spring和junit整合,这样junit在启动时就会加载spring容器 固定写法
@RunWith(SpringJUnit4ClassRunner.class)
//告诉junit spring的配置文件
@ContextConfiguration({"classpath:spring/ApplicationContext.xml","classpath:spring/ApplicationContext-mvc.xml"})
public class UserServiceTest {
@Autowired
protected WebApplicationContext wac;
//注入需要测试的Service或Mapper,直接调用方法测试即可
@Autowired
private UserService userService;
@Before
public void setUp() throws Exception {
System.out.println("begin test UserService");
assertNotNull(wac);
assertNotNull(userService);
}
@After
public void tearDown() throws Exception {
System.out.println("end test UserService");
}
@Test
public void login() {
System.out.println("test UserService.login()");
Boolean login = userService.login("liu","123456");
assertEquals(true,login);
}
}
3.3 Controller类
// 解决WebApplicationContext无法注入问题
@WebAppConfiguration
//配置spring和junit整合,这样junit在启动时就会加载spring容器 固定写法
@RunWith(SpringJUnit4ClassRunner.class)
//告诉junit spring的配置文件
@ContextConfiguration({"classpath:spring/ApplicationContext.xml","classpath:spring/ApplicationContext-mvc.xml"})
public class LoginControllerTest {
@Autowired
protected WebApplicationContext wac;
//注入需要测试的Service或Mapper,直接调用方法测试即可
@Autowired
private LoginController loginController;
@Before
public void setUp() throws Exception {
System.out.println("begin test LoginControlller");
assertNotNull(loginController);
}
@After
public void tearDown() throws Exception {
System.out.println("end test LoginControlller");
}
@Test
public void login() {
System.out.println("test LoginControlller.login()");
}
}