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

前言

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

2、框架具体功能

3、关键实践

3.1 下载 provider 的 jar 包,并代理声明 +zookeeper 设置

3.2 邮件发送功能

3.3 封装 Dubbo 接口信息类

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

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

4、利用 Jenkins 自动化运行 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("[email protected]");
                address[1] = new InternetAddress("[email protected]");
            } 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 接口自动化测试了。另,接下来可以加入关联、测试数据分离等功能,让框架变得更加易用。

最后: 为了回馈铁杆粉丝们,我给大家整理了完整的软件测试视频学习教程,朋友们如果需要可以自行免费领取 【保证100%免费】

加入我的软件测试交流群:110685036免费获取~(同行大佬一起学术交流,每晚都有大佬直播分享技术知识点)

软件测试面试小程序

被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!

涵盖以下这些面试题板块:

1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux

6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

获取方式 :

猜你喜欢

转载自blog.csdn.net/IT_LanTian/article/details/131021561