单元测试
程序员文章站
2022-04-27 14:57:48
...
单元测试和集成测试在软件研发中都至关重要,尤其是随着自动化的普及,自动化测试也越来越流行。
单元测试的作用:
1、自动化测试和集成
2、发现隐藏的bug
单元测试的原则:
1、准备测试环境,尤其是数据环境,数据环境尽可能的做到独立
2、明确单元测试的范围,范围的选择尽可能的适中
3、以需求和原形为准,尽可能的覆盖需求和原型
4、代码各个数据流尽可能的覆盖到
5、兼顾数据逻辑,尽量做到测试数据独立
6、跨范围依赖调用使用Mock
使用代码示例来简单记录一下:
采用的springboot + mybaites,仅仅是来测试service层的接口:
接口层(Interface):
public interface ServiceInformationInterf {
int deleteByPrimaryKey(String serviceid);
int insert(ServiceInformation record);
int insertSelective(ServiceInformation record);
ServiceInformation selectByPrimaryKey(String serviceid);
int updateByPrimaryKeySelective(ServiceInformation record);
int updateByPrimaryKey(ServiceInformation record);
List<ServiceInformation> selectAllService();
List<ServiceInformation> selectServiceInformationByCondition(String serviceId,String serviceName,String method,Integer pageNumber,Integer pageSize)throws Exception;
}
接口实现层(service):
@Service
@Transactional
public class ServiceInformationService implements ServiceInformationInterf {
private Logger log = LoggerUtils.getRequestLog();
@Autowired
private ServiceInformationMapper serviceInformationMapper;
@Autowired
private QuartzManager quartzManager;
@Override
public int deleteByPrimaryKey(String serviceId) {
//先删除相应的job任务
Scheduler scheduler = ShedulerFactoryUtils.getSheduler();
quartzManager.removeJob(scheduler,serviceId);
log.info("synchronous delete a jobTask,jobName:{}!",serviceId);
return serviceInformationMapper.deleteByPrimaryKey(serviceId);
}
@Override
public int insert(ServiceInformation record) {
return serviceInformationMapper.insert(record);
}
@Override
public int insertSelective(ServiceInformation record) {
String serviceId = record.getServiceId();
String cronTime = record.getIntervalTime();
Scheduler scheduler = ShedulerFactoryUtils.getSheduler();
//同步的在定时器任务框架中,添加一个定时任务
quartzManager.addJob(scheduler,serviceId, JobTask.class,cronTime,record);
log.info("synchronous add a jobTask !,JobName:{}",serviceId);
return serviceInformationMapper.insertSelective(record);
}
@Override
public ServiceInformation selectByPrimaryKey(String serviceid) {
return serviceInformationMapper.selectByPrimaryKey(serviceid);
}
@Override
public int updateByPrimaryKeySelective(ServiceInformation record) {
return serviceInformationMapper.updateByPrimaryKeySelective(record);
}
@Override
public int updateByPrimaryKey(ServiceInformation record) {
String serviceId = record.getServiceId();
Scheduler scheduler = ShedulerFactoryUtils.getSheduler();
ServiceInformation serviceInformation = oldToNewServcieInformation(record);
String cronTime = serviceInformation.getIntervalTime();
//用于修改已经启动的定时器任务
quartzManager.modifyJobTime(scheduler,serviceId,cronTime,serviceInformation);
log.info("synchronous modify a jobTask executing time!,JobName:{}",serviceId);
return serviceInformationMapper.updateByPrimaryKeySelective(record);
}
private ServiceInformation oldToNewServcieInformation(ServiceInformation record){
String serviceId = record.getServiceId();
String serviceName = record.getServiceName();
String url = record.getUrl();
String method = record.getMethod();
String pathParams = record.getPathParams();
String bodyParams = record.getBodyParams();
String queryParams = record.getQueryParams();
String expectedResult = record.getExpectedResult();
String cronTime = record.getIntervalTime();
Integer delayTime = record.getDelayTime();
Integer retryNum = record.getRetryNum();
Integer matchStrategy = record.getMatchStrategy();
ServiceInformation oldServiceInformation = selectByPrimaryKey(serviceId);
oldServiceInformation.setIntervalTime(cronTime);
if(serviceName!=null){
oldServiceInformation.setServiceName(serviceName);
}
if(method!=null){
oldServiceInformation.setMethod(method);
}
if(url!=null){
oldServiceInformation.setUrl(url);
}
if(pathParams!=null){
oldServiceInformation.setPathParams(pathParams);
}
if(queryParams!=null){
oldServiceInformation.setQueryParams(queryParams);
}
if(bodyParams!=null){
oldServiceInformation.setBodyParams(bodyParams);
}
if(expectedResult!=null){
oldServiceInformation.setExpectedResult(expectedResult);
}
if(cronTime!=null){
oldServiceInformation.setIntervalTime(cronTime);
}
if(matchStrategy!=null){
oldServiceInformation.setMatchStrategy(matchStrategy);
}
if(delayTime!=null){
oldServiceInformation.setDelayTime(delayTime);
}
if(retryNum!=null){
oldServiceInformation.setRetryNum(retryNum);
}
return oldServiceInformation;
}
@Override
public List<ServiceInformation> selectAllService() {
return serviceInformationMapper.selectAllService();
}
@Override
public List<ServiceInformation> selectServiceInformationByCondition(String serviceId, String serviceName, String method, Integer pageNumber, Integer pageSize)throws Exception{
if(pageNumber<=0||pageSize<=0){
throw new CustomException("pageNumber or pageSize is not correct!");
}
PageHelper.startPage(pageNumber,pageSize);
return serviceInformationMapper.SelectServiceByCondition(serviceId,serviceName,method);
}
单元测试:
import com.sdmk.availability.test.mockservice.AbstractTestSuite;
import com.talkingdata.sdmk.availabilityMonitor.entity.ServiceInformation;
import com.talkingdata.sdmk.availabilityMonitor.service.Interface.ServiceInformationInterf;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import static org.junit.Assert.*;
/**
* User: ysl
* Date: 2017/8/7
* Time: 15:58
*/
public class ServiceInformationServiceTestSuite extends AbstractTestSuite {
@Autowired
private ServiceInformationInterf serviceInformationService;
@Test
public void testSelectServiceInformationByServiceId() throws Exception {
ServiceInformation serviceInformation = serviceInformationService.selectByPrimaryKey(SERVICE_ID);
assertNotNull(serviceInformation);
}
@Test
@Transactional
public void testInsertServiceInformation()throws Exception{
ServiceInformation record = new ServiceInformation(
"b74d0dfa563846fb99157e7e68197027",
"深圳测试服务(testsuit)",
"http://172.20.33.3:9000/data/user-tag-gamedeepness/v2",
"get",
null,
null,
"{\"id\":\"25dcf7db266c249a9b1645760d91c4ddb\",\"type\":\"tdid\"}",
"{\"code\":2003,\"msg\":\"ok\",\"data\":{\"tags\":[]},\"seq\":\"b23ed0cbd99e47dfa128854cad697e61\"}",
"0 0 1 * * ?",
0,
15,
3
);
int result = serviceInformationService.insertSelective(record);
assertTrue(result == 1);
}
@Test
@Transactional
public void testUpdateServiceInformation()throws Exception{
ServiceInformation serviceInformation = serviceInformationService.selectByPrimaryKey(SERVICE_ID);
assertNotNull(serviceInformation);
serviceInformation.setServiceName("深圳机房测试服务");
int result = serviceInformationService.updateByPrimaryKey(serviceInformation);
assertTrue(result == 1);
ServiceInformation newServiceInformation = serviceInformationService.selectByPrimaryKey(SERVICE_ID);
assertEquals("修改服务配置信息没问题!", "深圳机房测试服务", newServiceInformation.getServiceName());
}
@Test
@Transactional
public void testDeleteServiceInformation()throws Exception{
int result = serviceInformationService.deleteByPrimaryKey(SERVICE_ID);
assertTrue(result == 1);
}
@Test
public void testSelectAllService()throws Exception{
List<ServiceInformation> serviceInformationList = serviceInformationService.selectAllService();
assertNotNull(serviceInformationList);
assertTrue(serviceInformationList.size()>0);
}
@Test
public void testSelectMonitor() throws Exception {
assertArrayEquals(
new Object[]{
serviceInformationService.selectServiceInformationByCondition(SERVICE_ID, null, null, 1, 20).size() > 0,
serviceInformationService.selectServiceInformationByCondition(null, "服务", null, 1, 20).size() > 0,
serviceInformationService.selectServiceInformationByCondition(SERVICE_ID, null, null, 1, 20).size() > 0,
serviceInformationService.selectServiceInformationByCondition(null, null, "get", 1, 20).size() > 0,
},
new Object[]{
true,
true,
true,
true
}
);
}
}
TestSuite:
import com.sdmk.availability.test.service.ServiceInformationServiceTestSuite;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
/**
* User: ysl
* Date: 2017/8/7
* Time: 14:02
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({com.sdmk.availability.test.service.MonitorServiceTestSuite.class,ServiceInformationServiceTestSuite.class})
public class BackgroundTestSuit {
}
单元测试采用maven + jenkins + jacoco插件:
测试结果:
上一篇: MySQL 基本用法(二)多表查询