示例#1
0
    def __init__(self, file_name, sheet_name, desired_caps={}, server_url=''):
        if desired_caps:
            self.desired_caps = desired_caps
        else:
            self.desired_caps = {
                'platformName': 'Desktop', 'browserName': 'Chrome'}
        self.server_url = server_url
        self.conditions = {}
        g.plan_name = file_name.split('-')[0]
        g.init(self.desired_caps, self.server_url)

        log_path = Path('snapshot') / g.plan_name / g.start_time[1:] 

        for p in ('JUnit', 'report', 'snapshot', log_path, 'report/' + g.plan_name):
            mkdir(p)
                  
        g.plan_data['log'] = set_log(logger, log_path)
        
        self.testcase_file = str(
            Path('testcase') / (file_name + '-' + _testcase + '.xlsx'))
        self.elements_file = str(
            Path('element') / (g.plan_name + '-' + _elements + '.xlsx'))
        self.report_xml = str(
            Path('JUnit') / (file_name + '-' + _report + g.start_time + '.xml'))
        self.testcase_workbook = Excel(self.testcase_file, 'r')
        self.sheet_names = self.testcase_workbook.get_sheet(sheet_name)
        self.report_excel = str(Path(
            'report') / g.plan_name / (file_name + '-' + _report + g.start_time + '.xlsx'))
        self.report_workbook = Excel(self.report_excel, 'w')

        self.report_data = {}  # 测试报告详细数据
示例#2
0
    def __init__(self, file_name, sheet_name, desired_caps={}, server_url=''):
        g.start_time = time.strftime("@%Y%m%d_%H%M%S", time.localtime())

        if desired_caps:
            self.desired_caps = desired_caps
        else:
            self.desired_caps = {
                'platformName': 'Desktop',
                'browserName': 'Chrome'
            }
        self.server_url = server_url

        self.conditions = {}

        for p in ('JUnit', 'report', 'snapshot'):
            mkdir(p)

        g.project_name = file_name.split('-')[0]
        self.testcase_file = Path('testcase') / (file_name + '-' + _testcase +
                                                 '.xlsx')
        self.elements_file = Path('element') / (g.project_name + '-' +
                                                _elements + '.xlsx')
        self.report_xml = Path('JUnit') / (file_name + '-' + _report +
                                           g.start_time + '.xml')
        self.testcase_workbook = Excel(self.testcase_file, 'r')
        self.sheet_names = self.testcase_workbook.get_sheet(sheet_name)

        self.report_workbook = Excel(
            Path('report') /
            (file_name + '-' + _report + g.start_time + '.xlsx'), 'w')

        self.report_data = {}  # 测试报告详细数据
示例#3
0
 def __init__(self):
     snapshot_plan = Path('snapshot') / g.plan_name
     self.snapshot_folder = snapshot_plan / g.start_time[1:]
     snapshot_expected = Path('snapshot') / 'expected'
     self.expected_folder = snapshot_expected / g.plan_name
     for p in (snapshot_plan, self.snapshot_folder, snapshot_expected, self.expected_folder):
         mkdir(p)
示例#4
0
def set_log(logger, log_path):
    mkdir('log')

    # 文件日志
    log_file = Path('log') / f'{today()}.log'
    file_handler = logging.FileHandler(filename=log_file, encoding="utf-8")
    file_handler.setFormatter(formatter)  # 可以通过setFormatter指定输出格式

    # 单次文件日志
    sweet_log = log_path / 'sweet.log'
    try:
        sweet_log.unlink()
    except:
        pass
    sweet_handler = logging.FileHandler(filename=sweet_log, encoding="utf-8")
    sweet_handler.setFormatter(formatter)  # 可以通过setFormatter指定输出格式

    # 控制台日志
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.formatter = formatter  # 也可以直接给formatter赋值

    # 为logger添加的日志处理器
    logger.addHandler(file_handler)
    logger.addHandler(sweet_handler)
    logger.addHandler(console_handler)

    # 指定日志的最低输出级别,默认为WARN级别
    # DEBUG,INFO,WARNING,ERROR,CRITICAL
    logger.setLevel(logging.INFO)

    return str(sweet_log)
示例#5
0
def set_log(logger):
    mkdir('log')
    # 文件日志
    log_file = Path('log') / f'{today()}.log'
    file_handler = logging.FileHandler(filename=log_file, encoding="utf-8")
    file_handler.setFormatter(formatter)  # 可以通过setFormatter指定输出格式

    # 控制台日志
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.formatter = formatter  # 也可以直接给formatter赋值

    # 为logger添加的日志处理器
    logger.addHandler(file_handler)
    logger.addHandler(console_handler)

    # 指定日志的最低输出级别,默认为WARN级别
    # DEBUG,INFO,WARNING,ERROR,CRITICAL
    logger.setLevel(logging.INFO)
示例#6
0
import sys
from sweetest.utility import mkdir


def today():
    now = datetime.datetime.now()
    return now.strftime('%Y%m%d')


# 获取logger实例,如果参数为空则返回root logger
logger = logging.getLogger("sweetest")

# 指定logger输出格式
formatter = logging.Formatter('%(asctime)s [%(levelname)s]: #  %(message)s')

mkdir('log')
# 文件日志
log_file = Path('log') / f'{today()}.log'
file_handler = logging.FileHandler(filename=log_file, encoding="utf-8")
file_handler.setFormatter(formatter)  # 可以通过setFormatter指定输出格式

# 控制台日志
console_handler = logging.StreamHandler(sys.stdout)
console_handler.formatter = formatter  # 也可以直接给formatter赋值

# 为logger添加的日志处理器
logger.addHandler(file_handler)
logger.addHandler(console_handler)

# 指定日志的最低输出级别,默认为WARN级别
# DEBUG,INFO,WARNING,ERROR,CRITICAL
示例#7
0
def markdown(plan, testsuites, testcases, md_path='markdown'):
    success = OK = '<font color=#00BB00>通过</font>'
    failure = NO = '<font color=#FF0000>失败</font>'
    blocked = '<font color=#FFD306>阻塞</font>'
    skipped = '<font color=#6C6C6C>-</font>'

    md = '| 测试套件名称 | 开始时间 | 结束时间 | 耗时 | 成功个数 | 失败个数 | 阻塞个数 | 总个数 | 结果 |\n'
    md += '| ----------- | ------- | ------- | ---- | ------- | ------- | -------- | ----- | ---- |\n'

    result = success
    sc, fc, bc, tc = 0, 0, 0, 0
    for v in testsuites.values():
        sc += v['success']
        fc += v['failure']
        bc += v['blocked']
        tc += v['total']
        re = success
        if v['result'] == 'failure':
            re = failure
        cost = round((v['end_timestamp'] - v['start_timestamp']) / 1000, 1)
        md += f'| {v["testsuite"]} | {tm(v["start_timestamp"])} | {tm(v["end_timestamp"])} | {cost} | '
        md += f'{v["success"]} | {v["failure"]} | {v["blocked"]} | {v["total"]} | {re} |\n'
        if v['result'] == 'failure':
            result = failure
    cost = round((plan['end_timestamp'] - plan['start_timestamp']) / 1000, 1)
    md += f'| **共计** | {tm(plan["start_timestamp"])} | {tm(plan["end_timestamp"])}  | {cost} | '
    md += f'{sc} | {fc} | {bc} | {tc} | {result} |\n'
    title = f'# 「{plan["plan"]}」自动化测试执行报告 {result} #\n\n[历史记录](/{plan["plan"]}/)\n\n'
    md = title + f'## 测试计划执行结果\n\n{md}\n\n## 测试套件执行结果\n\n'

    if result == success:
        icon = '✔️'
    else:
        icon = '❌'

    message = f'- {icon} <font color=#9D9D9D size=2>{tm(plan["start_timestamp"])} - {tm(plan["end_timestamp"])}</font> 测试计划'
    message += f'「[{plan["plan"]}]({plan["plan"]}/{plan["plan"]}_{tm(plan["start_timestamp"], "_")})」执行完成,测试结果:{result},成功:{sc},失败:{fc},阻塞:{bc}\n\n'

    # 测试套件 - 测试用例结果
    txt = ''
    for k, v in testcases.items():
        txt += f'\n- ### {k}\n\n'
        txt += '| 用例id  | 用例名称 |   前置条件   |开始时间         | 结束时间       | 耗时   | 结果    |\n'
        txt += '| ------- | ------- | ----------- | -------------- | -------------- | ----- | ------- |\n'
        for case in v:
            if case['flag'] == 'N':
                continue
            cost = round(
                (case['end_timestamp'] - case['start_timestamp']) / 1000, 1)
            result = eval(case['result'])
            txt += f'| [{case["id"]}](#{case["id"]}) | {case["title"]} | {case["condition"]} | {tm(case["start_timestamp"])} | {tm(case["end_timestamp"])} | {cost} | {result} |\n'

    md += f'{txt}\n\n## 测试用例执行结果\n'
    txt = ''
    for k, v in testcases.items():
        txt += f'\n- ### {k}\n'
        for case in v:
            if case['flag'] == 'N':
                continue
            txt += f'\n#### {case["id"]}\n\n**{case["title"]}** | {case["condition"]} | {case["designer"]} | {eval(case["result"])}\n\n'
            txt += '| 步骤  | 操作  | 页面  | 元素  | 测试数据  | 预期结果 | 输出数据  | 耗时 | 测试结果 | 备注 | 截图   |\n'
            txt += '|------|-------|-------|------|-----------|---------|-----------|-----|---------|------|--------|\n'
            for step in case['steps']:
                cost = round((step.get('end_timestamp', 0) -
                              step.get('start_timestamp', 0)) / 1000, 1)
                if cost == 0:
                    cost = '-'
                if not step['score']:
                    result = skipped
                else:
                    result = eval(step['score'])
                snapshot = ''
                if 'snapshot' in step:
                    for k, v in step['snapshot'].items():
                        snapshot += f"[{k}](/report/{v} ':ignore')\n"
                txt += f'| {step["no"]} | {step["keyword"]} | {step["page"]} | {escape(step["element"])} | {escape(step["data"])} | {escape(step["expected"])} | {escape(step["output"])} | {cost} | {result} | {step["remark"]} | {escape(snapshot, "%23")} |\n'
            result = eval(case['result'])
    md += txt

    p = Path(md_path) / 'report'
    latest = p / 'latest'
    report = p / g.plan_name
    mkdir(p)
    mkdir(report)

    with open(p / 'README.md', 'r', encoding='UTF-8') as f:
        txt = f.read()
        if '恭喜你安装成功' in txt:
            txt = ''
    with open(p / f'README.md', 'w', encoding='UTF-8') as f:
        f.write(message + txt)
    with open(latest / f'{g.plan_name}.md', 'w', encoding='UTF-8') as f:
        f.write(md)
    readme = report / 'README.md'
    if readme.is_file():
        with open(report / 'README.md', 'r', encoding='UTF-8') as f:
            txt = f.read()
    else:
        txt = ''
    with open(report / 'README.md', 'w', encoding='UTF-8') as f:
        f.write(message + txt)
    with open(report / f'{plan["plan"]}_{tm(plan["start_timestamp"], "_")}.md',
              'w',
              encoding='UTF-8') as f:
        f.write(md)
    with open(p / '_sidebar.md', 'r', encoding='UTF-8') as f:
        txt = f.read()
    if f'[{g.plan_name}]' not in txt:
        with open(p / '_sidebar.md', 'a', encoding='UTF-8') as f:
            f.write(f'\n	* [{g.plan_name}](latest/{g.plan_name})')

    files = []
    for f in report.iterdir():
        if f.stem not in ['_sidebar', 'README']:
            files.append(f.stem)
    files.sort(reverse=True)
    with open(report / '_sidebar.md', 'w', encoding='UTF-8') as f:
        txt = f'* 「{g.plan_name}」测试结果\n'
        for stem in files:
            txt += f'\n    * [{stem}]({g.plan_name}/{stem})'
        f.write(txt)
示例#8
0
 def __init__(self):
     self.plan_folder = 'snapshot/' + g.plan_name
     self.snapshot_folder = self.plan_folder + '/' + g.start_time[1:]
     self.expected_folder = 'snapshot/expected/' + g.plan_name
     for p in (self.plan_folder, self.snapshot_folder, self.expected_folder):
         mkdir(p)