예제 #1
0
    def _send_IM(self):
        """
        IM report 发送到IM群
        如果需要自定义内容,可实现_custom_IM_body方法
        """
        LogUtil.info(u"[IM SEND BEGIN] 开始发送IM 群通知。。。")
        IM_body, pass_rate = IM_report.format_simple_summary(
            self.unittest_results)

        # 当前服务请求接口数量
        covered_api_counter = self.__counter_current_project_covered_api()
        if covered_api_counter:
            IM_body += "\ncovered_api_counter : {}\n".format(
                covered_api_counter)

        # 自定义内容
        custom_IM_body = self._custom_IM_body()

        final_IM_body = u"{}\n详细报告 :<a href=http://{}/auto_reports/{}/{}>Report Link</a> \n{}".format(
            IM_body, tomcat_server, self.project_name, self.report_file_name,
            custom_IM_body)
        title_time = time.strftime("%Y-%m-%d_%H:%M", time.localtime())
        msg_title = u"{} 自动化测试报告_{} - 通过率 : {} %".format(
            self.project_name.upper(), title_time, pass_rate)
        self.IM_client.bot_join_group(self.group_id)
        self.IM_client.send_msg_to_group(msg_title, final_IM_body,
                                         self.group_id)
        for receiver in self.report_receiver_list:
            self.IM_client.send_msg_to_person(msg_title, final_IM_body,
                                              receiver)
예제 #2
0
    def get_random_size_list(my_list, list_size=None):
        '''
        从一个list里面,生成随机大小的子集list;
        比如: [2,5,7,9] 可能随机的结果是 [2,5], 也可能是[5,7,9]
        :param my_list: 原始list
        :param list_size: 期望拿到的输出的list 长度,必须要小于原始list长度
        :return:
        '''
        if list_size is not None:
            if list_size > len(my_list):
                raise Exception("期望得到的list_size,超过了当前list 最大值 - {}!!!".format(
                    len(list)))
            how_many = list_size
        else:
            if len(my_list) < 1:
                LogUtil.error("当前应该有错误,需要看一下 this_list: {}".format(
                    str(my_list)))
                raise Exception(u" 期望de this_list长度小于1!!!")
            how_many = random.randint(1, len(my_list))

        tmp_list = deepcopy(my_list)
        final_list = []
        for i in xrange(how_many):
            rand_item = tmp_list[random.randint(1, len(tmp_list)) - 1]

            final_list.append(rand_item)
            tmp_list.pop(tmp_list.index(rand_item))

        return final_list
예제 #3
0
    def send_IM(self, pass_rate, total, _pass, failure, error,
                merge_report_file_name):
        """
        IM report 发送到IM群
        如果需要自定义内容,可实现_custom_IM_body方法
        """
        LogUtil.info(u"[IM SEND BEGIN] 开始发送IM 群通知。。。")
        IM_body, pass_rate = IM_report.format_report_for_temporary_test(
            pass_rate=pass_rate,
            total_case=total,
            pass_case=_pass,
            failure_case=failure,
            error_case=error,
        )

        # 自定义内容
        custom_IM_body = self._custom_IM_body()
        final_IM_body = u"{}\n详细报告 :<a href=http://{}/auto_reports/{}/{}>Report Link</a> \n{}".format(
            IM_body, tomcat_server, self.project_name, merge_report_file_name,
            custom_IM_body)
        title_time = time.strftime("%Y-%m-%d_%H:%M", time.localtime())
        msg_title = u"{} 自动化测试报告_{} - 通过率 : {} %".format(
            self.project_name.upper(), title_time, pass_rate)

        self.IM_client.send_msg_to_group(msg_title, final_IM_body,
                                         self.group_id)
        for receiver in self.report_receiver_list:
            self.IM_client.send_msg_to_person(msg_title, final_IM_body,
                                              receiver)
예제 #4
0
 def _print_cover_request_url_set(self, request_url_set):
     LogUtil.info(
         u"\n-----------------------------------------------------------------------"
     )
     LogUtil.info(u"【URL 覆盖】当前项目【{}】 覆盖的url,接口如下: ".format(
         self.project_name))
     print('\n'.join(request_url_set))
예제 #5
0
 def _gen_rpc_payload(self, func_name, params_body):
     body = {}
     body['rpc_server_name'] = self.rpc_server_name
     body['func_name'] = func_name
     body['request'] = json.dumps(params_body)
     if self.address:
         body['address'] = self.address
     LogUtil.print_dict_in_lines(body, u"rpc payload")
     return json.dumps(body)
예제 #6
0
    def get_for_xxx(self, param_1, param_2):
        LogUtil.step(u"--- 通过API xxxx {} {}".format(param_1, param_2))

        params = {
            "param_1": param_1,
            "param_2": param_2,
        }
        rsp = MyRequests.get(self.GET_API, params=params)
        return rsp.json().get('data')
예제 #7
0
    def post_for_xxx(self, param_1, param_2):
        LogUtil.step(u"--- 通过API xxxx {} {}".format(param_1, param_2))

        data = {
            "param_1": param_1,
            "param_2": param_2,
        }
        req = MyRequests.post(self.POST_API, data=data, is_json=True)
        return req.json().get('code'), req.json().get('msg'), req.json().get('data')
예제 #8
0
 def _post(self):
     """
     后处理 用于处理数据,结果处理,展示等 这里暂时不留钩子
     """
     # 拷贝到远程
     if self.is_scp_to_remote:
         self._scp_to_remote()
     else:
         LogUtil.info(u"[REMOTE] 指定不拷贝到远程!本地文件名不带时间戳。")
예제 #9
0
    def get_email():
        '''
        随机生成一个可用的邮箱
        :return:
        '''
        randNumb = random.randint(1, 9999999)
        mail = "auto.mail.{}@bytedance.com".format(randNumb)

        LogUtil.info(u"使用随机生成的email :  " + str(mail))
        return mail
예제 #10
0
    def __generate_local_report_file_path(self):
        """
        生成本地文件路径,这里用的根路径加report
        """
        local_report_file_full_path = os.path.abspath(
            os.path.join(test_env_config.ROOT_DIR, "report",
                         self.report_file_name))
        LogUtil.info("Report_name=" + self.report_file_name)
        LogUtil.info(u"报告存放位置: \n" + local_report_file_full_path)

        # 确定生成报告的本地全路径
        self.local_report_file_full_path = local_report_file_full_path
예제 #11
0
    def address(self):
        if self.rpc_host not in VALID_TEST_HOST:
            raise Exception(
                "测试环境可用机器列表: {}, 不包含 当前请求的rpc host: {}\n "
                " -- 如果有例外,local 使用时候,可以屏蔽这里\n"
                "['注意!!!']不可以把线上ip push上去,自动化干的事情,谁也保不齐!!!".format(
                    VALID_TEST_HOST, self.rpc_host))

        if self.rpc_port and self.rpc_port:
            return "{}:{}".format(self.rpc_host, self.rpc_port)
        else:
            LogUtil.error(u'本次没有指定rpc的IP和端口,本次请求会打到线上!')
            return
예제 #12
0
    def test_1(self):
        """\
        说明\
        <br> 步骤与校验\
        <br> 1. 步骤 校验\
        <br> 2. 步骤 校验\
        <br> 3. 步骤 校验\
        """
        LogUtil.step(u"步骤1")
        param = self.db_cont_ops.get_first_info(1, 'name')

        LogUtil.verify(u"校验1")
        self.verify_1(param)
예제 #13
0
 def _act(self):
     """
     执行case,产生结果
     """
     self._generate_var()
     LogUtil.info(u"[RUN BEGIN] 结果输出到本地路径: {}".format(
         self.local_report_file_full_path))
     local_out_stream = open(self.local_report_file_full_path, 'wb')
     runner = HTMLTestRunner.HTMLTestRunner(
         stream=local_out_stream,
         title=self.report_title,
         description=self.report_description)
     self.unittest_results = runner.run(self.suite())
     LogUtil.info(u"[RUN END] 结果输出到本地路径: {}".format(
         self.local_report_file_full_path))
예제 #14
0
    def get_name(sale_id=None):
        '''
        随机生成一个名称,有Auto关键字
        :param sale_id: 不填写没东西,如果填写了虚拟人员id,会拼写虚拟人员中文名
        :return:
        '''
        ticks = str(int(time.time()))
        # ran = str(random.randint(0, 50000))

        if sale_id:
            name = people_dict.get_name_by_id(sale_id)
        else:
            name = u"名字"
        name = u"Auto-{}{}".format(name, ticks)
        LogUtil.info(u"随机生成的名称: {}".format(name))
        return name
예제 #15
0
 def post_after_merge(self, pass_rate, total, _pass, failure, error,
                      merge_report_file_name):
     """
     合并后发送IM消息
     """
     # 拷贝到远程
     if self.is_scp_to_remote:
         self.scp_merge_file_to_remote(merge_report_file_name)
     else:
         LogUtil.info(u"[REMOTE] 指定不拷贝到远程!本地文件名不带时间戳。")
     # 发送IM通知
     if self.is_send_IM:
         self.send_IM(pass_rate=pass_rate,
                      total=total,
                      _pass=_pass,
                      failure=failure,
                      error=error,
                      merge_report_file_name=merge_report_file_name)
예제 #16
0
    def get_number_serial(length=None):
        '''
        随机生成一个数字序列号 返回 str 至少3位
        '''
        if length == None:
            return str(random.randint(19999999999999, 99999999999999))

        elif length > 3:
            number_of_zero = length - 1
            start_serial = "1{}".format("".rjust(number_of_zero, str('0')))
            start_long = long(start_serial)
            end_serial = "1{}".format("".rjust(length, str('0')))
            end_long = long(end_serial) - 1
            randNumb = random.randint(start_long, end_long)
        else:
            raise Exception(u'[ERROR]目前只支持三维以上随机数生成!!!')

        LogUtil.info(u"使用随机生成的长传数字:  " + str(randNumb))
        return randNumb
예제 #17
0
 def _record_performance(start, request_obj):
     """
     记录性能相关,如果超过阈值,记录下来请求内容
     """
     end = datetime.datetime.now()
     diff_seconds = (end - start).total_seconds()
     LogUtil.info(u"-----------------------------------------------")
     LogUtil.info(u"【性能】请求花费时间 {} s ".format(diff_seconds))
     LogUtil.info(u"-----------------------------------------------")
예제 #18
0
    def _print_request_cost_info(self, request_list):
        LogUtil.info(
            u"\n-----------------------------------------------------------------------"
        )
        LogUtil.info(u"【性能】接口耗时,超过 '{}' s 的接口请求如下: ".format(
            cached_data.time_cost_threshold))

        if len(request_list) == 0:
            LogUtil.info(u"棒棒的,没有任何请求超过阈值!")

        request_url_dict = {}

        for request in request_list:
            request_url_dict[request.get('request').get('url')] = request.get(
                'time')

        DataFormatter().print_dict_in_lines(request_url_dict)
예제 #19
0
    def _scp_to_remote(self):
        """
        拷贝到远程
        """
        server_location = "{}:{}{}/".format(
            tomcat_server.split(":")[0], server_tomcat_dir, self.project_name)

        scp_command = 'scp {} {}'.format(self.local_report_file_full_path,
                                         server_location)
        LogUtil.info(u"[SCP REMOTE BEGIN] 拷贝到远程 命令: {}".format(scp_command))
        os.system(scp_command)
        LogUtil.info(
            u"[SCP REMOTE END] 拷贝完成 remote tomcat server : \n    {}".format(
                scp_command))

        remote_url_head = "http://{}/auto_reports/{}/".format(
            tomcat_server, self.project_name, self.report_file_name)
        remote_full_path = remote_url_head + self.report_file_name
        LogUtil.info(u"远端服务器URL: {}".format(remote_full_path))
예제 #20
0
    def _post(self):
        """
        后处理 用于处理数据,结果处理,展示等 这里暂时不留钩子
        """
        # 拷贝到远程
        if self.is_scp_to_remote:
            self._scp_to_remote()
        else:
            LogUtil.info(u"[REMOTE] 指定不拷贝到远程!本地文件名不带时间戳。")
        # 发送IM通知
        if self.is_send_IM:
            self._send_IM()
        else:
            LogUtil.info(u"[IM] 指定不发送IM")
        LogUtil.info(u"最后再次打印报告存放位置: \n" + self.local_report_file_full_path)

        # 最后打印一下,性能可能超标的请求 set
        self._print_request_cost_info(cached_data.request_list)
        self._print_cover_request_url_set(cached_data.request_path_set)
예제 #21
0
    def scp_merge_file_to_remote(self, merge_report_file_name):
        """
        拷贝到远程
        """
        server_location = "{}:{}{}/".format(
            tomcat_server.split(":")[0], server_tomcat_dir, self.project_name)
        import os
        local_report_file_full_path = os.path.abspath(
            os.path.join(test_env_config.ROOT_DIR, "report",
                         merge_report_file_name))

        scp_command = 'scp {} {}'.format(local_report_file_full_path,
                                         server_location)
        LogUtil.info(u"[SCP REMOTE BEGIN] 拷贝到远程 命令: {}".format(scp_command))
        import os
        os.system(scp_command)
        LogUtil.info(
            u"[SCP REMOTE END] 拷贝完成 remote tomcat server : \n    {}".format(
                scp_command))

        remote_url_head = "http://{}/auto_reports/{}/".format(
            tomcat_server, self.project_name, merge_report_file_name)
        remote_full_path = remote_url_head + merge_report_file_name
        LogUtil.info(u"远端服务器URL: {}".format(remote_full_path))
예제 #22
0
    def rpc_request(self, func_name, params_body):
        """
        通过MS测试通用接口调用rpc接口获取结果
        :param func_name: rpc方法名 不带括号,不带参数描述,支持下划线形式 如 query_a_b_c
        :param params_body: dict 该方法req的 params map
        :return: 调用成功的结果
        """
        LogUtil.info(u"-----------------【rpc Request】 ----------------")

        LogUtil.info(u"  基础参数  rpc_server_name: {}, address: {}".format(self.rpc_server_name, self.address))
        payload = self._gen_rpc_payload(func_name, params_body)

        start = datetime.datetime.now()

        errno, data, msg = rpcOps().request_rpc_server_name_rpc(data=payload)
        end = datetime.datetime.now()

        diff_seconds = (end - start).total_seconds()

        LogUtil.info(u"-----------------【rpc Response】 ----------------")
        LogUtil.info(u" errno: {}, msg: {}, data: {}".format(errno, msg, data.__repr__().decode("unicode-escape")))
        LogUtil.info(u"-----------------------------------------------")
        LogUtil.info(u"【性能】请求花费时间 {} s ".format(diff_seconds))
        LogUtil.info(u"-----------------------------------------------")
        if errno:
            raise Exception(u"MS 接口调用结果错误,msg:{}".format(msg))

        return data
예제 #23
0
    def log_response_details(response_body):
        LogUtil.info(
            "-----[RESPONSE] details below : ----------------------------")

        LogUtil.info('Returned code: {}'.format(response_body.status_code))

        if response_body.status_code != 200:
            LogUtil.info("[WARN]Return code is not 200!!!! but {} .".format(
                response_body.status_code))

            err_msg = response_body.text
            try:
                json_body = response_body.json()
                s = str(json_body).replace('u\'', '\'')
                LogUtil.info('  Response: ')
                LogUtil.info(s.decode('unicode-escape'))
                err_msg = s.decode('unicode-escape')
            except Exception as e:
                LogUtil.error('Response raw data: ')
                LogUtil.exception(err_msg, e)

            LogUtil.error(
                u"\n【FATAL ERROR】检查请求细节是否出错,或者服务器是否有问题\n      ---->>  {}".
                format(err_msg))

        else:
            try:
                json_body = response_body.json()
                s = str(json_body).replace('u\'', '\'')
                LogUtil.info('  Response: ')
                LogUtil.info(s.decode('unicode-escape'))

            except:
                LogUtil.info(u'  Response raw data: \n{}'.format(
                    response_body.text))
                raise Exception("http请求的返回不是Json格式,检查服务器是否有问题")

        LogUtil.info(
            "------------------------------------------------------------------------"
        )
예제 #24
0
    def log_request_details(url=None,
                            headers=None,
                            cookies=None,
                            params=None,
                            data=None,
                            json_data=None,
                            method=None):
        LogUtil.info(
            "-----[REQUEST] details below : ----------------------------")

        time_stamp = datetime.datetime.now()
        LogUtil.info("  Current time  : {}".format(
            time_stamp.strftime('%Y.%m.%d-%H:%M:%S')))

        LogUtil.info("  Request : {}".format(url))

        if headers:
            LogUtil.info("  Headers : {}".format(headers))
        if cookies:
            LogUtil.info("  Cookies : {}".format(cookies))
        if params:
            try:
                LogUtil.info("  Parameters : {}".format(
                    params.__repr__().decode("unicode-escape")))
            except:
                LogUtil.info("  Parameters : {}".format(params))

        if method:
            LogUtil.info("  Method : {}".format(method))
        if data:
            try:
                LogUtil.info("  Payload : {}".format(
                    data.__repr__().decode("unicode-escape")))
            except:
                LogUtil.info("  Payload : {}".format(data))

        if json_data:
            try:
                LogUtil.info("  Payload-json : {}".format(
                    json_data.__repr__().decode("unicode-escape")))
            except:
                LogUtil.info("  Payload-json : {}".format(json_data))

        request_obj = {}
        request_obj['url'] = url
        request_obj['method'] = method
        request_obj['headers'] = headers
        request_obj['cookies'] = cookies
        request_obj['parameters'] = params
        request_obj['payload'] = data
        return request_obj
예제 #25
0
    def merge_html(self, project_name, duration, merge_report_file_name, local=False):
        reports = {}
        index = 0
        head_list = []
        import os
        _re = project_name + '*html*'
        file_path = os.path.join(ROOT_DIR, "report", _re)
        for file in glob.glob(file_path):
            LogUtil.info(file)
            reports[index] = file
            index += 1

            d = pq(filename=file, parser='html')
            if not d:
                continue
            head_list.append(d('div').filter(".heading")('.attribute').text().split())

        start_time = min([head[2] for head in head_list]) + ' ' + min([head[3] for head in head_list])
        duration = duration
        total = sum([int(head[13]) for head in head_list])

        _pass = sum([int(head[17]) for head in head_list if head[15] == 'Pass'])
        # python 2.7 两个整数相除结果为整数,需要将至少一个转换为浮点数
        pass_rate = round(float(_pass) / total * 100, 2)
        failure = sum(int(head[head.index('Failure') + 2]) for head in head_list if 'Failure' in head)
        error = sum(int(head[head.index('Error') + 2]) for head in head_list if 'Error' in head)

        message = u"""
        <html>
            <head>
              <body>
                {0}
                <div>
                {1}
                </div>
              </body>
            </head>
        </html>"""

        head = u"""
                <div class='heading'>
                    <h1>{} API Automation Test Report</h1>
                    <p class='attribute'><strong>Start Time:</strong> {}</p>
                    <p class='attribute'><strong>Duration:</strong> {}min {}s</p>
                    <p class='attribute'><strong>Pass Rate:</strong> {} %</p>
                    <p class='attribute'><strong>Statistics:</strong> Total: {};  Pass: {};  Failure: {};   Error: {}; </p>
                    <p class='description'></p>
                </div>
                """.format(project_name.upper(), start_time, int(duration)/60, int(duration)%60, pass_rate, total, _pass, failure, error)

        insert = []
        for k, v in reports.items():
            if not local:
                v = v.split('/')[-1]
            insert.append('<iframe id={} class="contentView" '
                          'style="width: 100%;height: 400px;overflow: hidden;border: none;" '
                          'src="{}"></iframe>'.format(k,v))

        res = message.format(head, ''.join(insert))


        # # 生成合并后的文件名

        merge_full_path = os.path.join(ROOT_DIR, "report", merge_report_file_name)

        with open(merge_full_path, "w") as merge_file:
            merge_file.write(self.encode_utf8(res))

        return start_time, pass_rate, total, _pass, failure, error