def quit_driver(): # log.info("conftest文件初始化") # cf.init() binary_location = '/usr/bin/google-chrome' chrome_driver_binary = '/usr/local/bin/chromedriver' # chrome_options = webdriver.ChromeOptions() chrome_options = Options() chrome_options.binary_location = binary_location chrome_options.add_argument('--no-sandbox') # 解决DevToolsActivePort文件不存在的报错 chrome_options.add_argument( '--headless') # 浏览器不提供可视化页面. linux下如果系统不支持可视化不加这条会启动失败 chrome_options.add_argument('--disable-gpu') # 谷歌文档提到需要加上这个属性来规避bug chrome_options.add_argument('--disable-dev-shm-usage') chrome_options.add_argument( 'blink-settings=imagesEnabled=false') # 不加载图片, 提升速度 chrome_options.add_argument('--start-maximized') # 窗口最大化 # 新版google不显示正在受自动化软件控制 chrome_options.add_experimental_option('excludeSwitches', ['enable-automation']) # driver = webdriver.Chrome(options=chrome_options) os.environ["webdriver.chrome.driver"] = chrome_driver_binary driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver', chrome_options=chrome_options) driver.get(cf.get_value('site')) log.info('打开的网址是:' + cf.get_value('site')) log.info("初始化driver") cf.set_value('driver', driver) yield driver.quit() log.info('关闭浏览器')
def pytest_runtest_makereport(item, call): ''' 获取每个用例状态的钩子函数 :param item: :param call: :return: ''' # 获取钩子方法的调用结果 outcome = yield rep = outcome.get_result() # 仅仅获取用例call 执行结果是失败的情况, 不包含 setup/teardown if rep.when == "call" and rep.failed: mode = "a" if os.path.exists("failures") else "w" with open("failures", mode) as f: # let's also access a fixture for the fun of it if "tmpdir" in item.fixturenames: extra = " (%s)" % item.funcargs["tmpdir"] else: extra = "" f.write(rep.nodeid + extra + "\n") # 添加allure报告截图 if hasattr(cf.get_value('driver'), "get_screenshot_as_png"): with allure.step('添加失败截图...'): allure.attach( cf.get_value('driver').get_screenshot_as_png(), "失败截图", allure.attachment_type.PNG)
def set_driver(): """设置driver""" # 配置Chrome Driver chrome_options = webdriver.ChromeOptions() chrome_options.add_argument('--start-maximized') # 浏览器最大化 chrome_options.add_argument('--disable-infobars') # 不提醒chrome正在受自动化软件控制 prefs = {'download.default_directory': cf.get_value('download_path')} chrome_options.add_experimental_option('prefs', prefs) # 设置默认下载路径 # chrome_options.add_argument(r'--user-data-dir=D:\ChromeUserData') # 设置用户文件夹,可免登陆 driver = webdriver.Chrome('{}\\driver\\chromedriver.exe'.format( cf.get_value('root_path')), options=chrome_options) cf.set_value('driver', driver)
class TestWX(): """ pytest: 测试文件以test_开头 测试类以Test开头,并且不能带有__init__方法 测试函数以test_开头 断言使用assert """ driver = cf.get_value('driver') # 从全局变量取driver native_page = WXPage(driver) project_page = ProjectPage(driver) def test_in_project_list(self): """进入项目列表页""" try: self.native_page.into_yidu() self.native_page.click_project() assert self.project_page.wait_element( self.project_page.m_view_list) # 有‘查看列表’element log.info(u'断言有‘查看列表’元素 成功') self.native_page.screenshot(u'进入H5项目列表页') except Exception, e: self.native_page.screenshot(u'进入H5项目列表页失败') raise e
def send_mail(sendto): """ 发送邮件 :param sendto:收件人列表,如['*****@*****.**'] """ mail_host = 'smtp.sohu.com' # 邮箱服务器地址 username = '******' # 邮箱用户名 password = '******' # 邮箱密码 receivers = sendto # 收件人 # 创建一个带附件的实例 message = MIMEMultipart() message['From'] = Header(u'UI自动化', 'utf-8') message['subject'] = Header(u'UI自动化测试结果', 'utf-8') # 邮件标题 message.attach(MIMEText(u'测试结果详见附件', 'plain', 'utf-8'))# 邮件正文 # 构造附件 report_root = cf.get_value('report_path') # 获取报告路径 report_file = 'report.html' # 报告文件名称 att1 = MIMEText(open(report_root + report_file, 'rb').read(), 'base64', 'utf-8') att1["Content-Type"] = 'application/octet-stream' att1["Content-Disposition"] = 'attachment; filename={}'.format(report_file) message.attach(att1) try: smtp = smtplib.SMTP() smtp.connect(mail_host, 25) # 25为 SMTP 端口号 smtp.login(username, password) smtp.sendmail(username, receivers, message.as_string()) print u'邮件发送成功' except Exception, e: print u'邮件发送失败' raise e
class TestHome(): """ pytest: 测试文件以test_开头 测试类以Test开头,并且不能带有__init__方法 测试函数以test_开头 断言使用assert """ driver = cf.get_value('driver') # 从全局变量取driver home_page = HomePage(driver) news_page = NewsPage(driver) hao123_page = Hao123Page(driver) search_page = SearchPage(driver) def test_open_homepage(self): """首页-打开百度首页""" try: self.home_page.open_homepage() assert self.home_page.wait_element( self.home_page.l_more_product) # 有‘更多产品’element log.info(u'断言有‘更多产品’元素 成功') self.home_page.screenshot(u'打开百度首页') except Exception, e: self.home_page.screenshot(u'打开百度首页失败') raise e
def setupGUI(self): # create the menubar self.setupMenubar() # set size xSize = int(config.get_value('GUI', 'InitialWidth')) ySize = int(config.get_value('GUI', 'InitialHeight')) self.resize(xSize, ySize) width = self.resolution[0] height = self.resolution[1] xPos = (width / 2) - (xSize / 2) yPos = height / 2 - (ySize / 2) self.move(xPos, yPos) self.setWindowTitle('InsaniText') #set icon self.setWindowIcon(QIcon("/resources/icons/icon.ico")) # text area self.textArea = InsaniTextEdit(self.controller) self.textArea.setTabStopWidth( 20 ) # tab size (in pixels) is purely graphical. It does not convert to X spaces self.setCentralWidget(self.textArea) # create status bar self.setStatusBar(InsaniStatusbar(self.controller)) # add filetree sidebar self.filetree = InsaniFileTree(self.controller) treedock = QDockWidget() treedock.setWidget(self.filetree) self.addDockWidget(Qt.LeftDockWidgetArea, treedock) # add the diacritics top panel diapanel = diacritics.DiacriticPanel(self.textArea) diadock = QDockWidget() diadock.setWidget(diapanel) self.addDockWidget(Qt.TopDockWidgetArea, diadock) # set working dir self.controller.set_working_dir('.') # show the GUI self.show()
def update_dict(self): ''' 定时更新faq、分词、同义词字典 ''' print '>>update dict, active thread count = ', threading.active_count() # 定时器,参数为(多少时间后执行,单位为秒,执行的方法) dal_faq.init_faq_corpus() self.init_synonym() self.faqs = config.get_value("faq_list")
def test_commit_fromfrom(self): """提交问卷""" try: self.project_page.open(cf.get_value('project_list_url')) # 跳到项目列表url self.project_page.click_my_task() # 打开我的任务 self.project_page.commit_from() assert self.project_page.wait_text(u'数据提交成功') except Exception, e: self.project_page.screenshot(u'from提交失败') raise e
def test_open_progress(self): """打开项目进度""" try: self.project_page.open(cf.get_value('project_list_url')) # 跳到项目列表url self.project_page.click_project_progress() assert self.project_page.get_progress_count() > 0 # 断言填写员完成数>0 self.project_page.screenshot(u'项目进度统计图') except Exception, e: self.project_page.screenshot(u'项目进度完成数错误') raise e
def remove_stopwords(words): clean_words = [] stopwords = config.get_value("stopwords") for word in words: if word not in stopwords: # print 'filter words', word clean_words.append(word) # print '#'.join(clean_words) # for word in clean_words: # print 'word type = ', type(word) return clean_words
def key_words_to_synonyms(keywords): """ :return: 返回关键词替换后的同义词 """ synonyms_dict = config.get_value("synonyms_dict", None) replace_keywords = set() if synonyms_dict is None or len(synonyms_dict) == 0: logger.info("load synonyms dict error!") return set(keywords) else: logger.info("in rule based qq similarity, len(synonyms_dict) = %s", len(synonyms_dict)) for word in keywords: replace_keywords.add(synonyms_dict.get(word, word)) return replace_keywords
def screenshot(self, info='-'): """ 截图,起名为:文件名-方法名-注释 :param info: 截图说明 """ catalog_name = cf.get_value('screenshot_path') # 从全局变量取截图文件夹位置 if not os.path.exists(catalog_name): os.makedirs(catalog_name) class_object = inspect.getmembers( inspect.stack()[1][0])[-3][1]['self'] # 获得测试类的object classname = str(class_object).split('.')[1].split(' ')[0] # 获得测试类名称 testcase_name = inspect.stack()[1][3] # 获得测试方法名称 filepath = catalog_name + classname + "@" + testcase_name + info + ".png" self.driver.get_screenshot_as_file(filepath) log.info(u'截图:%s.png' % info)
def __init__(self): self.faqs = config.get_value("faq_list") # key: id, value: doc: self.synonym = dict() self.defualt_match_type = None self.load_defualt_match_type() start = time.time() self.init_synonym() end = time.time() logger.info("load faq segment used %d second, total Len faq = %d", end - start, len(self.faqs)) logger.info("load synonym successful, synonym len = %d", len(self.synonym)) if not is_test: self.repeatingTimer = RepeatingTimer(refresh_interval, self.update_dict) self.repeatingTimer.start()
def init_sql(): driver = config.get_value('DATABASE_DRIVER') username = config.get_value('DATABASE_USERNAME') password = config.get_value('DATABASE_PASSWORD') host = config.get_value('DATABASE_HOST') port = config.get_value('DATABASE_PORT') db_name = config.get_value('DATABASE_NAME') return SqlCommon(driver=driver, host=host, port=port, username=username, password=password, database=db_name)
def pytest_runtest_makereport(item): """当测试失败的时候,自动截图,展示到html报告中""" pytest_html = item.config.pluginmanager.getplugin('html') outcome = yield report = outcome.get_result() extra = getattr(report, 'extra', []) if report.when == 'call' or report.when == "setup": xfail = hasattr(report, 'wasxfail') if (report.skipped and xfail) or (report.failed and not xfail): file_name = report.nodeid.replace("::", "_") + ".png" driver = cf.get_value('driver') # 从全局变量取driver screen_img = driver.get_screenshot_as_base64() if file_name: html = '<div><img src="data:image/png;base64,%s" alt="screenshot" style="width:600px;height:300px;" ' \ 'onclick="window.open(this.src)" align="right"/></div>' % screen_img extra.append(pytest_html.extras.html(html)) report.extra = extra report.description = str(item.function.__doc__).decode( 'utf-8', 'ignore') # 不解码转成Unicode,生成HTML会报错
def load_defualt_match_type(self): conf = config.get_value("conf") if conf is None: logger.error("load lark_bot_nlp.conf error!") try: all_support_type = conf["default_match_type"]["all_support_type"] all_support_type = map(lambda x: x.strip().lower(), all_support_type.strip('|').split('|')) defualt_match_type = conf["default_match_type"]["match_type"] defualt_match_type = map(lambda x: x.strip().lower(), defualt_match_type.strip('|').split('|')) # 判断默认匹配类型是否配错 assert len(set(defualt_match_type) & set(all_support_type)) == len(set(defualt_match_type)), \ 'set defualt match type error' except: raise Exception( "load defualt_match_type error, please set defualt_match_type in lark_bot_nlp.conf" ) self.defualt_match_type = defualt_match_type
class TestSearch(): """ pytest: 测试文件以test_开头 测试类以Test开头,并且不能带有__init__方法 测试函数以test_开头 断言使用assert """ driver = cf.get_value('driver') # 从全局变量取driver news_page = NewsPage(driver) def test_show_QRcode(self): """新闻页-显示二维码""" try: self.news_page.open_newspage() self.news_page.move_QRcode() assert self.news_page.wait_element( self.news_page.im_QRcode) # 判断二维码图片出现 self.news_page.screenshot(u'显示二维码') except Exception, e: self.news_page.screenshot(u'显示二维码失败') raise e
def load_rules(rule_path): conf = config.get_value("conf") try: algorithm_type = conf["algorithm"]["type"] except: algorithm_type = "mix" with open(rule_path, 'r') as fout: rule_id = 0 for line in fout.readlines(): line = any2unicode(line) items = line.strip().split('\t') if len(items) != 3: raise Exception("导入规则错误!, rule id = %d" % (rule_id)) keywords = key_words_to_synonyms( map(lambda x: x.strip(), items[0].split('#'))) answer_ids = map(lambda x: int(x.strip()), items[1].strip().split('|')) score = float(items[2].strip()) if algorithm_type == 'word2vec': score = 1.0 rule = [str(rule_id), keywords, answer_ids, score] _rules.append(rule) rule_id += 1
class TestProject(): """ pytest: 测试文件以test_开头 测试类以Test开头,并且不能带有__init__方法 测试函数以test_开头 断言使用assert """ driver = cf.get_value('driver') # 从全局变量取driver project_page = ProjectPage(driver) # -----------------查看列表------------------ def test_in_project(self): """进入项目""" try: self.project_page.click_view_list() # 点击 查看列表 assert self.project_page.wait_element(self.project_page.b_add_people) # 有‘添加人员’ log.info(u'断言有‘添加人员’按钮 成功') self.project_page.screenshot(u'进入项目') except Exception, e: self.project_page.screenshot(u'进入项目失败') raise e
def get_args(self): log.info("Argprase命令行类初始化") cf.init() """命令行参数解析""" parser = argparse.ArgumentParser(description=u'可选择参数:') parser.add_argument('-e', '--environment', choices=['test', 'prod'], default='test', help=u'测试环境test,线上环境prod') parser.add_argument('-m', '--mark', choices=['mock', 'jenkins'], default='mock', help=u'测试环境百度mock,线上环境jenkins登录') args = parser.parse_args() args_env = args.environment log.info('args数据:' + str(args_env)) log.info('args传递的参数:' + str(args)) if args.environment in ('test', 'test'): cf.set_value('environment', 'test') cf.set_value('site', 'http://www.baidu.com/') elif args.environment in ('prod', 'prod'): cf.set_value('environment', 'prod') cf.set_value('site', 'a') else: exit() print("请输入test/prod") if args.mark in ('jen', 'jenkins'): cf.set_value('mark', 'jenkins') elif args.mark in ('mo', 'mock'): cf.set_value('mark', 'mock') else: exit() print("请输入jenkins/mock") log.info('获取到的site地址:' + cf.get_value('site'))
class TestSearch(): """ pytest: 测试文件以test_开头 测试类以Test开头,并且不能带有__init__方法 测试函数以test_开头 断言使用assert """ driver = cf.get_value('driver') # 从全局变量取driver home_page = HomePage(driver) search_page = SearchPage(driver) def test_click_result(self): """搜索页-点击首个搜索结果""" try: self.home_page.open_homepage() self.home_page.input_keyword(u'星空物语') # 输入关键字 self.search_page.click_result() # 点击百科 assert self.home_page.wait_text(u'电视剧《一起来看流星雨》片头曲') # 验证页面打开 self.home_page.screenshot(u'打开搜索结果') self.search_page.close() # 关闭百科页面 except Exception, e: self.home_page.screenshot(u'打开搜索结果失败') raise e
desired_caps['appPackage'] = 'com.tencent.mm' desired_caps['appActivity'] = '.ui.LauncherUI' desired_caps['noReset'] = 'True' # 不重置app # 设置原因:appium识别webview的时候, 把com.tencent.mm:tools的webview识别成com.tencent.mm的webview. 从而导致context切换失败 desired_caps['chromeOptions'] = {'androidProcess': 'com.tencent.mm:tools'} desired_caps['recreateChromeDriverSessions'] = 'True' desired_caps['newCommandTimeout'] = 600 driver = webdriver.Remote(r'http://*****:*****@qq.com']) # 将报告发送至邮箱
chrome_options = webdriver.ChromeOptions() chrome_options.add_argument('--start-maximized') # 浏览器最大化 chrome_options.add_argument('--disable-infobars') # 不提醒chrome正在受自动化软件控制 prefs = {'download.default_directory': cf.get_value('download_path')} chrome_options.add_experimental_option('prefs', prefs) # 设置默认下载路径 # chrome_options.add_argument(r'--user-data-dir=D:\ChromeUserData') # 设置用户文件夹,可免登陆 driver = webdriver.Chrome('{}\\driver\\chromedriver.exe'.format( cf.get_value('root_path')), options=chrome_options) cf.set_value('driver', driver) def main(): """运行pytest命令启动测试""" pytest.main([ '-v', '-s', 'test_case/', '--html=report/report.html', '--self-contained-html' ]) if __name__ == '__main__': cf.init() # 初始化全局变量 get_args() # 命令行参数解析 log = Logger('szh') # 初始化log配置 set_driver() # 初始化driver main() # 运行pytest测试集 cf.get_value('driver').quit() # 关闭selenium driver # 先将util.mail文件send_mail()中的用户名、密码填写正确,再启用发送邮件功能!!! # send_mail(['*****@*****.**']) # 将报告发送至邮箱
@pytest.mark.jenkins def test_case02(self, quit_driver): ''' jenkins ''' jp = JenkinsPage() jp.login_success('a', 'a') if __name__ == '__main__': arg = argparse.Argprase() arg.get_args() # log.info('配置初始化') # cf.init() log.info('主程序中获取到的site地址:' + cf.get_value('site')) log.info('开始运行代码') report_time = time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime(time.time())) report_name = 'search' + report_time + '.html' # pytest.main(['-q', '-s', 'TestSearch.py', '-m mock']) # mock标记测试 # 生成html报告 # pytest.main(['-q', '-s', 'TestSearch.py', '--reruns', '1', '--html=./report/' + report_name , '--self-contained-html']) # 生成allure报告 mark = cf.get_value('mark') log.info('获取到的mark数据:' + mark) # 本地运行 # pytest.main(['-q', '-s', 'TestSearch.py', '-m' + mark, '--alluredir', # './report']) # 服务器运行 allure_path = cf.get_value('allure')
def __init__(self): self.driver = cf.get_value('driver') # 从全局变量取driver
def open_newspage(self): site = cf.get_value('site').replace('www', 'news') # 从全局变量取百度地址并替换为新闻地址 self.open(site)
def open_homepage(self): site = cf.get_value('site') # 从全局变量取百度地址 self.open(site)