Exemplo n.º 1
0
async def run(request):
    """
    run接口,get请求,把测试任务放入队列中
    :param request:
    :return:
    """
    system_name = request.match_info['name']
    case_path = os.path.join(cfg.getConfig('case_path'), system_name)
    record_path = os.path.join(case_path, cfg.getConfig('record_name'))
    build_file = os.path.join(cfg.getConfig('case_path'), system_name,
                              'build.xml')
    email_file = glob.glob(os.path.join(case_path, 'email_*.txt'))
    if os.path.exists(case_path):
        if len(email_file) == 0:
            return web.Response(body=json.dumps(
                {
                    'code': 0,
                    'message': '没有设置收件人邮箱地址的txt文件,测试任务执行失败',
                    'data': None
                },
                ensure_ascii=False))
        elif len(email_file) > 1:
            return web.Response(body=json.dumps(
                {
                    'code': 0,
                    'message': '应该只有一个收件人邮箱地址的txt文件,但是找到了多个,测试任务执行失败',
                    'data': None
                },
                ensure_ascii=False))

        if not os.path.exists(record_path):
            f = open(record_path, 'a')
            f.close()

        if os.path.exists(build_file):
            schedule.task = [case_path, email_file[0]]
            return web.Response(body=json.dumps(
                {
                    'code': 1,
                    'message': '操作成功,测试任务正在准备执行',
                    'data': None
                },
                ensure_ascii=False))
        else:
            return web.Response(body=json.dumps(
                {
                    'code': 0,
                    'message': 'build.xml文件不存在,测试任务执行失败',
                    'data': None
                },
                ensure_ascii=False))
    else:
        return web.Response(body=json.dumps(
            {
                'code': 0,
                'message': '未找到与系统名称对应的脚本,请确认系统名称是否正确,脚本是否存在!',
                'data': None
            },
            ensure_ascii=False))
Exemplo n.º 2
0
    def run(self, case_email_path):
        """
        执行测试任务
        :param case_email_path: 列表,第一个元素是测试用例文件路径,第二个元素是收件人的txt文件路径
        :return:
        """
        if int(cfg.getConfig('is_git')):
            logger.info('准备从git上拉取最新版本')
            repo = Repo(cfg.getConfig('git_path'))
            remote = repo.remote()
            remote.pull()
            logger.info('从git上拉取版本成功')

        file_name = None
        case_path = case_email_path[0]
        email_path = case_email_path[1]
        build_path = os.path.join(case_path, 'build.xml')
        logger.info(f'开始执行测试任务{build_path}')

        start_time = time.strftime('%Y-%m-%d %H:%M:%S')
        res = os.popen(
            'ant -f {}'.format(build_path)).readlines()  # 执行测试,并等待测试完成
        for i in range(len(res)):
            if 'Build failed' in res[i]:  # 如果有失败日志,打印出
                logger.error('{}\n{}'.format(res[i - 1], res[i]))
                break
            if 'xslt' in res[i] and 'Processing' in res[i] and 'to' in res[
                    i]:  # 获取测试报告文件名
                line = res[i].strip()
                logger.debug(line)
                if '/' in line:
                    file_name = line.split('/')[-1]
                else:
                    file_name = line.split('\\')[-1]
                logger.info(file_name)
                break

        if file_name:
            logger.info('测试任务执行完成')
            time.sleep(2)
            msg = self.parse_html(file_name, case_path)  # 重组html

            sendMsg(msg['fail_case'], email_path)  # 发送邮件

            string = f"{start_time},{build_path},{msg['total_num']},{msg['failure_num']}\n"
            self.lock.acquire()
            logger.info(f'写测试记录到本地, {string}')
            with open(os.path.join(case_path, cfg.getConfig('record_name')),
                      'a',
                      encoding='utf-8') as f:
                f.write(string)
            self.lock.release()
            logger.info('测试完成')
        else:
            logger.error('测试任务执行失败')
Exemplo n.º 3
0
    def __init__(self):
        self.testing = Testing()
        self.thread_pool_size = max(1, int(cfg.getConfig('thread_pool')))
        self.test_task = queue.Queue()  # 创建队列
        self.executor = ThreadPoolExecutor(self.thread_pool_size)  # 创建线程池

        self.run()
Exemplo n.º 4
0
    def lookup(self):
        while True:
            time.sleep(2)
            n = len(self.tasking)
            logger.info(f'当前正在执行的任务数为{n}')
            inds = []
            for i in range(n):
                html_path = os.path.join(
                    cfg.getConfig('report_path'),
                    self.tasking[i]["file_name"]) + '.html'
                logger.info(html_path)
                if not os.path.exists(html_path):
                    if time.time(
                    ) - self.tasking[i]["start_time"] < self.interval:
                        continue
                    else:
                        logger.error(f'测试任务执行超时')
                        inds.append(i)
                        html = f'<html><body>' \
                               f'<h3>异常提醒:{self.tasking[i]["build_file"]} 测试任务执行超时,请检查!</h3>' \
                               f'<p style="color:blue;">此邮件自动发出,请勿回复。</p></body></html>'
                        try:
                            sendMsg(html, self.tasking[i], is_path=False)
                        except Exception as err:
                            logger.error(err)
                else:
                    time.sleep(1)
                    logger.info('测试任务执行完成')
                    flag = self.post_deal(self.tasking[i])
                    if flag:
                        inds.append(i)

            for j in range(len(inds) - 1, -1, -1):
                self.tasking.pop(inds[j])
Exemplo n.º 5
0
async def sendEmail(request):
    """
    get请求,用于发送邮件,用于客户端异常时发送邮件提醒
    :param request:
    :return:
    """
    name = request.match_info['name']
    port = request.match_info['port']
    ind = request.match_info['ind']
    IP = request.match_info['IP']
    email_file = glob.glob(
        os.path.join(cfg.getConfig('case_path'), name, 'email_*.txt'))
    if len(email_file) == 0:
        return web.Response(body=json.dumps(
            {
                'code': 0,
                'message': '没有设置收件人邮箱地址的txt文件,测试任务执行失败',
                'data': None
            },
            ensure_ascii=False))
    elif len(email_file) > 1:
        return web.Response(body=json.dumps(
            {
                'code': 0,
                'message': '应该只有一个收件人邮箱地址的txt文件,但是找到了多个,测试任务执行失败',
                'data': None
            },
            ensure_ascii=False))

    if int(ind) == 1:
        msg = f'{IP} 服务器上的 {port} 端口已经停了,无法执行 {name} 的接口自动化测试,请及时检查端口状态'
    else:
        msg = f'{IP} 服务器上的 {name} 接口自动化测试执行异常,请检查测试用例,或手动执行get请求 http://{IP}:{PORT}/run?systemName={name} '
    html = f'<html><body>' \
           f'<h3>异常提醒:{msg}!</h3>' \
           f'<p style="color:blue;">此邮件自动发出,请勿回复。</p></body></html>'
    try:
        sendMsg(html, email_file[0], is_path=False)
        return web.Response(
            body=json.dumps({
                'code': 1,
                'message': '邮件提醒发送成功!',
                'data': None
            },
                            ensure_ascii=False))
    except Exception as err:
        return web.Response(body=json.dumps(
            {
                'code': 0,
                'message': err,
                'data': None
            }, ensure_ascii=False))
Exemplo n.º 6
0
    def run(self, paths):
        """
        执行测试任务
        :param paths: 字典
        :return:
        """
        try:
            if int(cfg.getConfig('is_git')):
                logger.info('准备从git上拉取最新版本')
                repo = Repo(cfg.getConfig('git_path'))
                remote = repo.remote()
                remote.pull()
                logger.info('从git上拉取版本成功')
        except Exception as err:
            logger.error(err)

        build_path = paths["build_file"]
        logger.info(f'开始执行测试任务{build_path}')

        try:
            if paths["method"] == "GET":
                shutil.copy(paths["config_file"],
                            paths["new_config_file"])  # 复制,用于jmx执行
            else:
                if paths["post_data"].get('params'):
                    replace_config(paths["config_file"],
                                   paths["post_data"]['params'],
                                   paths["new_config_file"])

            report_name = f'{paths["system_name"]}-{int(time.time() * 1000)}'
            _ = os.popen('nohup ant -f {} -DReportName={} &'.format(
                build_path, report_name))  # 执行测试
            paths.update({"file_name": report_name})
            paths.update({"start_time": time.time()})
            self.tasking.append(paths)
            time.sleep(3)
        except Exception as err:
            logger.error(err)
Exemplo n.º 7
0
async def get_list(request):
    """
    获取当前测试用例目录下的系统名,及执行测试任务需要的get请求的url
    """
    case_path = cfg.getConfig('case_path')
    max_num = 0
    for i in os.listdir(case_path):
        if max_num < len(i):
            max_num = len(i)
    dirs = [
        d + ' ' * (max_num - len(d)) + '\t\t' + 'http://' + IP + ':' + PORT +
        '/run?systemName=' + d for d in os.listdir(case_path)
        if os.path.isdir(os.path.join(case_path, d))
    ]
    return web.Response(body='\n'.join(dirs))
Exemplo n.º 8
0
async def sendEmail(request):
    """
    get请求,用于发送邮件,用于客户端异常时发送邮件提醒
    :param request:
    :return:
    """
    name = request.match_info['name']
    port = request.match_info['port']
    email_file = glob.glob(
        os.path.join(cfg.getConfig('case_path'), name, 'email_*.txt'))
    if len(email_file) == 0:
        return web.Response(body=json.dumps(
            {
                'code': 0,
                'message': '没有设置收件人邮箱地址的txt文件,测试任务执行失败',
                'data': None
            },
            ensure_ascii=False))
    elif len(email_file) > 1:
        return web.Response(body=json.dumps(
            {
                'code': 0,
                'message': '应该只有一个收件人邮箱地址的txt文件,但是找到了多个,测试任务执行失败',
                'data': None
            },
            ensure_ascii=False))

    html = f'<html><body>' \
           f'<h3>异常提醒:{name}的接口自动化测试环境对应的{port}端口已经停了,请及时重启或更换端口!</h3>' \
           f'<p style="color:blue;">此邮件自动发出,请勿回复。</p></body></html>'
    try:
        sendMsg(html, email_file[0], is_path=False)
        return web.Response(
            body=json.dumps({
                'code': 1,
                'message': '邮件提醒发送成功',
                'data': None
            },
                            ensure_ascii=False))
    except Exception as err:
        return web.Response(body=json.dumps(
            {
                'code': 0,
                'message': err,
                'data': None
            }, ensure_ascii=False))
Exemplo n.º 9
0
def sendMsg(html, receiver_email, is_path=True, is_send=True):
    """
    发送邮件
    :param html: 邮件正文用到的html文件路径,或者html
    :param receiver_email: 收件人邮箱地址的txt文件路径
    :param is_path: bool,True表示html是一个路径,False表示html是html
    :param is_send: bool,是否发邮件,仅用于第一次发送失败后,再次发送
    :return:
    """
    if int(cfg.getConfig('is_email')):
        try:
            receive_name = re.findall('email_(.*?).txt', receiver_email)[0]     # 提取收件人姓名
            with open(receiver_email, 'r', encoding='utf-8') as f:
                sends = f.readlines()
            subject = sends[0]
            send_to = sends[1]
            logger.info('开始发送邮件,收件人{}'.format(send_to))
            message = MIMEMultipart()
            message['From'] = Header(cfg.getConfig('sender_name'))      # 发件人名字
            message['To'] = Header(receive_name)    # 收件人名字
            message['Subject'] = Header(subject, 'utf-8')   # 邮件主题

            if is_path:
                with open(html, 'r', encoding='utf-8') as f:
                    fail_case = f.read()
            else:
                fail_case = html

            email_text = MIMEText(fail_case, 'html', 'utf-8')
            message.attach(email_text)  # 添加邮件正文

            try:
                server = smtplib.SMTP_SSL(cfg.getConfig('smtp'), 465)
                # server.connect(cfg.getConfig('smtp'))
            except Exception as err:
                logger.error(err)
                server = smtplib.SMTP(cfg.getConfig('smtp'), 25)
                # server.connect(cfg.getConfig('smtp'))

            server.login(cfg.getConfig('sender_email'), '123456')  # 登陆邮箱
            server.sendmail(cfg.getConfig('sender_email'), send_to.split(','), message.as_string())  # 发送邮件
            server.quit()
            del email_text
            del message
            logger.info('邮件发送成功')
        except Exception as err:
            logger.error(err)
            if is_send:
                sendMsg(html, receiver_email, is_path=is_path, is_send=False)

    else:
        logger.info('设置为不自动发送邮件,已跳过。')
Exemplo n.º 10
0
async def run(request):
    """
    run接口,把测试任务放入队列中
    :param request:
    :return:
    """
    if request.method == 'GET':
        paths = {"method": "GET"}
        system_name = request.query.get('systemName')  # 待执行测试的系统根路径
        case_path = os.path.join(cfg.getConfig('case_path'),
                                 system_name)  # 测试用例路径
        paths.update({"system_name": system_name})
        paths.update({"case_path": case_path})  # 测试用例路径
        paths.update({
            "record_path":
            os.path.join(case_path, cfg.getConfig('record_name'))
        })  # 测试结果记录路径
        paths.update({
            "build_file":
            os.path.join(cfg.getConfig('case_path'), system_name, 'build.xml')
        })  # build.xml路径
        paths.update(
            {"email_file": os.path.join(case_path,
                                        'email_default.txt')})  # 邮件默认配置文件
        paths.update({
            "config_file":
            os.path.join(case_path, 'config_default.txt')
        })  # jmx执行的配置文件对应的默认配置文件
        paths.update({"new_email_file": os.path.join(case_path,
                                                     'email.txt')})  # 邮件配置文件
        paths.update(
            {"new_config_file": os.path.join(case_path,
                                             'config.txt')})  # jmx执行的配置文件
        if os.path.exists(case_path):
            if not os.path.exists(paths["record_path"]):
                f = open(paths["record_path"], 'a')
                f.close()

            if os.path.exists(paths["build_file"]):
                schedule.task = paths
                return web.Response(body=json.dumps(
                    {
                        'code': 1,
                        'message': '操作成功,测试任务正在准备执行',
                        'data': None
                    },
                    ensure_ascii=False))
            else:
                return web.Response(body=json.dumps(
                    {
                        'code': 0,
                        'message': 'build.xml文件不存在,测试任务执行失败',
                        'data': None
                    },
                    ensure_ascii=False))
        else:
            return web.Response(body=json.dumps(
                {
                    'code': 0,
                    'message': '未找到与系统名称对应的脚本,请确认系统名称是否正确,脚本是否存在!',
                    'data': None
                },
                ensure_ascii=False))
    else:
        post_data = await request.json()
        paths = {"method": "POST"}
        system_name = request.query.get('systemName')  # 待执行测试的系统根路径
        case_path = os.path.join(cfg.getConfig('case_path'),
                                 system_name)  # 测试用例路径
        paths.update({"system_name": system_name})
        paths.update({"case_path": case_path})  # 测试用例路径
        paths.update({
            "record_path":
            os.path.join(case_path, cfg.getConfig('record_name'))
        })  # 测试结果记录路径
        paths.update({
            "build_file":
            os.path.join(cfg.getConfig('case_path'), system_name, 'build.xml')
        })  # build.xml路径
        paths.update(
            {"email_file": os.path.join(case_path,
                                        'email_default.txt')})  # 邮件默认配置文件
        paths.update({
            "config_file":
            os.path.join(case_path, 'config_default.txt')
        })  # jmx执行的配置文件对应的默认配置文件
        paths.update({"new_email_file": os.path.join(case_path,
                                                     'email.txt')})  # 邮件配置文件
        paths.update(
            {"new_config_file": os.path.join(case_path,
                                             'config.txt')})  # jmx执行的配置文件
        paths.update({"post_data": post_data})

        if os.path.exists(case_path):
            if not os.path.exists(paths["record_path"]):
                f = open(paths["record_path"], 'a')
                f.close()

            if os.path.exists(paths["build_file"]):
                schedule.task = paths
                return web.Response(body=json.dumps(
                    {
                        'code': 1,
                        'message': '操作成功,测试任务正在准备执行',
                        'data': None
                    },
                    ensure_ascii=False))
            else:
                return web.Response(body=json.dumps(
                    {
                        'code': 0,
                        'message': 'build.xml文件不存在,测试任务执行失败',
                        'data': None
                    },
                    ensure_ascii=False))
        else:
            return web.Response(body=json.dumps(
                {
                    'code': 0,
                    'message': '未找到与系统名称对应的脚本,请确认系统名称是否正确,脚本是否存在!',
                    'data': None
                },
                ensure_ascii=False))
Exemplo n.º 11
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: leeyoshinari
import os
import glob
import json
import asyncio
from aiohttp import web
from schedule import Scheduler
from sendEmail import sendMsg
from logger import logger, cfg

schedule = Scheduler()
report_path = cfg.getConfig('report_path')
IP = cfg.getConfig('host')
PORT = cfg.getConfig('port')
if not os.path.exists(report_path):
    os.mkdir(report_path)


async def get_list(request):
    """
    获取当前测试用例目录下的系统名,及执行测试任务需要的get请求的url
    """
    case_path = cfg.getConfig('case_path')
    max_num = 0
    for i in os.listdir(case_path):
        if max_num < len(i):
            max_num = len(i)
    dirs = [
        d + ' ' * (max_num - len(d)) + '\t\t' + 'http://' + IP + ':' + PORT +
Exemplo n.º 12
0
async def run(request):
    """
    run接口,把测试任务放入队列中
    :param request:
    :return:
    """
    if request.method == 'GET':
        system_name = request.query.get('systemName')  # 待执行测试的系统根路径
        case_path = os.path.join(cfg.getConfig('case_path'),
                                 system_name)  # 测试用例路径
        record_path = os.path.join(case_path,
                                   cfg.getConfig('record_name'))  # 测试结果记录路径
        build_file = os.path.join(cfg.getConfig('case_path'), system_name,
                                  'build.xml')  # build.xml路径
        email_file = os.path.join(case_path, 'email_default.txt')  # 邮件默认配置文件
        config_file = os.path.join(case_path,
                                   'config_default.txt')  # jmx执行的配置文件对应的默认配置文件
        new_email_file = os.path.join(case_path, 'email.txt')  # 邮件配置文件
        new_config_file = os.path.join(case_path, 'config.txt')  # jmx执行的配置文件
        if os.path.exists(case_path):
            shutil.copy(email_file, new_email_file)  # 复制,用于发送邮件
            shutil.copy(config_file, new_config_file)  # 复制,用于jmx执行

            if not os.path.exists(record_path):
                f = open(record_path, 'a')
                f.close()

            if os.path.exists(build_file):
                schedule.task = [case_path, new_email_file]
                return web.Response(body=json.dumps(
                    {
                        'code': 1,
                        'message': '操作成功,测试任务正在准备执行',
                        'data': None
                    },
                    ensure_ascii=False))
            else:
                return web.Response(body=json.dumps(
                    {
                        'code': 0,
                        'message': 'build.xml文件不存在,测试任务执行失败',
                        'data': None
                    },
                    ensure_ascii=False))
        else:
            return web.Response(body=json.dumps(
                {
                    'code': 0,
                    'message': '未找到与系统名称对应的脚本,请确认系统名称是否正确,脚本是否存在!',
                    'data': None
                },
                ensure_ascii=False))
    else:
        post_data = await request.json()
        system_name = request.query.get('systemName')  # 待执行测试的系统根路径
        case_path = os.path.join(cfg.getConfig('case_path'),
                                 system_name)  # 测试用例路径
        record_path = os.path.join(case_path,
                                   cfg.getConfig('record_name'))  # 测试结果记录路径
        build_file = os.path.join(cfg.getConfig('case_path'), system_name,
                                  'build.xml')  # build.xml路径
        email_file = os.path.join(case_path, 'email_default.txt')  # 邮件默认配置文件
        config_file = os.path.join(case_path,
                                   'config_default.txt')  # jmx执行的配置文件对应的默认配置文件
        new_email_file = os.path.join(case_path, 'email.txt')  # 邮件配置文件
        new_config_file = os.path.join(case_path, 'config.txt')  # jmx执行的配置文件

        if os.path.exists(case_path):
            if not os.path.exists(record_path):
                f = open(record_path, 'a')
                f.close()

            if post_data.get('email'):
                replace_email(email_file, post_data['email'], new_email_file)

            if post_data.get('params'):
                replace_config(config_file, post_data['params'],
                               new_config_file)

            if os.path.exists(build_file):
                schedule.task = [case_path, new_email_file]
                return web.Response(body=json.dumps(
                    {
                        'code': 1,
                        'message': '操作成功,测试任务正在准备执行',
                        'data': None
                    },
                    ensure_ascii=False))
            else:
                return web.Response(body=json.dumps(
                    {
                        'code': 0,
                        'message': 'build.xml文件不存在,测试任务执行失败',
                        'data': None
                    },
                    ensure_ascii=False))
        else:
            return web.Response(body=json.dumps(
                {
                    'code': 0,
                    'message': '未找到与系统名称对应的脚本,请确认系统名称是否正确,脚本是否存在!',
                    'data': None
                },
                ensure_ascii=False))
Exemplo n.º 13
0
def sendMsg(html, paths, failure_num=1, is_path=True, is_send=True):
    """
    发送邮件
    :param html: 邮件正文用到的html文件路径,或者html
    :param paths:
    :param failure_num: 失败的用例数
    :param is_path: bool,True表示html是一个路径,False表示html是html
    :param is_send: bool,是否发邮件,仅用于第一次发送失败后,再次发送
    :return: 
    """
    flag = 0
    is_email = int(cfg.getConfig('is_email'))
    if is_email:
        if is_email == 1:
            flag = 1
        if is_email == 2:
            if failure_num > 0:
                flag = 1
            else:
                logger.info('所有用例执行成功,不发送邮件,已跳过。')
        if is_email == 3:
            if failure_num == 0:
                flag = 1
            else:
                logger.info('有执行失败的用例,不发送邮件,已跳过。')
    else:
        logger.info('设置为不自动发送邮件,已跳过。')

    if flag:
        try:
            if paths["method"] == "GET":
                shutil.copy(paths["email_file"], paths["new_email_file"])
            else:
                if paths["post_data"].get('email'):
                    replace_email(paths["email_file"], paths["post_data"]['email'], paths["new_email_file"])

            email_dict = json.load(open(paths["new_email_file"], 'r', encoding='utf-8'))
            subject = email_dict['subject']
            send_to = email_dict['receiveEmail']
            receive_name = email_dict['receiveName']
            logger.info('开始发送邮件,收件人{}'.format(send_to))
            message = MIMEMultipart()
            message['From'] = Header(cfg.getConfig('sender_name'))      # 发件人名字
            message['To'] = Header(receive_name)    # 收件人名字
            message['Subject'] = Header(subject, 'utf-8')   # 邮件主题

            if is_path:
                with open(html, 'r', encoding='utf-8') as f:
                    fail_case = f.read()
            else:
                fail_case = html

            email_text = MIMEText(fail_case, 'html', 'utf-8')
            message.attach(email_text)  # 添加邮件正文

            try:
                server = smtplib.SMTP_SSL(cfg.getConfig('smtp'), 465)
            except Exception as err:
                logger.error(err)
                server = smtplib.SMTP(cfg.getConfig('smtp'), 25)

            server.login(cfg.getConfig('sender_email'), '123456')  # 登陆邮箱
            server.sendmail(cfg.getConfig('sender_email'), send_to.split(','), message.as_string())  # 发送邮件
            server.quit()
            del fail_case, email_text, message, server
            logger.info('邮件发送成功')
        except Exception as err:
            logger.error(err)
            if is_send:
                sendMsg(html, paths, is_path=is_path, is_send=False)   # 发送失败后,重发一次
Exemplo n.º 14
0
    def parse_html(self, file_name, case_path):
        """
        提取自动生成的测试报告中的一些信息,重组测试报告用于邮件发送
        :param case_path: 测试用例路径
        :param file_name: 测试报告名称
        :return:
        """
        try:
            all_case = os.path.join(cfg.getConfig('report_path'),
                                    file_name)  # 完整的测试报告路径
            fail_case = os.path.join(cfg.getConfig('report_path'),
                                     'send_' + file_name)  # 处理好用于邮件发送的测试报告路径
            logger.info('开始处理html测试报告{}'.format(all_case))
            with open(all_case, 'r', encoding='utf-8') as f:
                htmls = f.readlines()

            html = ''
            for line in htmls:
                html += line.strip()

            # 提取用例总数,成功率数据
            case_num = re.findall(
                '响应时间最大值</th>.*<td align="center">(\d+)</td><td align="center">(\d+)</td>'
                '<td align="center">\d{1,3}.\d+%', html)[0]
            total_num = [int(case_num[0])]
            failure_num = [int(case_num[1])]

            # 提取出概览和失败用例,用于邮件发送
            # res = re.findall('(.*?)<h2>所有用例', html)[0]
            res = html.split('<h2>所有用例')[0]
            url = 'http://{}:{}/testReport/{}'.format(cfg.getConfig('host'),
                                                      cfg.getConfig('port'),
                                                      file_name)
            logger.info(f'详细测试报告跳转链接为 {url}')
            # 添加完整测试报告路径跳转链接
            jump_url = f'<span style="font-size: 125%; margin-left: 2.5%;">如需查看详细测试结果,<a href="{url}">请点我</a></span>'

            # 添加历史数据
            self.lock.acquire()
            with open(os.path.join(case_path, cfg.getConfig('record_name')),
                      'r',
                      encoding='utf-8') as f:
                history = f.readlines()
            self.lock.release()
            for line in history:
                datas = line.split(',')
                total_num.append(int(datas[-2]))
                failure_num.append(int(datas[-1]))
            ratio = 100 - round(100 * sum(failure_num) / sum(total_num), 2)
            history = f'<hr align="center" width="95%" size="1"><h2>历史数据概览</h2><table width="95%" cellspacing="2" ' \
                      f'cellpadding="5" border="0" class="details" align="center"><tbody><tr valign="top"><th>累计执行次数' \
                      f'</th><th>累计执行用例数</th><th>累计执行失败用例数</th><th>执行成功率</th></tr><tr valign="top" ' \
                      f'style="font-weight: bold;"><td align="center">{len(total_num)}</td><td align="center">{sum(total_num)}</td>' \
                      f'<td align="center">{sum(failure_num)}</td><td align="center">{ratio}%</td></tr></tbody></table>'

            res1 = re.sub('<span>(.*?)</span>', jump_url + history, res)
            # 添加尾巴
            res = res1 + '<p style="color:blue;font-size: 125%;">此邮件自动发出,请勿回复。</p></body></html>'
            # 写到本地
            with open(fail_case, 'w', encoding='utf-8') as f:
                f.writelines(res)

            logger.info('html测试报告处理完成')
            return {
                'all_case': all_case,
                'fail_case': fail_case,
                'total_num': total_num[0],
                'failure_num': failure_num[0]
            }
        except Exception as err:
            logger.error(err)
Exemplo n.º 15
0
    def __init__(self):
        self.interval = int(cfg.getConfig('interval'))
        self.tasking = []

        t = Thread(target=self.lookup)
        t.start()
Exemplo n.º 16
0
    def run(self, case_email_path):
        """
        执行测试任务
        :param case_email_path: 列表,第一个元素是测试用例文件路径,第二个元素是收件人的txt文件路径
        :return:
        """
        try:
            if int(cfg.getConfig('is_git')):
                logger.info('准备从git上拉取最新版本')
                repo = Repo(cfg.getConfig('git_path'))
                remote = repo.remote()
                remote.pull()
                logger.info('从git上拉取版本成功')
        except Exception as err:
            logger.error(err)

        file_name = None
        error_msg = None
        case_path = case_email_path[0]
        email_path = case_email_path[1]
        build_path = os.path.join(case_path, 'build.xml')
        logger.info(f'开始执行测试任务{build_path}')

        try:
            start_time = time.strftime('%Y-%m-%d %H:%M:%S')
            res = os.popen(
                'ant -f {}'.format(build_path)).readlines()  # 执行测试,并等待测试完成
            logger.debug(res)
            length = len(res)
            for i in range(length, -1, -1):
                if 'Failed' in res[i]:  # 如果有失败日志,打印出
                    error_msg = '{}\n{}'.format(res[i], res[i - 1])
                    logger.error(error_msg)
                    break
                if 'xslt' in res[i] and 'Processing' in res[i] and 'to' in res[
                        i]:  # 获取测试报告文件名
                    line = res[i].strip()
                    logger.debug(line)
                    if '/' in line:
                        file_name = line.split('/')[-1]
                    else:
                        file_name = line.split('\\')[-1]
                    logger.info(file_name)
                    break

            del res
            if file_name:
                logger.info('测试任务执行完成')
                time.sleep(2)
                msg = self.parse_html(file_name, case_path)  # 重组html

                sendMsg(msg['fail_case'],
                        email_path,
                        failure_num=msg['failure_num'])  # 发送邮件

                string = f"{start_time},{build_path},{msg['total_num']},{msg['failure_num']}\n"
                self.lock.acquire()
                logger.info(f'写测试记录到本地, {string}')
                with open(os.path.join(case_path,
                                       cfg.getConfig('record_name')),
                          'a',
                          encoding='utf-8') as f:
                    f.write(string)
                self.lock.release()
                logger.info('测试完成')
            else:
                error_msg = 'html格式的测试报告未找到'
        except Exception as err:
            error_msg = err
            logger.error(err)

        if error_msg:
            logger.error(f'测试任务执行失败,失败信息:{error_msg}')
            html = f'<html><body>' \
                   f'<h3>异常提醒:{build_path} 测试任务执行失败,请重新执行! 失败信息:{error_msg}</h3>' \
                   f'<p style="color:blue;">此邮件自动发出,请勿回复。</p></body></html>'
            try:
                sendMsg(html, email_path, is_path=False)
            except Exception as err:
                logger.error(err)