diff --git a/apiM/module.py b/apiM/module.py index be1a174e96e2be2e44b62e4bca4639267aaeb6ad..2036ecdf5173be2286b65e1f2d0845812ec06f56 100644 --- a/apiM/module.py +++ b/apiM/module.py @@ -28,6 +28,12 @@ class Module: self.session = session self.base_ip = base_ip self.mysql = mysql + self.cookies = None + self.code = None + self.result_text = None + self.result_content = None + RunConfig.API_RESULT_CODE = None + RunConfig.API_RESULT = None def send(self): global _res @@ -49,19 +55,18 @@ class Module: headers=va('headers') ) logger.info(f"{va('method')}:{va('scheme') + '://' + va('ip') + ':' + str(va('port')) + va('path')}") + self.cookies = _res.cookies + self.code = _res.status_code + self.result_text = _res.text + self.result_content = _res.content + RunConfig.API_RESULT_CODE = self.code + try: + RunConfig.API_RESULT = self.result_json() + except Exception: + RunConfig.API_RESULT = self.result_text except Exception as e: logger.error(f"{va('method')}:{va('scheme') + '://' + va('ip') + ':' + str(va('port')) + va('path')}" f"--请求失败--{e}") - # global cookies, code, result_text, result_json, result_content - self.cookies = _res.cookies - self.code = _res.status_code - self.result_text = _res.text - self.result_content = _res.content - RunConfig.API_RESULT_CODE = self.code - try: - RunConfig.API_RESULT = self.result_json() - except Exception: - RunConfig.API_RESULT = self.result_text def result_json(self): diff --git a/config.py b/config.py index b5cd42823e84f694a77f355fb6a951afaf1d407b..d95de9659fd29b322a656193cac3f90646308617 100644 --- a/config.py +++ b/config.py @@ -1,4 +1,5 @@ import os + PRO_PATH = os.path.dirname(os.path.abspath(__file__)) @@ -9,6 +10,7 @@ class RunConfig: # 运行测试用例的目录或文件 UI_cases_path = os.path.join(PRO_PATH, "test_dir/test_UI", "test_baidu.py") API_cases_path = os.path.join(PRO_PATH, "test_dir/test_API", "test_api_baidu.py") + APP_cases_path = os.path.join(PRO_PATH, "test_dir/test_APP", "test_wx.py") # 配置浏览器驱动类型(chrome/firefox/chrome-headless/firefox-headless)。 driver_type = "chrome" @@ -25,12 +27,16 @@ class RunConfig: # 浏览器驱动(不需要修改) driver = None + # app 驱动(不需要修改) + app_driver = None + # 报告路径(不需要修改) NEW_REPORT = None # 项目日志配置 UI_LOG_DIR = PRO_PATH + "/logs/UI/" API_LOG_DIR = PRO_PATH + "/logs/API/" + APP_LOG_DIR = PRO_PATH + "/logs/APP/" # 邮件发件人(邮箱配置地址::邮箱::密码) SEND_USER = '' @@ -61,6 +67,26 @@ class RunConfig: 'password': '123456', 'database': 'test', } + # app name + app_name = '' + # appium启动配置 + desired_caps = { + 'platformName': 'Android', # 设备类型; + 'platformVersion': '7', # 设备的类型的版本号,如果是安卓,填写大的版本号即可,小数不用填; + 'deviceName': 'MI9', # 设备的名称,这个和后续的测试没有多大关系; + 'appPackage': 'com.tencent.mm', # 需要测试的app包名; + 'appActivity': 'com.tencent.mm.ui.LauncherUI', # 需要测试的app启动名; + # 'unicodeKeyboard': True, # 如果指定了UI2作为驱动,不需要配置; + # 'resetKeyboard': True, # 重置自动化时设置的键盘; + # 'chromedriverExecutableDir': '路径', # 启动webview的webdriver驱动 + 'noReset': True, # 防止每次启动app时候都初始化所有数据; + # 'newCommandTimeout': 6000, # 代码向appiumserver发送命令的延迟时间,单位是秒,不设置默认一分钟; + # 'automationName': 'uiautomator2', # 这个并不是所有应用都适配的,1.15.1以前默认是UI1,之后是默认UI2;IOS: XCUITest;也可直接使用appium + 'autoGrantPermissions': True, # 自动跳过授权 + 'skipServerInstallation': True, + 'skipDeviceInitialization': True, # 跳过安装AppiumSetting,初次测试请改为False。 + } + if __name__ == '__main__': - pass \ No newline at end of file + print(RunConfig.API_cases_path) diff --git a/conftest.py b/conftest.py index 843d3933357d782d955dfb6bb2e9f9917ed6ba89..8ebe3e535b39bf521855f6055793e3948a883b81 100644 --- a/conftest.py +++ b/conftest.py @@ -1,12 +1,15 @@ import os +import sys import time -import pymysql +import appium.version +import psutil import requests import pytest from py.xml import html from selenium import webdriver from selenium.webdriver import Remote +from appium import webdriver as app_webdriver from selenium.webdriver.chrome.options import Options as CH_Options from selenium.webdriver.firefox.options import Options as FF_Options from selenium.webdriver.chrome.service import Service as ChromeService @@ -21,23 +24,26 @@ from database import MySql BASE_DIR = os.path.dirname(os.path.abspath(__file__)) UI_REPORT_DIR = BASE_DIR + "/test_report/UI/" API_REPORT_DIR = BASE_DIR + "/test_report/API/" +APP_REPORT_DIR = BASE_DIR + "/test_report/APP/" # 设置报告的标题 def pytest_html_report_title(report): if RunConfig.RUN == None or RunConfig.RUN.lower() == 'ui': - report.title = "UI自动化测试报告" + report.title = "WEB UI自动化测试报告" + elif RunConfig.RUN.lower() == 'api': + report.title = "接口自动化测试报告" else: - report.title = "API自动化测试报告" + report.title = 'APP自动化测试报告' # 设置用例描述表头 def pytest_html_results_table_header(cells): cells.insert(2, html.th('用例描述')) # cells.insert(2, html.th('Description')) - if RunConfig.RUN == None or RunConfig.RUN.lower() == 'ui': + if RunConfig.RUN == None or RunConfig.RUN.lower() == 'ui' or RunConfig.RUN.lower() == 'app': pass - else: + elif RunConfig.RUN.lower() == 'api': cells.insert(3, html.th('响应状态码')) cells.insert(4, html.th('响应内容')) cells.pop() @@ -46,9 +52,9 @@ def pytest_html_results_table_header(cells): # 设置用例描述表格 def pytest_html_results_table_row(report, cells): cells.insert(2, html.td(report.description)) - if RunConfig.RUN == None or RunConfig.RUN.lower() == 'ui': + if RunConfig.RUN == None or RunConfig.RUN.lower() == 'ui' or RunConfig.RUN.lower() == 'app': pass - else: + elif RunConfig.RUN.lower() == 'api': cells.insert(3, html.td(report.code)) cells.insert(4, html.td(report.body)) cells.pop() @@ -62,22 +68,23 @@ def pytest_configure(config): if RunConfig.RUN == None or RunConfig.RUN.lower() == 'ui': # 用于去掉接口测试中的Base URL config.run_type = 'ui' - if str(RunConfig.ISTEST) == '0' or str(RunConfig.ISTEST).lower() == 'false': - RunConfig.ISTEST = False - config.istest = bool(RunConfig.ISTEST) - else: + elif RunConfig.RUN.lower() == 'api': # 用于去掉Base URL config.run_type = 'api' - if str(RunConfig.ISTEST) == '0' or str(RunConfig.ISTEST).lower() == 'false': - RunConfig.ISTEST = False - config.istest = bool(RunConfig.ISTEST) config._metadata['Platform'] = f'Requests-{requests.__version__}' - - -# def pytest_metadata(metadata): -# print(1111, metadata) -# metadata.pop('Base URL') -# print(1111,metadata) + else: + config.run_type = 'app' + if not RunConfig.app_name: + config.app_name = RunConfig.desired_caps["deviceName"] + config.app_name = RunConfig.app_name + config._metadata['Platform'] = f'platform: {RunConfig.desired_caps["platformName"]}-' \ + f'{RunConfig.desired_caps["platformVersion"]}-' \ + f'{config.app_name}; Appium: {appium.version.version}' + if str(RunConfig.ISTEST) == '0' or str(RunConfig.ISTEST).lower() == 'false': + RunConfig.ISTEST = False + config.istest = bool(RunConfig.ISTEST) + else: + config.istest = True @pytest.mark.hookwrapper @@ -86,7 +93,7 @@ def pytest_runtest_makereport(item): 用于向测试用例中添加用例的开始时间、内部注释,和失败截图等. :param item: """ - if RunConfig.RUN == None or RunConfig.RUN.lower() == 'ui': + if RunConfig.RUN == None or RunConfig.RUN.lower() == 'ui' or RunConfig.RUN.lower() == 'app': pytest_html = item.config.pluginmanager.getplugin('html') outcome = yield report = outcome.get_result() @@ -111,9 +118,12 @@ def pytest_runtest_makereport(item): outcome = yield report = outcome.get_result() report.description = description_html(item.function.__doc__) - report.code = RunConfig.API_RESULT_CODE - report.body = RunConfig.API_RESULT - + if RunConfig.API_RESULT_CODE: + report.code = RunConfig.API_RESULT_CODE + report.body = RunConfig.API_RESULT + else: + report.code = '无' + report.body = '无' def description_html(desc): """ @@ -122,7 +132,7 @@ def description_html(desc): :return: """ if desc is None: - return "No case description" + return "没有描述信息!" desc_ = "" for i in range(len(desc)): if i == 0: @@ -147,15 +157,24 @@ def capture_screenshots(): :param case_name: 用例名 :return: """ - global driver - # file_name = case_name.split("/")[-1] - if RunConfig.NEW_REPORT is None: - raise NameError('没有初始化测试报告目录') + if RunConfig.RUN is None or RunConfig.RUN.lower() == 'ui': + global driver + # file_name = case_name.split("/")[-1] + if RunConfig.NEW_REPORT is None: + raise NameError('没有初始化测试报告目录') + else: + # image_dir = os.path.join(RunConfig.NEW_REPORT, "image", file_name) + base64_img = RunConfig.driver.get_screenshot_as_base64() + return base64_img + # RunConfig.driver.save_screenshot(image_dir) else: - # image_dir = os.path.join(RunConfig.NEW_REPORT, "image", file_name) - base64_img = RunConfig.driver.get_screenshot_as_base64() + global app_driver + filename = 'error'+str(time.time())+'.png' + RunConfig.app_driver.get_screenshot_as_file(filename) + import base64 + base64_img = base64.b64encode(open(filename, 'rb').read()) + os.remove(filename) return base64_img - # RunConfig.driver.save_screenshot(image_dir) # 用例 call 执行时调用 @@ -219,6 +238,36 @@ def browser(base_url): return driver +# 初始化Appium driver +@pytest.fixture(scope='session', autouse=True) +def app_driver(): + """ + 定义全局的app driver + return: app_driver + """ + if RunConfig.RUN is not None and RunConfig.RUN.lower() == 'app': + if get_appium(): + global app_driver + app_driver = app_webdriver.Remote(command_executor='http://localhost:4723/wd/hub', + desired_capabilities=RunConfig.desired_caps) + logger.info(f'初始化app_driver-{app_driver}') + RunConfig.app_driver = app_driver + return app_driver + else: + logger.error('没有检测到启动Appium服务,请启动Appium!') + + +def get_appium(): + for proc in psutil.process_iter(): + try: + info = proc.as_dict(attrs=['pid', 'name']) + except psutil.NoSuchProcess: + pass + else: + if "Appium.exe" in info["name"]: + return True + + # 初始化全局session @pytest.fixture(scope='session', autouse=True) def session(): @@ -264,15 +313,15 @@ def close(): if RunConfig.RUN is None or RunConfig.RUN.lower() == 'ui': yield driver driver.quit() - mysql.close() - logger.info('mysql close!') - logger.info("test end!") - else: + elif RunConfig.RUN.lower() == 'api': yield session session.close() - mysql.close() - logger.info('mysql close!') - logger.info("test end!") + else: + yield app_driver + app_driver.terminate_app(RunConfig.desired_caps['appPackage']) + mysql.close() + logger.info('mysql close!') + logger.info("test end!") if __name__ == "__main__": diff --git a/test_dir/test_API/__init__.py b/page/app_page/__init__.py similarity index 88% rename from test_dir/test_API/__init__.py rename to page/app_page/__init__.py index cf07cef0232bf0d9141a46ea489fb0e48e872674..da190728b4a23cc04bc69d02289f2d5e4925e4c6 100644 --- a/test_dir/test_API/__init__.py +++ b/page/app_page/__init__.py @@ -3,7 +3,7 @@ """ @author: zhangZW @file: __init__.py.py -@time: 2022/09/02 +@time: 2022/09/26 @des: description """ diff --git a/page/app_page/app_weixin_page.py b/page/app_page/app_weixin_page.py new file mode 100644 index 0000000000000000000000000000000000000000..c0efce489cdbb6afbf0bd4eb131b51d966b38aab --- /dev/null +++ b/page/app_page/app_weixin_page.py @@ -0,0 +1,10 @@ +from page import Page, Element + + +class IndexPage(Page): + login_button = Element(id_="com.tencent.mm:id/hi4") + + +class LoginPage(Page): + phone_input = Element(android_uiautomator='text("请填写手机号")') + next_button = Element(xpath='//*[contains(@text,"下一步")]') \ No newline at end of file diff --git a/test_dir/test_UI/__init__.py b/page/web_page/__init__.py similarity index 88% rename from test_dir/test_UI/__init__.py rename to page/web_page/__init__.py index cf07cef0232bf0d9141a46ea489fb0e48e872674..da190728b4a23cc04bc69d02289f2d5e4925e4c6 100644 --- a/test_dir/test_UI/__init__.py +++ b/page/web_page/__init__.py @@ -3,7 +3,7 @@ """ @author: zhangZW @file: __init__.py.py -@time: 2022/09/02 +@time: 2022/09/26 @des: description """ diff --git a/page/baidu_page.py b/page/web_page/baidu_page.py similarity index 100% rename from page/baidu_page.py rename to page/web_page/baidu_page.py diff --git a/pytest.ini b/pytest.ini index d62a06b2b67d5306ac4c5f15e28b0aeca7e7ecb1..b6f85f68cdaf7d481408fd9f53e24f0cf71d932e 100644 --- a/pytest.ini +++ b/pytest.ini @@ -4,6 +4,6 @@ test_base_url = https://www.baidu.com # UI production environment base_url = https://www.baidu.com # API test environment -test_base_ip = www.baidu.com +test_base_ip = www.baidu.com2 # API production environment base_ip = hao.360.com1 diff --git a/requirements.txt b/requirements.txt index ea9406aa06ab59d33838ab2352dd6e5f2b261253..5ced6b5f82fd2eb174316e1943f2c9b239f210e4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ cffi==1.15.1 charset-normalizer==2.1.1 click==7.1.2 colorama==0.4.5 +cryptography==38.0.1 func-timeout==4.3.5 h11==0.13.0 idna==3.3 @@ -17,8 +18,10 @@ outcome==1.2.0 packaging==21.3 pluggy==0.13.1 poium==1.1.5 +psutil==5.9.2 py==1.11.0 pycparser==2.21 +PyMySQL==1.0.2 pyparsing==3.0.9 PySocks==1.7.1 pytest==6.2.4 diff --git a/run_tests.py b/run_tests.py index 975df80aeb5f4729834cdcca69f8244e974a9d2c..73e4732a168a974353ce9fb67f86772b4179158f 100644 --- a/run_tests.py +++ b/run_tests.py @@ -4,7 +4,7 @@ import time from poium.common.logging import logger import pytest import click -from conftest import UI_REPORT_DIR, API_REPORT_DIR +from conftest import UI_REPORT_DIR, API_REPORT_DIR, APP_REPORT_DIR from config import RunConfig # logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') @@ -13,7 +13,7 @@ from config import RunConfig ''' 说明: -1、用例创建原则,测试文件名必须以“test”开头,测试函数必须以“test”开头。 +1、用例创建原则,测试文件名必须以“test”开头,测试函数必须以“test”开头,测试类必须以“Test”开头。 2、运行方式: > python run_tests.py (回归模式,生成HTML报告) > python run_tests.py -m debug (调试模式) @@ -35,30 +35,14 @@ def init_env(new_report): def run(m, rt, istest): RunConfig.RUN = rt RunConfig.ISTEST = istest + now_time = time.strftime("%Y_%m_%d_%H_%M_%S") if rt is None or rt.lower() == "ui": if m is None or m == "run": # **********新建日志************ - now_time = time.strftime("%Y_%m_%d_%H_%M_%S") RunConfig.NEW_REPORT = os.path.join(UI_REPORT_DIR, now_time) + case_path = RunConfig.UI_cases_path logger.add(RunConfig.UI_LOG_DIR + f'{RunConfig.NEW_REPORT.split("/")[-1]}.log', enqueue=True) - logger.info("UI回归模式,开始执行✈✈!") - init_env(RunConfig.NEW_REPORT) - html_report = os.path.join(RunConfig.NEW_REPORT, f'{RunConfig.NEW_REPORT.split("/")[-1]}_report.html') - xml_report = os.path.join(RunConfig.NEW_REPORT, "junit-xml.xml") - pytest.main(["-s", "-v", RunConfig.UI_cases_path, - "--html=" + html_report, - "--junit-xml=" + xml_report, - "--self-contained-html", - "--maxfail", RunConfig.max_fail, - "--reruns", RunConfig.rerun, - '--capture=fd']) - logger.info("运行结束,生成测试报告♥❤!") - try: - send_mail(RunConfig.SEND_USER, RunConfig.RECE_USERS, html_report.replace('\\', '/')) - logger.info(f'发送邮件-{";".join(RunConfig.RECE_USERS)}') - send_ding(RunConfig.atMobiles, 'UI') - except Exception as e: - logger.error(f"报告-{html_report.replace}-发送失败!--{e}") + logger.info("WEB UI回归模式,开始执行✈✈!") elif m == "debug": print("debug模式,开始执行!") pytest.main(["-v", "-s", RunConfig.UI_cases_path]) @@ -66,30 +50,51 @@ def run(m, rt, istest): elif rt.lower() == 'api': if m is None or m == "run": # **********新建日志************ - now_time = time.strftime("%Y_%m_%d_%H_%M_%S") RunConfig.NEW_REPORT = os.path.join(API_REPORT_DIR, now_time) logger.add(RunConfig.API_LOG_DIR + f'{RunConfig.NEW_REPORT.split("/")[-1]}.log', enqueue=True) + case_path = RunConfig.API_cases_path logger.info("API回归模式,开始执行✈✈ !") - init_env(RunConfig.NEW_REPORT) - html_report = os.path.join(RunConfig.NEW_REPORT, f'{RunConfig.NEW_REPORT.split("/")[-1]}_report.html') - xml_report = os.path.join(RunConfig.NEW_REPORT, "junit-xml.xml") - pytest.main(["-s", "-v", RunConfig.API_cases_path, - "--html=" + html_report, - "--junit-xml=" + xml_report, - "--self-contained-html", - "--maxfail", RunConfig.max_fail, - "--reruns", RunConfig.rerun]) - logger.info("运行结束,生成测试报告♥❤!") - try: - send_mail(RunConfig.SEND_USER, RunConfig.RECE_USERS, html_report.replace('\\', '/')) - logger.info(f'发送邮件-{";".join(RunConfig.RECE_USERS)}') - send_ding(RunConfig.atMobiles, '接口') - except Exception as e: - logger.error(f"报告-{html_report}-发送失败!--{e}") elif m == "debug": print("debug模式,开始执行!") pytest.main(["-v", "-s", RunConfig.API_cases_path]) print("运行结束!!") + elif rt.lower() == 'app': + if m is None or m == "run": + # **********新建日志************ + RunConfig.NEW_REPORT = os.path.join(APP_REPORT_DIR, now_time) + logger.add(RunConfig.APP_LOG_DIR + f'{RunConfig.NEW_REPORT.split("/")[-1]}.log', enqueue=True) + case_path = RunConfig.APP_cases_path + logger.info("APP回归模式,开始执行✈✈!") + elif m == "debug": + print("debug模式,开始执行!") + pytest.main(["-v", "-s", RunConfig.APP_cases_path]) + print("运行结束!!") + else: + raise ValueError('命令行参数错误,无效参数!') + if m is None or m == "run": + init_env(RunConfig.NEW_REPORT) + html_report = os.path.join(RunConfig.NEW_REPORT, f'{RunConfig.NEW_REPORT.split("/")[-1]}_report.html') + xml_report = os.path.join(RunConfig.NEW_REPORT, "junit-xml.xml") + pytest.main(["-s", "-v", case_path, + "--html=" + html_report, + "--junit-xml=" + xml_report, + "--self-contained-html", + "--maxfail", RunConfig.max_fail, + "--reruns", RunConfig.rerun]) + logger.info("运行结束,生成测试报告♥❤!") + try: + send_mail(RunConfig.SEND_USER, RunConfig.RECE_USERS, html_report.replace('\\', '/')) + logger.info(f'发送邮件-{";".join(RunConfig.RECE_USERS)}') + if 'APP' in case_path: + ty = 'APP' + elif 'API' in case_path: + ty = '接口' + else: + ty = 'WEB UI' + send_ding(RunConfig.atMobiles, ty) + except Exception as e: + logger.error(f"报告-{html_report}-发送失败!--{e}") + def send_mail(sender: str, receer: list, filepath: str) -> None: @@ -97,9 +102,14 @@ def send_mail(sender: str, receer: list, filepath: str) -> None: from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart today = time.strftime('%Y-%m-%d', time.localtime()) - subject = f"{today}的UI测试报告已生成,请查看附件{filepath.split('/')[-1]}" + subject = f"{today}的WEB UI测试报告已生成,请查看附件{filepath.split('/')[-1]}" if 'API' in filepath: subject = f"{today}的API测试报告已生成,请查看附件{filepath.split('/')[-1]}" + elif 'APP' in filepath: + if RunConfig.app_name: + subject = f"{today}的APP-{RunConfig.app_name}测试报告已生成,请查看附件{filepath.split('/')[-1]}" + else: + subject = f"{today}的APP测试报告已生成,请查看附件{filepath.split('/')[-1]}" with open(filepath, 'rb') as f: send_att = f.read() att = MIMEText(send_att, 'html', 'utf-8') diff --git a/test_dir/test_APP/test_wx.py b/test_dir/test_APP/test_wx.py new file mode 100644 index 0000000000000000000000000000000000000000..6591d36e3124c2e1723f41fad63144ec38f78977 --- /dev/null +++ b/test_dir/test_APP/test_wx.py @@ -0,0 +1,24 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +""" +@author: zhangZW +@file: test_wx.py +@time: 2022/09/25 +@des: description +""" +import pytest + +from page.app_page import app_weixin_page + + +class Testwx: + + def test_weixin_login(self, app_driver): + page = app_weixin_page.IndexPage(app_driver) + page.login_button.click() + login_page = app_weixin_page.LoginPage(app_driver) + login_page.phone_input.set_text('18333221122') + login_page.next_button.click() + +if __name__ == '__main__': + pytest.main(['test_wx.py', '-s']) \ No newline at end of file diff --git a/test_dir/test_UI/test_baidu.py b/test_dir/test_UI/test_baidu.py index bd43262de52d8e8d761d69d1a4f5de55bef9fed8..0e2bc8f4cca49c4dbd53875c98c93b472c20f12c 100644 --- a/test_dir/test_UI/test_baidu.py +++ b/test_dir/test_UI/test_baidu.py @@ -1,14 +1,17 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- """ -@author: 虫师 -@data: 2019-10-17 -@function python 基本用法 +@author: zhangZW +@file: test_baidu.py +@time: 2022/09/26 +@des: description """ + import sys from time import sleep -import pytest from os.path import dirname, abspath sys.path.insert(0, dirname(dirname(abspath(__file__)))) -from page.baidu_page import BaiduPage +from page.web_page.baidu_page import BaiduPage class TestSearch: diff --git a/test_dir/test_UI/test_parametrize.py b/test_dir/test_UI/test_parametrize.py index 9bf90ced2b02dc1ee73bd922043e8e258d982714..5fa43f8cdfce1a6ae608484e3db87ffc07cb32c7 100644 --- a/test_dir/test_UI/test_parametrize.py +++ b/test_dir/test_UI/test_parametrize.py @@ -1,8 +1,3 @@ -""" -@author: 虫师 -@data: 2019-10-17 -@function pytest 参数使用 -""" import sys import json from time import sleep @@ -11,7 +6,7 @@ from os.path import dirname, abspath base_path = dirname(dirname(abspath(__file__))) sys.path.insert(0, base_path) -from page.baidu_page import BaiduPage +from page.web_page.baidu_page import BaiduPage @pytest.mark.parametrize( diff --git "a/\351\234\200\350\246\201\344\277\256\346\224\271\347\232\204\344\276\235\350\265\226\346\226\207\344\273\266\357\274\214\350\257\267\350\246\206\347\233\226site-packages\344\270\213\347\232\204\346\226\207\344\273\266/pytest_base_url/plugin.py" "b/\351\234\200\350\246\201\344\277\256\346\224\271\347\232\204\344\276\235\350\265\226\346\226\207\344\273\266\357\274\214\350\257\267\350\246\206\347\233\226site-packages\344\270\213\347\232\204\346\226\207\344\273\266/pytest_base_url/plugin.py" index 5e725f7df457368aa8f1ddfdfb1efb0f4b63ff3a..312b37dbf77c15695d2688245e03bd99ad110149 100644 --- "a/\351\234\200\350\246\201\344\277\256\346\224\271\347\232\204\344\276\235\350\265\226\346\226\207\344\273\266\357\274\214\350\257\267\350\246\206\347\233\226site-packages\344\270\213\347\232\204\346\226\207\344\273\266/pytest_base_url/plugin.py" +++ "b/\351\234\200\350\246\201\344\277\256\346\224\271\347\232\204\344\276\235\350\265\226\346\226\207\344\273\266\357\274\214\350\257\267\350\246\206\347\233\226site-packages\344\270\213\347\232\204\346\226\207\344\273\266/pytest_base_url/plugin.py" @@ -19,6 +19,7 @@ def base_url(request): if base_url is not None: return base_url + @pytest.fixture(scope="session", autouse=True) def _verify_url(request, base_url): """Verifies the base URL""" @@ -45,11 +46,14 @@ def pytest_configure(config): base_url = config.getoption("base_url") or config.getini("base_url") if config.run_type == 'api': pass - else: + elif config.run_type == 'ui': if base_url is not None: config.option.base_url = base_url if hasattr(config, "_metadata"): config._metadata["Base URL"] = base_url + else: + if config.app_name: + config._metadata['APP name'] = config.app_name def pytest_report_header(config, startdir): @@ -60,13 +64,16 @@ def pytest_report_header(config, startdir): base_url = config.getoption("base_url") if base_url is not None: return "baseurl: {0}".format(base_url) - else: + elif config.run_type == 'api': if config.istest: base_ip = config.getini("test_base_ip") else: base_ip = config.getini("base_ip") if base_ip is not None: return "baseip: {0}".format(base_ip) + else: + if config.app_name: + return 'app name: {}'.format(config.app_name) def pytest_addoption(parser):