def get_element(self, selector): """定位元素""" by = selector[0] value = selector[1] bys = ['id', 'name', 'class', 'tag', 'link', 'plink', 'css', 'xpath'] element = None if by in bys: try: if by == 'id': element = self.driver.find_element_by_id(value) elif by == 'name': element = self.driver.find_element_by_name(value) elif by == 'class': element = self.driver.find_element_by_class_name(value) elif by == 'tag': element = self.driver.find_element_by_tag_name(value) elif by == 'link': element = self.driver.find_element_by_link_text(value) elif by == 'plink': element = self.driver.find_element_by_partial_link_text(value) elif by == 'css': element = self.driver.find_element_by_css_selector(value) elif by == 'xpath': element = self.driver.find_element_by_xpath(value) log1.info('元素定位成功。定位方式:%s,使用的值:%s' % (by, value)) return element except NoSuchElementException: log1.error('没有定位到元素,定位方式:%s,使用的值:%s' % (by, value), exc_info=1) else: log1.error('元素定位方式错误,请使用id,name,class,tag,link,plink,css,xpath为定位方式参数')
def open_browser(self): """打开浏览器,访问url""" browser = config.config_read('environment', 'browser') log1.info('读取浏览器配置,值为%s' % browser) url = config.config_read('environment', 'url') log1.info('读取url,值为%s' % url) # noinspection PyBroadException try: if browser == 'chrome': option = webdriver.ChromeOptions() option.add_argument('disable-infobars') self.driver = webdriver.Chrome(chrome_options=option) log1.info('打开chrome浏览器') elif browser == 'firefox': self.driver = webdriver.Firefox() log1.info('打开firefox浏览器') else: log1.error('浏览器配置有误,应为chrome或firefox') self.driver.get(url) log1.info('访问url') self.driver.maximize_window() log1.info('浏览器最大化') self.driver.implicitly_wait(10) log1.info('设置静态等待时间10秒') return self.driver except BaseException: log1.error('浏览器打开报错', exc_info=1)
def use_js(self, js): """调用js""" # noinspection PyBroadException try: self.driver.execute_script(js) log1.info('js执行成功,js内容为:%s' % js) except BaseException: log1.error('js执行报错', exc_info=1)
def switch_ifarme(self, selector): """切换farm""" element = self.get_element(selector) # noinspection PyBroadException try: self.driver.switch_to.frame(element) log1.info('切换frame成功') except BaseException: log1.error('切换frame报错', exc_info=1)
def type(self, selector, value): """往输入框输入内容""" element = self.get_element(selector) element.clear() # noinspection PyBroadException try: element.send_keys(value) log1.info('输入的内容:%s' % value) except BaseException: log1.error('内容输入报错', exc_info=1) self.get_img()
def get(self, url, params=None, headers=None, files=None, auth=None): """get请求,返回响应码和响应实体""" try: r = requests.get(url, params=params, headers=headers, files=files, auth=auth, verify=False, stream=True, timeout=10) log1.info('请求实体内容:%s' % params) status_code = r.status_code log1.info('返回状态码:%d' % status_code) response = r.json() log1.info('响应实体内容:%s' % response) return status_code, response except BaseException: log1.error('请求失败!', exc_info=1)
def post_json(self, url, data=None, headers=None, auth=None): """post请求,使用json格式提交请求实体,返回响应码和响应实体""" try: r = requests.post(url, json=data, headers=headers, auth=auth, verify=False, timeout=10) log1.info('请求实体内容:%s' % data) status_code = r.status_code log1.info('返回状态码:%d' % status_code) response = r.json() log1.info('响应实体内容:%s' % response) return status_code, response except BaseException: log1.error('请求失败!', exc_info=1)
def test_login3(self): """密码不正确""" case_name = '密码不正确' log1.info("执行测试用例:%s" % case_name) login = LoginPage(self.driver) login.login('xuhaixiang1993', ' 12314') error_text = login.get_login_error() try: self.assertEqual(error_text, 'Incorrect username or password.') log1.info("测试用例执行成功:%s" % case_name + '\n') except AssertionError: log1.error("测试用例执行失败:%s" % case_name + '\n') raise
def test_login1(self): """用户名为空""" case_name = '用户为空' log1.info("执行测试用例:%s" % case_name) login = LoginPage(self.driver) login.login(' ', '12324') error_text = login.get_login_error() try: self.assertEqual(error_text, 'Incorrect username or password.') log1.info("测试用例执行成功:%s" % case_name + '\n') except AssertionError: log1.error("测试用例执行失败:%s" % case_name + '\n') raise
def dict_value(self, dict1, obj, defaule=None): """查找嵌套字典中key对应的值""" try: for k, v in dict1.items(): if k == obj: log1.info('嵌套字典中%s对应的值为%s' % (obj, v)) return v else: if type(v) is dict: re = self.dict_value(v, obj, defaule) if re is not defaule: return re except BaseException: log1.error('可能有非字典嵌套', exc_info=1)
def test_select_selenium(self): """测试搜索""" case_name = '测试搜索' log1.info("执行测试用例:%s" % case_name) home = HomePage(self.driver) home.search_for('selenium') home.my_sleep(2) title = home.get_title() try: self.assertEqual(title, 'Search · selenium · GitHub') log1.info("测试用例执行通过:%s" % case_name+'\n') except AssertionError: log1.error("测试用例执行失败:%s" % case_name+'\n') raise
def get(self, url, params=None, headers=None, files=None): '''封装get方法,返回状态码和响应内容''' try: response = requests.get(url, params=params, headers=headers, files=files) # log1.info("请求的参数是:{}".format(params)) response_statu_code = response.status_code # log1.info("返回的状态码是:{}".format(response_statu_code)) response_text = response.content.decode('utf-8') # log1.info("响应内容是:{}".format(response_text)) except BaseException as e: log1.error("请求错误:{}".format(e))
def post(self, url, params=None, headers=None, files=None): '''封装post请求''' try: response = requests.post(url, params=params, headers=headers, files=files) # log1.info("请求url:{}".format(url)) # log1.info("请求参数:{}".format(params)) log1.info("响应状态码:{}".format(response.status_code)) log1.info("响应内容:{}".format(response.text)) return response except BaseException as e: log1.error("请求错误:{}".format(e))
def test_login4(self): """登录成功""" # 想要执行成功,需使用GitHub账号和密码 case_name = '登录成功' log1.info("执行测试用例:%s" % case_name) login = LoginPage(self.driver) login.login('username', 'password') login_title = login.get_title() try: self.assertEqual(login_title, 'GitHub') log1.info("测试用例执行成功:%s" % case_name+'\n') except AssertionError: log1.error("测试用例执行失败:%s" % case_name+'\n') raise
def test_switch_login(self): """切换到login页面""" case_name = '切换至login页面' log1.info("执行测试用例:%s" % case_name) home = HomePage(self.driver) home.click_sign_in() home_title = home.get_title() try: # Sign in中间空格删了,验证失败后会被测试报告统计 self.assertEqual(home_title, 'Signin to GitHub · GitHub') log1.info("测试用例执行通过:%s" % case_name+'\n') except AssertionError: log1.error("测试用例执行失败:%s" % case_name+'\n') raise
def switch_menue(self, parentelement, secelement, targetelement): """三级菜单切换""" self.my_sleep(3) # noinspection PyBroadException try: self.driver.switch_to_default_content() self.click(parentelement) log1.info('成功点击一级菜单:%s' % parentelement) self.click(secelement) log1.info('成功点击二级菜单:%s' % secelement) self.click(targetelement) log1.info('成功点击三级菜单:%s' % targetelement) except BaseException: log1.error('切换菜单报错', exc_info=1)
def click(self, selector): """点击元素""" element = self.get_element(selector) # noinspection PyBroadException try: element.click() log1.info('点击元素成功') except BaseException: isdisplay = self.isdisplayed(element) if isdisplay is True: self.my_sleep(3) element.click() log1.info('点击元素成功') else: log1.error('点击元素报错', exc_info=1)
def test_post_two(self): """验证执行失败,测试报告是否会统计""" case_name = '测试失败' log1.info("执行测试用例:%s" % case_name) try: postone = Base() # url地址少了/ url = postone.config_read('test', 'url', url='user/emails') payloda = {'emails': ['*****@*****.**', '*****@*****.**']} auth = ('username', 'password') status_code, response_json = postone.post_json(url, data=payloda, auth=auth) if status_code is 201: log1.info('测试用例执行成功:%s' % case_name) except BaseException: log1.error("测试用例执行出错:%s" % case_name, exc_info=1) raise
def config_remove(self, section, key=None): """从配置文件中删除""" try: # 在section下删除key if key is not None: config.remove_option(section, key) with open(config_path,'w', encoding='utf-8') as f: config.write(f) log1.info('在section:%s下删除键:%s' % (section, key)) else: # 删除section config.remove_section(section) with open(config_path, 'w', encoding='utf-8') as f: config.write(f) log1.info('删除section:%s' % section) except configparser.NoSectionError: log1.error('section is not in config', exc_info=1) except configparser.NoOptionError: log1.error('key is not in config', exc_info=1)
def config_write(self, section, key=None, value=None): """往配置文件中写入""" try: # 在section下新增key = value if key is not None and value is not None: config.set(section, key, value) with open(config_path, 'w', encoding='utf-8') as f: config.write(f) log1.info('在section:%s下添加%s=%s' % (section, key, value)) else: # 新增section config.add_section(section) with open(config_path, 'w', encoding='utf-8') as f: config.write(f) log1.info('新增section:%s' % section) except configparser.NoSectionError: log1.error('section is not in config', exc_info=1) except configparser.NoOptionError: log1.error('key is not in config', exc_info=1)
def test_post_one(self): """调用github添加邮箱接口""" case_name = '添加邮箱' log1.info("执行测试用例:%s" % case_name) try: postone = Base() url = postone.config_read('test', 'url', url='/user/emails') # 想要添加的邮箱,请求实体 payloda = {'emails': ['*****@*****.**', '*****@*****.**']} # github用户名和密码 auth = ('username', 'password') status_code, response_json = postone.post_json(url, data=payloda, auth=auth) if status_code is 201: log1.info('测试用例执行成功:%s' % case_name) except BaseException: log1.error("测试用例执行出错:%s" % case_name, exc_info=1) raise
def sent_mail(): try: # 创建一个带附件的实例 message = MIMEMultipart() message['From'] = formataddr([usernmae, email]) # 括号里的对应发件人邮箱昵称、发件人邮箱账号 log1.info('发件人姓名:%s' % usernmae) log1.info('发件人邮箱:%s' % email) message['To'] = ';'.join(addressed_eamils) # 括号里的对应收件人邮箱昵称、收件人邮箱账号 log1.info('收件人邮箱:' + ';'.join(addressed_eamils)) message['Subject'] = rq + "xxxUI自动化测试报告.html" # 邮件的主题,也可以说是标题 # 邮件正文内容 message.attach(MIMEText('附件为xxxUI自动化测试报告.html', 'plain', 'utf-8')) # 读取要发送的附件 att1 = MIMEText(open(file, 'rb').read(), 'base64', 'utf-8') log1.info('读取附件') # 设置附件对应的content-type att1["Content-Type"] = 'application/octet-stream' # 这里的filename可以任意写,写什么名字,邮件中显示什么名字 att1.add_header("Content-Disposition", "attachment", filename=("gbk", "", "xxxUI自动化测试报告.html")) # 附件名称非中文时的写法 # att["Content-Disposition"] = 'attachment; filename="test.html")' message.attach(att1) log1.info('添加附件') server = smtplib.SMTP_SSL("smtp.qq.com", 465) # 发件人邮箱中的SMTP服务器,端口是25 log1.info('连接QQ邮箱smtp服务') server.login(email, password) # 括号中对应的是发件人邮箱账号、邮箱密码 log1.info('连接成功') server.sendmail(email, addressed_eamils, message.as_string()) # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件 server.quit() # 关闭连接 log1.info("邮件发送成功") except Exception: log1.error("邮件发送失败", exc_info=1)
def get_img(self): """截图""" # img文件夹路径 img_path = os.path.join(getcwd.get_cwd(), 'img/') # img文件夹不存在,新建该文件夹 if not os.path.exists(img_path): os.makedirs(img_path) # 获取当前日期 local_date = time.strftime('%Y-%m-%d', time.localtime(time.time())) # 日期文件夹路径 date_file_path = os.path.join(img_path,local_date) # 日期文件夹不存在,新建该文件夹 if not os.path.exists(date_file_path): os.makedirs(date_file_path) # 截图存放路径 local_time = time.strftime('%Y-%m-%d %H%M%S', time.localtime(time.time())) jt_name = local_time+'.png' jt_path = os.path.join(date_file_path, jt_name) try: self.driver.get_screenshot_as_file(jt_path) log1.info('截图保存成功') except BaseException: log1.error('截图失败', exc_info=1)
def config_read(self, section, key=None, url=None): """从配置文件中读取""" try: # key是url,拼接url返回 if key == 'url': config_url = config.get(section, key) url = config_url+url log1.info('请求的url:%s' % url) return url # 读取section下所有key elif key is None: config_get = config.options(section) log1.info('读取%s下%s=%s' % (section, key, config_get)) return config_get else: # 读取section下key的值 config_get = config.get(section, key) log1.info('读取%s下所有key:%s' % (section, config_get)) return config_get except configparser.NoSectionError: log1.error('section is not in config', exc_info=1) except configparser.NoOptionError: log1.error('key is not in config', exc_info=1)
import getcwd from TestSuites.testHome import TestHome from TestSuites.testLogin import TestLogin from Common.log import log1 if __name__ == "__main__": suite = unittest.TestSuite() suite.addTest(TestHome('test_select_selenium')) suite.addTest(TestHome('test_switch_login')) suite.addTest(TestLogin('test_login1')) suite.addTest(TestLogin('test_login2')) suite.addTest(TestLogin('test_login3')) suite.addTest(TestLogin('test_login4')) log1.info('加载测试用例') path = getcwd.get_cwd() file_path = os.path.join(path, 'Report/xxxUi自动化测试报告.html') try: fp = open(file_path, 'wb') runner = HTMLTestRunnerCN.HTMLTestReportCN(stream=fp, title='xxxUi自动化测试报告', description='报告描述', tester='测试者') runner.run(suite) log1.info('test end') fp.close() log1.info('测试报告生成成功') except BaseException: log1.error("测试报告生成失败", exc_info=1) # sent_mail()
from Common.log import log1 try: log1.info('开始测试') r = 10/0 log1.info('result:',r) except ZeroDivisionError as f: log1.error('test',exc_info=1) log1.info('end')
import os import unittest import HTMLTestRunnerCN import getcwd from Common.log import log1 from TestCase.testPost import TestPost from TestCase.testGet import TestGet if __name__ == "__main__": suite = unittest.TestSuite() suite.addTest(TestPost('test_post_one')) suite.addTest(TestPost('test_post_two')) suite.addTest(TestGet('test_get_one')) log1.info('加载测试用例') path = getcwd.get_cwd() file_path = os.path.join(path, 'report/xxx接口自动化测试报告.html') try: fp = open(file_path, 'wb') runner = HTMLTestRunnerCN.HTMLTestReportCN(stream=fp, title='xxx接口自动化测试报告', description='报告中描述部分', tester='测试者') runner.run(suite) log1.info('test end') fp.close() log1.info('测试报告生成成功') except BaseException: log1.error('测试报告生成失败', exc_info=1) # send_mail()
from Common.log import log1 try: log1.info("开始测试") r = 10/0 log1.info("resuit:",r) except ZeroDivisionError as e : log1.error("报错信息:",exc_info = 1) log1.info('end')