背景:在项目后端接口开发还未完成,我们无法进行自动化接口用例的调试,希望与开发同步完成接口自动化用例的编写及调试,待项目转测后,可以直接跑自动化用例,提高测试效率.
选用的maven + Spring Boot框架,代码的示例自己随便构造的, 由于实际项目接口没有做cookie的校验, 所以示例接口没有添加cookie和做cookie校验,后续有需求再研究...直接上代码
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>LMock</groupId> 8 <artifactId>spring-boot-LMock</artifactId> 9 <version>1.0.0</version> 10 11 <parent> 12 <groupId>org.springframework.boot</groupId> 13 <artifactId>spring-boot-starter-parent</artifactId> 14 <version>2.0.2.RELEASE</version> 15 </parent> 16 17 <dependencies> 18 <dependency> 19 <groupId>org.springframework.boot</groupId> 20 <artifactId>spring-boot-starter-web</artifactId> 21 </dependency> 22 <dependency> 23 <groupId>org.projectlombok</groupId> 24 <artifactId>lombok</artifactId> 25 <version>1.16.14</version> 26 </dependency> 27 <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> 28 <dependency> 29 <groupId>com.alibaba</groupId> 30 <artifactId>fastjson</artifactId> 31 <version>1.2.49</version> 32 </dependency> 33 </dependencies> 34 35 <build> 36 <plugins> 37 <plugin> 38 <groupId>org.apache.maven.plugins</groupId> 39 <artifactId>maven-compiler-plugin</artifactId> 40 <configuration> 41 <source>1.8</source> 42 <target>1.8</target> 43 </configuration> 44 </plugin> 45 46 <plugin> 47 <groupId>org.springframework.boot</groupId> 48 <artifactId>spring-boot-maven-plugin</artifactId> 49 <configuration> 50 <mainClass>Application</mainClass> 51 </configuration> 52 <executions> 53 <execution> 54 <goals> 55 <goal>repackage</goal> 56 </goals> 57 </execution> 58 </executions> 59 </plugin> 60 61 <plugin> 62 <artifactId>maven-compiler-plugin</artifactId> 63 <configuration> 64 <source>1.8</source> 65 <target>1.8</target> 66 <encoding>UTF-8</encoding> 67 <compilerArguments> 68 <extdirs>${project.basedir}/lib</extdirs> 69 </compilerArguments> 70 </configuration> 71 </plugin> 72 73 </plugins> 74 </build> 75 76 </project>
resources目录下面的配置文件application.properties, 注意:该文件要utf8编码格式,不然中文会乱码
server.port=${port:8889}
logging.file=lmock.log
logging.path=logs
#userInfo
u.name=张三
u.sex=男
u.age=20
u.addr=北京市紫禁城
u.status=0
u.uid=123456789
#loginInfo
login.account=123456789@qq.com,987654321@163.com
login.pwd=123456
#responsemsg
ERROR.CODE.1001={"resultCode": 1001, "msg": "用户名或者密码错误"}
logback.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <configuration> 4 <include resource="org/springframework/boot/logging/logback/defaults.xml"/> 5 <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{80} - %msg%n"/> 6 <property name="LOG_PATH" value="${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}"/> 7 <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> 8 <file>${LOG_PATH}/${LOG_FILE}</file> 9 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 10 <fileNamePattern>${LOG_PATH}/${LOG_FILE}.%d{yyyy-MM-dd}</fileNamePattern> 11 </rollingPolicy> 12 <encoder charset="UTF-8"> 13 <pattern>${FILE_LOG_PATTERN}</pattern> 14 </encoder> 15 </appender> 16 17 18 <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 19 <encoder> 20 <pattern>${FILE_LOG_PATTERN}</pattern> 21 </encoder> 22 </appender> 23 24 <appender name="CRAWLER_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender"> 25 <file>${LOG_PATH}/event.log</file> 26 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 27 <fileNamePattern>${LOG_PATH}/event.%d{yyyy-MM-dd}.log</fileNamePattern> 28 <maxHistory>30</maxHistory> 29 </rollingPolicy> 30 <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> 31 <pattern>%msg%n</pattern> 32 </encoder> 33 </appender> 34 35 <logger name="com.business.intelligence.util.CrawlerLogger" level="INFO" additivity="false"> 36 <appender-ref ref="CRAWLER_LOG"/> 37 </logger> 38 39 <root level="INFO"> 40 <appender-ref ref="STDOUT"/> 41 <appender-ref ref="FILE"/> 42 </root> 43 44 </configuration>
入口程序:Application.java
1 import org.springframework.boot.SpringApplication;
2 import org.springframework.boot.autoconfigure.SpringBootApplication;
3 import org.springframework.context.annotation.ComponentScan;
4
5 @SpringBootApplication
6 @ComponentScan("com.lmock")
7 public class Application {
8
9 public static void main(String[] args) {
10 SpringApplication.run(Application.class, args);
11 }
12 }
javabean的类, LoginInfo.java UserInfo.java
1 package com.lmock.bean;
2
3 import lombok.Data;
4
5 @Data
6 public class UserInfo {
7 private String name;
8 private String sex;
9 private int age;
10 private String addr;
11 private int status;
12 private String uid;
13
14 @Override
15 public String toString() {
16 return "{"name": "" + name +
17 "", "sex": "" + sex +
18 "", "age": " + age +
19 ", "addr": "" + addr +
20 "", "status": " + status +
21 ", "uid": "" + uid +
22 ""}";
23 }
24 }
1 package com.lmock.bean;
2
3 import lombok.Data;
4
5 @Data
6 public class LoginInfo {
7 private String account;
8 private String pwd;
9 }
配置文件数据处理类, ReadConfig.java
1 package com.lmock.data;
2
3 import com.lmock.bean.UserInfo;
4
5 import java.io.UnsupportedEncodingException;
6 import java.util.Arrays;
7 import java.util.List;
8 import java.util.Locale;
9 import java.util.ResourceBundle;
10
11 public class ReadConfig {
12 private static ResourceBundle bundle = ResourceBundle.getBundle("application", Locale.PRC);
13
14 public static String login_account = bundle.getString("login.account");
15 public static List<String> login_account_list = Arrays.asList(login_account.split(","));
16 public static String login_pwd = bundle.getString("login.pwd");
17 public static String ERROR_CODE_1001 = transcoding("ERROR.CODE.1001");
18
19 public String readUserInfo() {
20 UserInfo ui = new UserInfo();
21 ui.setName(transcoding("u.name"));
22 ui.setSex(transcoding("u.sex"));
23 ui.setAge(Integer.parseInt(transcoding("u.age")));
24 ui.setAddr(transcoding("u.addr"));
25 ui.setStatus(Integer.parseInt(transcoding("u.status")));
26 ui.setUid(transcoding("u.uid"));
27 return ui.toString();
28 }
29
30 private static String transcoding(String key) {
31 try {
32 return new String(bundle.getString(key).getBytes("ISO-8859-1"), "UTF8");
33 } catch (UnsupportedEncodingException e) {
34 return bundle.getString(key);
35 }
36 }
37
38 }
接口实现类, PostDemo.java
1 package com.lmock.server;
2
3 import com.lmock.bean.LoginInfo;
4 import com.lmock.bean.UserInfo;
5 import com.lmock.data.ReadConfig;
6 import org.springframework.web.bind.annotation.RequestBody;
7 import org.springframework.web.bind.annotation.RequestMapping;
8 import org.springframework.web.bind.annotation.RequestMethod;
9 import org.springframework.web.bind.annotation.RestController;
10
11 @RestController
12 public class PostDemo {
13 @RequestMapping(value = "/v1/getUserInfo", method = RequestMethod.POST)
14 public String getUserInfo(@RequestBody LoginInfo loginInfo){
15 UserInfo ui;
16 if(loginInfo.getAccount().equals("123456789@qq.com") && loginInfo.getPwd().equals("123456")){
17 ui = new UserInfo();
18 ui.setName("张三");
19 ui.setAge(20);
20 ui.setAddr("北京市紫禁城");
21 ui.setSex("男");
22 ui.setStatus(0);
23 ui.setUid("123456789");
24 return ui.toString();
25 }
26 return "{"resultCode": 1001, "msg": "用户名或者密码错误"}";
27 }
28
29 @RequestMapping(value = "/v2/getUserInfo", method = RequestMethod.POST)
30 public String getUserInfoWithConfig(@RequestBody LoginInfo loginInfo){
31 if(ReadConfig.login_account_list.contains(loginInfo.getAccount()) && loginInfo.getPwd().equals(ReadConfig.login_pwd)){
32 return new ReadConfig().readUserInfo();
33 }
34 return ReadConfig.ERROR_CODE_1001;
35 }
36 }
最后决定用V2的方式写Mock, 这样接口参数校验的逻辑写好后, 只需要修改properties配置文件数据即可, 这样就可以当作一个测试桩, 也可以把桩要返回的数据写成json文件,这里没有去研究了, 个人觉得写成配置文件也挺好的,特别是需要多个数据, 可以利用List
启动Mock后,接口请求的效果