【自动化测试实战】从 0 到 1 搭建 Dubbo 接口自动化测试

前言

由于公司 Dubbo 接口数量较多,且核心接口较多,故需要一套 Dubbo 接口自动化框架,来提高测试效率。

1、Dubbo 接口自动化测试框架实现逻辑

2、框架具体功能

框架需要
实现功能

功能说明当前版本是否已实现从 maven 库自动下载所需 jar 包为了更好的自动化,所有的 provider 的 jar 都从 maven 下载,避免手工导入已实现参数自定义匹配不同的 Dubbo 接口,不同的参数需求已实现断言功能一个接口是否调用成功,在于断言是否成功已实现邮件报警功能如果 Dubbo 接口调用 provider 失败,自动进行邮件报警已实现自动运行利用 jenkins 自动运行已实现

3、关键实践
由于目前阶段刚接触 java 及 Dubbo,本次实现为基本功能实现,数据隔离等没有做。
3.1 下载 provider 的 jar 包,并代理声明 +zookeeper 设置

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:Dubbo="http://code.alibabatech.com/schema/Dubbo"

xmlns:p="http://www.springframework.org/schema/p"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://code.alibabatech.com/schema/Dubbo

http://code.alibabatech.com/schema/Dubbo/Dubbo.xsd">


<Dubbo:application name="demo-consumer"/>


<Dubbo:registry address="zookeeper://1127.0.0.1:2181" />


<Dubbo:reference id="IPromiseForOrderService" interface="com.test.api.IPromiseForOrderService" version="1.0" check="true"/>

</beans>

3.2 邮件发送功能

(1)邮件服务器配置在 mailConfig.properties


(2)获取 mailconfig 信息,并封装成类



public class MailConfig {

private static final String PROPERTIES_DEFAULT = "mailConfig.properties";

public static String host;

public static Integer port;

public static String userName;

public static String passWord;

public static String emailForm;

public static String timeout;

public static String personal;

public static Properties properties;

static{

init();

}


/**

* 初始化

*/

private static void init() {

properties = new Properties();

InputStream inputStream = null;

try{


inputStream = MailConfig.class.getClassLoader().getResourceAsStream(PROPERTIES_DEFAULT);

properties.load(inputStream);

inputStream.close();

host = properties.getProperty("mailHost");

port = Integer.parseInt(properties.getProperty("mailPort"));

userName = properties.getProperty("mailUsername");

passWord = properties.getProperty("mailPassword");

emailForm = properties.getProperty("mailFrom");

timeout = properties.getProperty("mailTimeout");

personal = " 自动化测试 ";

} catch(IOException e){

e.printStackTrace();

}

}

}

(3)封装发送邮件功能


public class MailUtil {

private static final String HOST = MailConfig.host;

private static final Integer PORT = MailConfig.port;

private static final String USERNAME = MailConfig.userName;

private static final String PASSWORD = MailConfig.passWord;

private static final String emailForm = MailConfig.emailForm;

private static final String timeout = MailConfig.timeout;

private static final String personal = MailConfig.personal;

private static JavaMailSenderImpl mailSender = createMailSender();

/**

* 邮件发送器

*

* @return 配置好的工具

*/

private static JavaMailSenderImpl createMailSender() {

JavaMailSenderImpl sender = new JavaMailSenderImpl();

sender.setHost(HOST);

sender.setPort(PORT);

sender.setUsername(USERNAME);

sender.setPassword(PASSWORD);

sender.setDefaultEncoding("Utf-8");

Properties p = new Properties();

p.setProperty("mail.smtp.timeout", timeout);

p.setProperty("mail.smtp.auth", "false");

sender.setJavaMailProperties(p);

return sender;

}


/**

* 发送邮件

*

* @param to 接受人

* @param subject 主题

* @param html 发送内容

* @throws MessagingException 异常

* @throws UnsupportedEncodingException 异常

*/

public void sendMail(InternetAddress[] to, String subject, String html) throws MessagingException,UnsupportedEncodingException {

MimeMessage mimeMessage = mailSender.createMimeMessage();

// 设置 utf-8 或 GBK 编码,否则邮件会有乱码

MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");

messageHelper.setFrom(emailForm, personal);

messageHelper.setTo(to);

messageHelper.setSubject(subject);

messageHelper.setText(html, false);

mailSender.send(mimeMessage);

}

}

3.3 封装 Dubbo 接口信息类

把 Dubbo 接口封装成一个类,方便信息 get 和 set


public class DubboInterfaceInfo {

private String DubboInterfaceWiki;

private String DubboInterfacePacketName;

private String DubboInterfaceClassName;

private RestRequest request;

private String responseStatusSuccessful;

private String responseMessageSuccessful;

private String DubboInterfaceId;


public DubboInterfaceInfo() {}


public String getDubboInterfaceWiki() {

return this.DubboInterfaceWiki;

}

public void setDubboInterfaceWiki(String DubboInterfaceWiki) {

this.DubboInterfaceWiki = DubboInterfaceWiki;

}


public String getDubboInterfacePacketName() {

return this.DubboInterfacePacketName;

}

public void setDubboInterfacePacketName(String DubboInterfacePacketName) {

this.DubboInterfacePacketName = DubboInterfacePacketName;

}


public String getDubboInterfaceClassName() {

return this.DubboInterfaceClassName;

}

public void setDubboInterfaceClassName(String DubboInterfaceClassName) {

this.DubboInterfaceClassName = DubboInterfaceClassName;

}


public RestRequest getRestRequest() {

return this.request;

}

public void setRestRequest(RestRequest request) {

this.request = request;

}


public String getResponseStatusSuccessful() {

return this.responseStatusSuccessful;

}

public void setResponseStatusSuccessful(String responseStatusSuccessful) {

this.responseStatusSuccessful = responseStatusSuccessful;

}


public String getResponseMessageSuccessful() {

return this.responseMessageSuccessful;

}

public void setResponseMessageSuccessful(String responseMessageSuccessful) {

this.responseMessageSuccessful = responseMessageSuccessful;

}


public String getDubboInterfaceId() {

return this.DubboInterfaceId;

}

public void setDubboInterfaceId(String DubboInterfaceId) {

this.DubboInterfaceId = DubboInterfaceId;

}

}

3.4 利用 JMeter 调用 provider 服务,并断言,邮件报警

利用 Jmeter 调用 provider 服务,并断言,邮件报警,这些功能封装成 Dubbo 接口测试类,代码如下:


public class IPromiseForOrderServiceTest extends AbstractJavaSamplerClient {

/**

* CONTEXT

* 读取 Dubbo-config.xml 中的内容

*/

private static final ApplicationContext CONTEXT = new ClassPathXmlApplicationContext("Dubbo-config.xml");

public DubboInterfaceInfo DubboInterfaceInfo = new DubboInterfaceInfo();

public String responseSuccess;

public String responseFail;

public FreeStockForOrderParam request;

/**

* IPromiseForOrderService

* 此处需要实例化 Dubbo 接口 IPromiseForOrderService,像定义变量一样实例化

*/

private static IPromiseForOrderService IPromiseForOrderService;


/**

* IPromiseForOrderService

* 以下方法用于 输入 Dubbo 接口信息

*/

public void DubboInterfaceInfoInitialization () {

DubboInterfaceInfo.setDubboInterfaceWiki("......");

DubboInterfaceInfo.setDubboInterfacePacketName("......");

DubboInterfaceInfo.setDubboInterfaceClassName("......");

DubboInterfaceInfo.setDubboInterfaceId("......");

DubboInterfaceInfo.setResponseStatusSuccessful("0");

DubboInterfaceInfo.setResponseMessageSuccessful("success");

String orderNo = "orderNo";

String operater="";

String channel="";

String operateId="operateId";

String version= PromiseVersion.V_1_0_0.getVersion();

request = new FreeStockForOrderParam();

if (orderNo != null || orderNo.length() > 0) {

request.setOrderNo(orderNo);

}

if (operater != null || operater.length() > 0) {

request.setOperater(operater);

}

if (channel != null || channel.length() > 0) {

request.setChannel(channel);

}

if (operateId != null || operateId.length() > 0) {

request.setOperateId(operateId);

}

if (version != null || version.length() > 0) {

request.setVersion(version);

}

RestRequest<FreeStockForOrderParam> req = new RestRequest<FreeStockForOrderParam>();

req.setRequest(request);

DubboInterfaceInfo.setRestRequest(req);

}



@Override

public void setupTest(JavaSamplerContext arg0){

IPromiseForOrderService=(IPromiseForOrderService)CONTEXT.getBean("......");

}


@Override

public SampleResult runTest(JavaSamplerContext javaSamplerContext) {

SampleResult sr = new SampleResult();


try {

sr.sampleStart();

RestResponse responseData = IPromiseForOrderService.freeSaleStock(DubboInterfaceInfo.getRestRequest());

// 自定义 Dubbo 调用成功和失败的邮件正文内容

responseSuccess =

"Dubbo 接口: "

+ DubboInterfaceInfo.getDubboInterfaceId() + " 请求成功\r\n"

+ "WIKI 地址: " + DubboInterfaceInfo.getDubboInterfaceWiki() + "\r\n"

+ "PacketName: " + DubboInterfaceInfo.getDubboInterfacePacketName() + "\r\n"

+ "ClassName: " + DubboInterfaceInfo.getDubboInterfaceClassName() + "\r\n"

;

responseFail =

"Dubbo 接口: " + DubboInterfaceInfo.getDubboInterfaceId() + " 请求失败\r\n"

+ "WIKI 地址: " + DubboInterfaceInfo.getDubboInterfaceWiki() + "\r\n"

+ "PacketName: " + DubboInterfaceInfo.getDubboInterfacePacketName() + "\r\n"

+ "ClassName" + DubboInterfaceInfo.getDubboInterfaceClassName() + "\r\n"

+ " 请求参数为:Channel: " + request.getChannel() +

" / operater: " + request.getOperater() +

" / OperateId: " + request.getOperateId() +

" / OrderNo: " + request.getOrderNo() +

" / Version: " + request.getVersion()

+ "\r\n"

+ " 返回结果为:"

+ "ResponseStatus: " + responseData.getStatus()

+ " / ResponseMessage: " + responseData.getMessage()

+ " / ResponseResult: " + responseData.getResult();



/**

* 邮件定义及发送

*/

InternetAddress[] address = new InternetAddress[2];

try {

address[0] = new InternetAddress("lalllalala@qq.com");

address[1] = new InternetAddress("3456789@qq.com");

} catch (AddressException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

MailUtil mailUtil = new MailUtil();


if ((DubboInterfaceInfo.getResponseStatusSuccessful().equals(responseData.getStatus())) && (DubboInterfaceInfo.getResponseMessageSuccessful().equals(responseData.getMessage()))) {

sr.setSuccessful(true);

sr.setResponseData("responseData: " + responseData, "utf-8");

System.out.println(responseSuccess);

mailUtil.sendMail(address,"Dubbo 接口:" + DubboInterfaceInfo.getDubboInterfaceId() + " 请求成功 ",responseSuccess.toString());


} else {

sr.setSuccessful(false);

System.out.println(responseFail);

mailUtil.sendMail(address,"Dubbo 接口:" + DubboInterfaceInfo.getDubboInterfaceId() + " 请求失败 ",responseFail.toString());

}


sr.sampleEnd();

} catch (Exception e) {

e.printStackTrace();

}


return sr;

}



}

3.5 利用 Testng 注释,调用 Dubbo 接口类,进行测试

public class TestngTest {

@Test()

public void testDubboInterface() {

JavaSamplerContext arg0 = new JavaSamplerContext(new Arguments());


Dubbo 接口测试类 TestForIPromiseForOrderService = new Dubbo 接口测试类 ();

TestForIPromiseForOrderService.DubboInterfaceInfoInitialization();

TestForIPromiseForOrderService.setupTest(arg0);

SampleResult sr = TestForIPromiseForOrderService.runTest(arg0);

}

}
4、利用 Jenkins 自动化运行 Dubbo 测试项目

至此,大功告成,你可以完成 Dubbo 接口自动化测试了。另,接下来可以加入关联、测试数据分离等功能,让框架变得更加易用。

行动吧,在路上总比一直观望的要好,未来的你肯定会感 谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入扣群: 320231853,里面有各种软件测试+开发资料和技术可以一起交流学习哦。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值