因最近在学习springboot,想着这么NB的框架如果用来写接口自动化会怎样呢?于是自己就搭建了一个接口自动化的框架。
在看该项目时,需要一点点的springboot基础。话不多说,直接上源码,将代码复制过去改下接口就能运行。有写的不好的地方,还请各位大佬指点指点。
1.先看下整个项目结构:
2.项目的 pom.xml文件
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.4.0
org.example
pdhttp
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.0
mysql
mysql-connector-java
runtime
org.apache.httpcomponents
httpclient
4.5.5
com.alibaba
fastjson
1.2.47
org.springframework.boot
spring-boot-configuration-processor
true
junit
junit
test
com.alibaba
fastjson
1.2.51
springboot引导类:
package com.itcast; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class AppHttp { public static void main(String[] args) { SpringApplication.run(AppHttp.class,args); } }
2.分层设计的思想和完整的web项目一样,根据controller、service、dao三层
service层用来管理测试用例集
service接口源代码:
package com.itcast.service;
import org.apache.http.client.methods.CloseableHttpResponse;
import java.util.Map;
public interface LoginHttp {
CloseableHttpResponse login(String url, Map map);
}
service实现类:
package com.itcast.service.impl;
import com.itcast.common.RunTest;
import com.itcast.service.LoginHttp;
import com.itcast.utils.TestStringUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
public class LoginHttpImpl implements LoginHttp {
@Autowired
private RunTest runTest;
@Override
public CloseableHttpResponse login(String url, Map map) {
String params = TestStringUtil.setParams(map);
return runTest.run_Post(url,params);
}
}
controller层用来控制分发接口请求
package com.itcast.controller;
import com.itcast.object.Inter;
import com.itcast.service.LoginHttp;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class LoginController {
@Autowired
private LoginHttp loginHttp;
@Autowired
private Inter inter;
public CloseableHttpResponse login(String url_type, Map map){
String url = inter.getAddress().get(url_type);
return loginHttp.login(url,map);
}
}
dao层用来管理接口的测试数据
package com.itcast.dao;
import com.itcast.object.LoginObj;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface InterMapper {
@Select("select * from loginuser")
List selectAll();
@Select("select * from user where id=#{id}")
LoginObj select(int id);
}
3.自定义一个Bean配置类,用来反向控制对象的创建(目前只加了一个httpClient,后期可根据自己的业务的需求进行开发)
package com.itcast.config;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HttpConfig {
@Bean
@ConditionalOnMissingBean
@ConditionalOnClass
public CloseableHttpClient httpClient(){
return HttpClientBuilder.create().build();
}
}
4.其次是工具类和实体类还有封装HttpClient里的常用请求方法(只写了一点点)
工具类:
package com.itcast.utils;
import java.util.Map;
public class TestStringUtil {
//参数化
public static String setParams(Map map){
StringBuffer sb=new StringBuffer("?");
if (isEmpty(map)){
System.out.println("参数为空,请检查!");
}
for (String key : map.keySet()) {
sb.append(key+"="+map.get(key)+"&");
}
return sb.toString();
}
public void test(){
}
public static boolean isEmpty(Object o){
if (null==o || o.toString().length()==0){
return true;
}else {
return false;
}
}
}
数据库映射实体类:
package com.itcast.object;
import java.util.Date;
public class LoginObj {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "LoginObj{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
httpClient请求方法的封装
package com.itcast.common;
import com.alibaba.fastjson.JSON;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class RunTest {
@Autowired
private CloseableHttpClient httpClient;
public CloseableHttpResponse run_Get(String param){
return null;
}
/**
*
* @param url 请求地址
* @param params 请求参数(字符串类型)
* @return 响应消息对象
*/
public CloseableHttpResponse run_Post(String url,String params){
HttpPost post=new HttpPost(url+params);
post.setHeader("Content-Type","application/json;charset=utf-8");
CloseableHttpResponse response=null;
try {
response=httpClient.execute(post);
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
/**
*
* @param url 请求地址
* @param params 请求参数(对象类型)
* @return 响应消息对象
*/
public CloseableHttpResponse run_Post2(String url,Object params){
HttpPost post=new HttpPost();
String json = JSON.toJSONString(params);
StringEntity entity=new StringEntity(json,"UTF-8");
post.setEntity(entity);
post.setHeader("Content-Type","application/json;charset=utf-8");
CloseableHttpResponse response=null;
try {
response=httpClient.execute(post);
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
}
5.接口地址常量类。主要用来管理接口地址的映射关系,便于维护
package com.itcast.object;
public class Address_Url {
public static final String LOGIN_URL="login";
}
6.yml配置文件。这里我把接口地址和jdbc的数据源都放在一个yml中了,可以分开写的
inter:
address: {login: http://localhost:8081/user/login}
name: aaaa
spring:
datasource:
url: jdbc:mysql://localhost:3306/db1?serverTimezone=GMT
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
7.yml配置的实体类。主要用来获取yml配置中的数据
package com.itcast.object;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@ConfigurationProperties(prefix = "inter")
public class Inter {
private Map address;
private String name;
public Map getAddress() {
return address;
}
public void setAddress(Map address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Inter{" +
"address=" + address +
", name='" + name + '\'' +
'}';
}
}
8.测试类
import com.alibaba.fastjson.JSON;
import com.itcast.AppHttp;
import com.itcast.controller.LoginController;
import com.itcast.dao.InterMapper;
import com.itcast.object.Address_Url;
import com.itcast.object.LoginObj;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AppHttp.class)
public class TestCase {
@Autowired
private CloseableHttpClient httpClient;
@Autowired
private LoginController loginController;
@Autowired
private InterMapper interMapper;
@Test
public void test() throws IOException {
LoginObj login_obj = interMapper.select(1);
Map map = JSON.parseObject(JSON.toJSONString(login_obj), Map.class);
CloseableHttpResponse response = loginController.login(Address_Url.LOGIN_URL, map);
HttpEntity entity = response.getEntity();
String text = EntityUtils.toString(entity);
System.out.println(response.getStatusLine());
System.out.println(text);
closeResponse(response);
}
public void closeResponse(CloseableHttpResponse response){
try {
if (response!=null) {
response.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}