zoukankan      html  css  js  c++  java
  • 实战 | 从 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 接口自动化测试了。另,接下来可以加入关联、测试数据分离等功能,让框架变得更加易用。

    ** _
    来霍格沃兹测试开发学社,学习更多软件测试与测试开发的进阶技术,知识点涵盖web自动化测试 app自动化测试、接口自动化测试、测试框架、性能测试、安全测试、持续集成/持续交付/DevOps,测试左移、测试右移、精准测试、测试平台开发、测试管理等内容,课程技术涵盖bash、pytest、junit、selenium、appium、postman、requests、httprunner、jmeter、jenkins、docker、k8s、elk、sonarqube、jacoco、jvm-sandbox等相关技术,全面提升测试开发工程师的技术实力
    QQ交流群:484590337
    公众号 TestingStudio
    点击获取更多信息

  • 相关阅读:
    微信小程序从零开始开发步骤(三)
    微信小程序从零开始开发步骤(三)底部导航栏
    微信小程序从零开始开发步骤(二)
    微信小程序从零开始开发步骤(二)
    微信小程序从零开始开发步骤(一)
    [NOIP2016]组合数问题
    5.20 考试 20 未完
    lca 例题 WK
    rmq RMQ
    BZ
  • 原文地址:https://www.cnblogs.com/hogwarts/p/15842264.html
Copyright © 2011-2022 走看看