1、问题背景
不同的测试类型,例如功能测试的端到端测试以及服务端测试;亦或是专项测试中的异常测试、性能测试等,都会遇到这样的问题:
当去执行一个测试用例时,需要获取依赖基础服务(例如数据库、缓存等)的某个值来让用例顺利的PASS;这时候通常的做法是集成基础服务的访问到应用的测试框架中,会发现我们的测试框架随着这种依赖的增加而变得很庞大且冗余繁复。冗余繁复?因为每个人去构建的时候都会去重复造一遍车轮,事实上这些依赖的基础服务需要最大化的共享,才能够更好的提升测试效率。
2、解决方案-测试依赖服务化
关于测试服务共享,基本思路就是构建一个应用服务对外提供访问;不同的语言有不同框架的选择,个人偏向于java,在构建一个Resetful API应用服务时常见的是采用spring MVC的架构形式开发;而此时在选型时考虑到框架的复杂度给使用者会带来一定的学习成本(这里的使用者分为两类:一类是纯调用者,可能不用关心框架;另外一类是二次应用开发的人,可简单修改提供的应用服务来自适应自己的需求)。从轻量且懒人思维的角度,发现spring的演进历程中提供了Spring boot;
Spring Boot的问世旨在帮助开发者更容易地创建基于Spring的应用程序和服务,使得现有的和新的Spring开发者能够最快速地获得所需要的Spring功能。它就是用来简化Spring应用的搭建以及开发过程。该框架致力于实现免XML配置,提供便捷,独立的运行环境,实现“一键运行”满足快速应用开发的需求。
其特点如下:
l 创建独立的Spring应用程序
l 嵌入的Tomcat,无需部署WAR文件
l 简化Maven配置
l 自动配置Spring
l 提供生产就绪型功能,如指标,健康检查和外部配置
l 绝对没有代码生成和对XML没有要求配置
接下来以一个典型案例来说明如何利用spring boot快速构建应用服务
3、利用mybatis快速构建数据库增删改查
实现目标:以Resetful API提供对数据库的增删改查(参数为sql语句)
分解实现步骤:构建Resetful API + 利用mybatis实现sql执行
首先来看一个典型的分层设计
在开展测试的时候,如上业务分层展现的一样,经常交互的就是数据库。例如抓取数据库中存储的短信验证码,修改某个标注位,插入一条访问记录等操作。就此构建如下的api来实现对数据库的访问:
/sql/selectOne @param sql 查
/sql/insert @param sql 插
/sql/update @param sql 改
/sql/delete @param sql 删
3.1 构建Resetful API
代码结构如下
【maven配置】引入starter配置
org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 1.2.0 org.springframework.boot spring-boot-starter-jdbc
【主入口】
MicroservicesApplication.java包含main函数,像普通java程序启动即可。
@SpringBootApplicationpublic class MicroservicesApplication extends SpringBootServletInitializer { public static void main(String[] args) throws Exception { SpringApplication.run(MicroservicesApplication.class, args); } }
【controller】
SqlController请求入口Controller提供Restful API接口,如下是提供了查询接口:
@RestControllerpublic class SqlController { @Autowired private SqlSession sqlSession; // 创建sqlMapper private SqlMapper sqlMapper; @RequestMapping("/sql/selectOne") public String SelectOneImpl(String sql) { sqlMapper = new SqlMapper(sqlSession); Map value = sqlMapper.selectOne(sql); JSONObject jsonObject = JSONObject.fromObject(value); String retValue = jsonObject.toString(); DebugLogger.debug("select result:" + retValue); return retValue; }
SqlMapper 的实现原理见3.2实现:SqlMapper构造参数public SqlMapper(SqlSession sqlSession),需要一个入参SqlSession sqlSession,其原理是根据SQL动态的创建一个MappedStatement,然后使用MappedStatement的id在sqlSession中执行。
3.2 利用mybatis实现sql执行
【引入mybatis starter】
org.mybatis.spring.boot mybatis-spring-boot-starter 1.2.0
【配置数据库】
在pom.xml中引入模块化的Starter POMs后,其中各个模块都有自己的默认配置,所以如果不是特殊应用场景,就只需要在application.properties中完成一些属性配置就能开启各模块的应用。如配置数据库:
###jdbc config#####
spring.datasource.url=jdbc:mysql://xx.xx.xx.xx:xx/urscloud?useUnicode=true&characterEncoding=utf-8&autoReconnect=true
spring.datasource.username=xx
spring.datasource.password=xx
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
【编写SqlMapper】
以update操作为例说明:
public int update(String sql) { String msId = msUtils.update(sql); return sqlSession.update(msId);}
实现:SqlMapper构造参数public SqlMapper(SqlSession sqlSession),需要一个入参SqlSession sqlSession,其原理是根据SQL动态的创建一个MappedStatement,然后使用MappedStatement的id在sqlSession中执行。
3.3 内嵌tomcat执行
采用maven package生成jar包microservices-1.0.jar,执行如下:
java –jar microservices-1.0.jar
4、spring boot集成docker
【引入docker-maven-plugin】
docker-maven-plugin 插件是用于构建 Maven 的 Docker Image,如下配置:
com.spotify docker-maven-plugin 0.4.11 ${docker.image.prefix}/${project.artifactId} src/main/docker / ${project.build.directory} ${project.build.finalName}.war
引入配置
registry.hz.netease.com
【构建dockerfile】
创建文件src/main/docker/Dockerfile,内容如下:
FROM registry.hz.netease.com/urstestbase:latest
VOLUME /tmp
COPY microservices-1.0.war /home/webroot-ursmocro
EXPOSE 8901
ENTRYPOINT [ "sh", "-c", "/home/tomcat-urstest-identify-Ins1/tomcat restart " ]
【构建 Docker Image】
mvn package docker:build实现快速构建镜像上传至registry.hz.netease.com
【启动容器】
docker run -d -p 8901:8901 -p 8902:22 -t registry.hz.netease.com/microservices
5、共享服务
目前已经支持的服务如下:
l 支持数据库操作增删改查(SQL作为参数)
l 支持nkv缓存set、get、delete操作
l 支持redis服务set和get操作
l 支持根据正则表达式随机生成字符串
l 支持获取将军令动态密码
通过这种共享的方式,测试小团队可以共同维护这样的基于spring boot开发的应用服务来满足需求。