├── .gitattributes ├── .gitignore ├── Page ├── BasePage.py ├── PageObject │ ├── ContactPage.py │ ├── HomePage.py │ ├── LoginPage.py │ ├── SendMailPage.py │ └── __init__.py └── __init__.py ├── README.md ├── RunTestCase.py ├── TestCases ├── __init__.py ├── conftest.py ├── test_contactCase.py ├── test_loginCase.py └── test_sendMailCase.py ├── config ├── __init__.py ├── conf.py └── config.ini ├── conftest.py ├── data ├── __init__.py ├── attachment ├── contact_data.py ├── login_data.py ├── send_mail_data.py └── tcData.xlsx ├── pytest.ini ├── report ├── testReport18_19_10.html └── testReport22_52_18.html ├── requirements.txt └── util ├── __init__.py ├── clipboard.py ├── keyboard.py ├── parseConFile.py ├── parseExcelFile.py └── sendMailForReprot.py /.gitattributes: -------------------------------------------------------------------------------- 1 | *.py linguist-language=python 2 | *.html linguist-language=python 3 | *.css linguist-language=python 4 | *.xlsx linguist-language=python 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ##ignore these files## 2 | assets 3 | .pytest_cache 4 | .idea 5 | *.log 6 | venv -------------------------------------------------------------------------------- /Page/BasePage.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/20 8:45 4 | @Auth : linux超 5 | @File : BasePage.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | import time 11 | from selenium.webdriver.support.wait import WebDriverWait as WD 12 | from selenium.webdriver.support import expected_conditions as ec 13 | from selenium.webdriver.common.by import By 14 | from selenium.common.exceptions import ( 15 | TimeoutException, 16 | NoAlertPresentException, 17 | ) 18 | 19 | from util.clipboard import ClipBoard 20 | from util.keyboard import KeyBoard 21 | from util.parseConFile import ParseConFile 22 | from util.parseExcelFile import ParseExcel 23 | 24 | 25 | class BasePage(object): 26 | """结合显示等待封装一些selenium内置方法""" 27 | cf = ParseConFile() 28 | excel = ParseExcel() 29 | 30 | def __init__(self, driver, timeout=30): 31 | self.byDic = { 32 | 'id': By.ID, 33 | 'name': By.NAME, 34 | 'class_name': By.CLASS_NAME, 35 | 'xpath': By.XPATH, 36 | 'link_text': By.LINK_TEXT 37 | } 38 | self.driver = driver 39 | self.outTime = timeout 40 | 41 | def find_element(self, by, locator): 42 | """ 43 | find alone element 44 | :param by: eg: id, name, xpath, css..... 45 | :param locator: id, name, xpath for str 46 | :return: element object 47 | """ 48 | try: 49 | print('[Info:Starting find the element "{}" by "{}"!]'.format(locator, by)) 50 | element = WD(self.driver, self.outTime).until(lambda x: x.find_element(by, locator)) 51 | except TimeoutException as t: 52 | print('error: found "{}" timeout!'.format(locator), t) 53 | else: 54 | return element 55 | 56 | def find_elements(self, by, locator): 57 | """ 58 | find group elements 59 | :param by: eg: id, name, xpath, css..... 60 | :param locator: eg: id, name, xpath for str 61 | :return: elements object 62 | """ 63 | try: 64 | print('[Info:start find the elements "{}" by "{}"!]'.format(locator, by)) 65 | elements = WD(self.driver, self.outTime).until(lambda x: x.find_elements(by, locator)) 66 | except TimeoutException as t: 67 | print('error: found "{}" timeout!'.format(locator), t) 68 | else: 69 | return elements 70 | 71 | def is_element_exist(self, by, locator): 72 | """ 73 | assert element if exist 74 | :param by: eg: id, name, xpath, css..... 75 | :param locator: eg: id, name, xpath for str 76 | :return: if element return True else return false 77 | """ 78 | if by.lower() in self.byDic: 79 | try: 80 | WD(self.driver, self.outTime). \ 81 | until(ec.visibility_of_element_located((self.byDic[by], locator))) 82 | except TimeoutException: 83 | print('Error: element "{}" not exist'.format(locator)) 84 | return False 85 | return True 86 | else: 87 | print('the "{}" error!'.format(by)) 88 | 89 | def is_click(self, by, locator): 90 | if by.lower() in self.byDic: 91 | try: 92 | element = WD(self.driver, self.outTime). \ 93 | until(ec.element_to_be_clickable((self.byDic[by], locator))) 94 | except TimeoutException: 95 | print("元素不可以点击") 96 | else: 97 | return element 98 | else: 99 | print('the "{}" error!'.format(by)) 100 | 101 | def is_alert(self): 102 | """ 103 | assert alert if exsit 104 | :return: alert obj 105 | """ 106 | try: 107 | re = WD(self.driver, self.outTime).until(ec.alert_is_present()) 108 | except (TimeoutException, NoAlertPresentException): 109 | print("error:no found alert") 110 | else: 111 | return re 112 | 113 | def switch_to_frame(self, by, locator): 114 | """判断frame是否存在,存在就跳到frame""" 115 | print('info:switching to iframe "{}"'.format(locator)) 116 | if by.lower() in self.byDic: 117 | try: 118 | WD(self.driver, self.outTime). \ 119 | until(ec.frame_to_be_available_and_switch_to_it((self.byDic[by], locator))) 120 | except TimeoutException as t: 121 | print('error: found "{}" timeout!切换frame失败'.format(locator), t) 122 | else: 123 | print('the "{}" error!'.format(by)) 124 | 125 | def switch_to_default_frame(self): 126 | """返回默认的frame""" 127 | print('info:switch back to default iframe') 128 | try: 129 | self.driver.switch_to.default_content() 130 | except Exception as e: 131 | print(e) 132 | 133 | def get_alert_text(self): 134 | """获取alert的提示信息""" 135 | alert = self.is_alert() 136 | if alert: 137 | return alert.text 138 | else: 139 | return None 140 | 141 | def get_element_text(self, by, locator, name=None): 142 | """获取某一个元素的text信息""" 143 | try: 144 | element = self.find_element(by, locator) 145 | if name: 146 | return element.get_attribute(name) 147 | else: 148 | return element.text 149 | except AttributeError: 150 | print('get "{}" text failed return None'.format(locator)) 151 | 152 | def load_url(self, url): 153 | """加载url""" 154 | print('info: string upload url "{}"'.format(url)) 155 | self.driver.get(url) 156 | 157 | def get_source(self): 158 | """获取页面源码""" 159 | return self.driver.page_source 160 | 161 | def send_keys(self, by, locator, value=''): 162 | """写数据""" 163 | print('info:input "{}"'.format(value)) 164 | try: 165 | element = self.find_element(by, locator) 166 | element.send_keys(value) 167 | except AttributeError as e: 168 | print(e) 169 | 170 | def clear(self, by, locator): 171 | """清理数据""" 172 | print('info:clearing value') 173 | try: 174 | element = self.find_element(by, locator) 175 | element.clear() 176 | except AttributeError as e: 177 | print(e) 178 | 179 | def click(self, by, locator): 180 | """点击某个元素""" 181 | print('info:click "{}"'.format(locator)) 182 | element = self.is_click(by, locator) 183 | if element: 184 | element.click() 185 | else: 186 | print('the "{}" unclickable!') 187 | 188 | @staticmethod 189 | def sleep(num=0): 190 | """强制等待""" 191 | print('info:sleep "{}" minutes'.format(num)) 192 | time.sleep(num) 193 | 194 | def ctrl_v(self, value): 195 | """ctrl + V 粘贴""" 196 | print('info:pasting "{}"'.format(value)) 197 | ClipBoard.set_text(value) 198 | self.sleep(3) 199 | KeyBoard.two_keys('ctrl', 'v') 200 | 201 | @staticmethod 202 | def enter_key(): 203 | """enter 回车键""" 204 | print('info:keydown enter') 205 | KeyBoard.one_key('enter') 206 | 207 | def wait_element_to_be_located(self, by, locator): 208 | """显示等待某个元素出现,且可见""" 209 | print('info:waiting "{}" to be located'.format(locator)) 210 | try: 211 | return WD(self.driver, self.outTime).until(ec.presence_of_element_located((self.byDic[by], locator))) 212 | except TimeoutException as t: 213 | print('error: found "{}" timeout!'.format(locator), t) 214 | 215 | def get_page_source(self): 216 | return self.get_source() 217 | 218 | 219 | if __name__ == "__main__": 220 | pass 221 | -------------------------------------------------------------------------------- /Page/PageObject/ContactPage.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/20 12:29 4 | @Auth : linux超 5 | @File : ContactPage.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | from Page.BasePage import BasePage 11 | from util.parseConFile import ParseConFile 12 | 13 | 14 | class ContactPage(BasePage): 15 | # 配置文件读取元素 16 | do_conf = ParseConFile() 17 | # 新键联系人按钮 18 | new_contact_btn = do_conf.get_locators_or_account('ContactPageElements', 'new_contact') 19 | # 姓名输入框 20 | name = do_conf.get_locators_or_account('ContactPageElements', 'name') 21 | # 电子邮箱输入框 22 | mail = do_conf.get_locators_or_account('ContactPageElements', 'mail') 23 | # 标记为星级 24 | star = do_conf.get_locators_or_account('ContactPageElements', 'star') 25 | # 电话号码输入框 26 | phone = do_conf.get_locators_or_account('ContactPageElements', 'phone') 27 | # 备注输入框 28 | comment = do_conf.get_locators_or_account('ContactPageElements', 'comment') 29 | # 确定按钮 30 | commit = do_conf.get_locators_or_account('ContactPageElements', 'commit') 31 | # 添加失败的提示信息 32 | error_tip = do_conf.get_locators_or_account('ContactPageElements', 'tooltip') 33 | 34 | def add_contact(self, name, mail, star, phone, comment): 35 | """添加联系人""" 36 | self.click_new_contact_btn() 37 | self.input_name(name) 38 | self.input_mail(mail) 39 | if star == '1': 40 | self.select_str() 41 | self.input_phone(phone) 42 | self.input_comment(comment) 43 | self.click_commit_btn() 44 | 45 | def click_new_contact_btn(self): 46 | return self.click(*ContactPage.new_contact_btn) 47 | 48 | def input_name(self, name): 49 | return self.send_keys(*ContactPage.name, name) 50 | 51 | def input_mail(self, mail): 52 | return self.send_keys(*ContactPage.mail, mail) 53 | 54 | def select_str(self): 55 | return self.click(*ContactPage.star) 56 | 57 | def input_phone(self, phone): 58 | return self.send_keys(*ContactPage.phone, phone) 59 | 60 | def input_comment(self, comment): 61 | return self.send_keys(*ContactPage.comment, comment) 62 | 63 | def click_commit_btn(self): 64 | return self.click(*ContactPage.commit) 65 | 66 | def get_error_text(self): 67 | return self.get_element_text(*ContactPage.error_tip) 68 | 69 | 70 | if __name__ == '__main__': 71 | pass 72 | -------------------------------------------------------------------------------- /Page/PageObject/HomePage.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/20 12:28 4 | @Auth : linux超 5 | @File : HomePage.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | from Page.BasePage import BasePage 11 | from util.parseConFile import ParseConFile 12 | 13 | 14 | class HomePage(BasePage): 15 | # 配置文件读取元素 16 | do_conf = ParseConFile() 17 | # 首页 18 | homePage = do_conf.get_locators_or_account('HomePageElements', 'homePage') 19 | # 通讯录 20 | mailList = do_conf.get_locators_or_account('HomePageElements', 'mailList') 21 | # 应用中心 22 | applicationCenter = do_conf.get_locators_or_account('HomePageElements', 'applicationCenter') 23 | # 收件箱 24 | inBox = do_conf.get_locators_or_account('HomePageElements', 'inBox') 25 | 26 | def select_menu(self, menu='mailList'): 27 | if menu == "mailList": 28 | self.click_address_list_menu() 29 | elif menu == 'homePage': 30 | self.click_home_page_menu() 31 | elif menu == 'applicationCenter': 32 | self.click_application_center_menu() 33 | elif menu == 'inBox': 34 | self.click_in_box_menu() 35 | else: 36 | raise ValueError( 37 | '''菜单选择错误! 38 | homePage->首页 39 | mailList->通讯录 40 | applicationCenter->应用中心 41 | inBox->收件箱''' 42 | ) 43 | 44 | def click_home_page_menu(self): 45 | return self.click(*HomePage.homePage) 46 | 47 | def click_address_list_menu(self): 48 | return self.click(*HomePage.mailList) 49 | 50 | def click_application_center_menu(self): 51 | return self.click(*HomePage.applicationCenter) 52 | 53 | def click_in_box_menu(self): 54 | return self.click(*HomePage.inBox) 55 | 56 | 57 | if __name__ == '__main__': 58 | pass 59 | -------------------------------------------------------------------------------- /Page/PageObject/LoginPage.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/20 12:28 4 | @Auth : linux超 5 | @File : LoginPage.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | from Page.BasePage import BasePage 11 | from util.parseConFile import ParseConFile 12 | 13 | 14 | class LoginPage(BasePage): 15 | # 配置文件读取元素 16 | do_conf = ParseConFile() 17 | # 选择密码登录的按钮 18 | password_login_btn = do_conf.get_locators_or_account('LoginPageElements', 'password_login_btn') 19 | # 登录框外的iframe 20 | frame = do_conf.get_locators_or_account('LoginPageElements', 'frame') 21 | # 用户名输入框 22 | username = do_conf.get_locators_or_account('LoginPageElements', 'username') 23 | # 密码输入框 24 | password = do_conf.get_locators_or_account('LoginPageElements', 'password') 25 | # 登录按钮 26 | loginBtn = do_conf.get_locators_or_account('LoginPageElements', 'loginBtn') 27 | # 登录失败的提示信息 28 | error_head = do_conf.get_locators_or_account('LoginPageElements', 'errorHead') 29 | # 登录成功后的用户显示元素 30 | account = do_conf.get_locators_or_account('HomePageElements', 'account') 31 | 32 | def login(self, username, password): 33 | """登录流程""" 34 | self.open_url() 35 | self.click_password_login_btn() 36 | self.switch_login_frame() 37 | self.input_username(username) 38 | self.input_password(password) 39 | self.click_login_btn() 40 | 41 | def open_url(self): 42 | return self.load_url('https://mail.126.com') 43 | 44 | def click_password_login_btn(self): 45 | return self.click(*LoginPage.password_login_btn) 46 | 47 | def switch_login_frame(self): 48 | return self.switch_to_frame(*LoginPage.frame) 49 | 50 | def clear_username(self): 51 | return self.clear(*LoginPage.username) 52 | 53 | def input_username(self, username): 54 | self.clear_username() 55 | return self.send_keys(*LoginPage.username, username) 56 | 57 | def clear_password(self): 58 | return self.clear(*LoginPage.password) 59 | 60 | def input_password(self, password): 61 | self.clear_password() 62 | return self.send_keys(*LoginPage.password, password) 63 | 64 | def click_login_btn(self): 65 | return self.click(*LoginPage.loginBtn) 66 | 67 | def switch_default_frame(self): 68 | return self.switch_to_default_frame() 69 | 70 | def get_error_text(self): 71 | return self.get_element_text(*LoginPage.error_head) 72 | 73 | def get_login_success_account(self): 74 | return self.get_element_text(*LoginPage.account) 75 | 76 | 77 | if __name__ == "__main__": 78 | pass 79 | -------------------------------------------------------------------------------- /Page/PageObject/SendMailPage.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/20 9:16 4 | @Auth : linux超 5 | @File : SendMailPage.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | from Page.BasePage import BasePage 11 | from util.parseConFile import ParseConFile 12 | 13 | 14 | class SendMailPage(BasePage): 15 | # 配置文件读取元素 16 | do_conf = ParseConFile() 17 | # 写信按钮 18 | writeMail = do_conf.get_locators_or_account('SendMailPageElements', 'writeMail') 19 | # 收件人输入框 20 | addressee = do_conf.get_locators_or_account('SendMailPageElements', 'addressee') 21 | # 邮件主题 22 | subject = do_conf.get_locators_or_account('SendMailPageElements', 'subject') 23 | # 上传附件 24 | uploadAttachment = do_conf.get_locators_or_account('SendMailPageElements', 'uploadAttachment') 25 | # 正文外的iframe 26 | iframe = do_conf.get_locators_or_account('SendMailPageElements', 'iframe') 27 | # 正文 28 | text = do_conf.get_locators_or_account('SendMailPageElements', 'text') 29 | # 发送按钮 30 | sendBtn = do_conf.get_locators_or_account('SendMailPageElements', 'sendBtn') 31 | # 发送成功的提示信息 32 | send_success = do_conf.get_locators_or_account('SendMailPageElements', 'send_success') 33 | # 收件人为空的提示信息 34 | error_info_address_is_none = do_conf.get_locators_or_account('SendMailPageElements', 'error_info_address_is_none') 35 | # 收件人格式或者主题为空的提示信息 36 | error_info_popup_window = do_conf.get_locators_or_account('SendMailPageElements', 'error_info_popup_window') 37 | 38 | def send_mail(self, address, subject, text, pfa): 39 | self.click_write_mail_btn() 40 | self.input_address(address) 41 | self.input_subject(subject) 42 | if pfa: 43 | self.upload_file(pfa) 44 | self.switch_frame() 45 | self.input_main_text(text) 46 | self.switch_default_frame() 47 | self.click_send_btn() 48 | 49 | def click_write_mail_btn(self): 50 | return self.click(*SendMailPage.writeMail) 51 | 52 | def input_address(self, address): 53 | return self.send_keys(*SendMailPage.addressee, address) 54 | 55 | def input_subject(self, subject): 56 | return self.send_keys(*SendMailPage.subject, subject) 57 | 58 | def upload_file(self, pfa): 59 | return self.send_keys(*SendMailPage.uploadAttachment, pfa) 60 | 61 | def switch_frame(self): 62 | return self.switch_to_frame(*SendMailPage.iframe) 63 | 64 | def input_main_text(self, text): 65 | return self.send_keys(*SendMailPage.text, text) 66 | 67 | def switch_default_frame(self): 68 | return self.switch_to_default_frame() 69 | 70 | def click_send_btn(self): 71 | return self.click(*SendMailPage.sendBtn) 72 | 73 | def wait_success_info_element_located(self): 74 | return self.wait_element_to_be_located(*SendMailPage.send_success) 75 | 76 | def get_error_address_is_none(self): 77 | element = self.driver.find_element(*SendMailPage.error_info_address_is_none) 78 | return element.text 79 | 80 | def get_error_popup_window(self): 81 | return self.get_element_text(*SendMailPage.error_info_popup_window) 82 | 83 | 84 | if __name__ == '__main__': 85 | pass 86 | -------------------------------------------------------------------------------- /Page/PageObject/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/12 12:28 4 | @Auth : linux超 5 | @File : __init__.py.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ -------------------------------------------------------------------------------- /Page/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/12 9:17 4 | @Auth : linux超 5 | @File : __init__.py.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PytestAutoTestFrameWork 2 | Pytest框架实战项目实例 3 | 帮助: 4 | 通过此项目可以学到以下内容 5 | 1.命令行如何运行测试用例 6 | 2.pytest如何收集测试用例 7 | 3.如何使用fixture 8 | 4.如何使用conftest.py文件 9 | 5.如何使用pytest-html插件生成测试报告 10 | 6.PO设计模式思想是什么样的 11 | 7.selenium 部分API的使用和如何进行简单的二次封装 12 | 9.pytest框架如何参数化测试用例 13 | 10.如何发送测试报告邮件 14 | 11.如何使用代码的方式执行测试用例或整个项目 15 | 12.测试用例编写逻辑 16 | 说明: 17 | 1.本项目测试地址为126邮箱 18 | https://mail.126.com 19 | 2.请先简单了解126邮箱的各个功能 20 | 3.本人博客地址:https://www.cnblogs.com/linuxchao 21 | 环境需求: 22 | 1.windows 7 以上版本 23 | 2.需安装python 3.以上版本 24 | 3.selenium 2 以上版本 25 | 4.需安装pytest框架 26 | 5.需安装pytest -html插件 27 | 6.需安装火狐或谷歌浏览器及对应驱动 28 | 7.需对发送测试报告邮件的邮箱正确配置(可在我博客中找到相关配置文章) 29 | 8.需要安装pypiwin32库 30 | 9.需要安装openpyxl数据处理库 31 | 10.需要安装yagmail库发送测试报告 32 | 运行项目: 33 | 1.下载项目到本地 34 | 2.打开cmd切换到项目根目录 35 | 3.输入python RunTestCase.py运行项目 36 | 4.或者直接通过pytest --html=’report.html‘ 运行(这种方式不会自动发送测试邮件) 37 | 5.或者在pycharm中打开项目,直接运行RunTestCase.py文件 38 | 用例说明: 39 | 请下载原代码自己查看用例具体测试了哪些功能 40 | 41 | 修改说明: 42 | .修改了所有代码的编写规范,使其更加符合PEP8 43 | .由于126邮箱升级,因为修改了部分用例的逻辑,更加容易理解 44 | .所有的用例按照不同错误提示信息进行了分组 45 | .修改了测试数据的存储方式,由excel改为了使用py文件直接存储 46 | .添加了环境管理文件requirement.txt文件,方便clone本想的人能够顺利运行项目 47 | .注意!注意!注意! 48 | .测试数据中的126邮箱的用户名和密码是我本人的邮箱, 请不要做危害国家和我个人的事情,不要浪费我一翻辛苦,非常感谢! 49 | 当然,你最好改为你自己的邮箱,否则你运行项目的时候我会平凡收到邮件 50 | .由于126邮箱有很多限制,坑比较多,比如你登录次数过多时会有验证码的提示(验证码比较难处理, 我未做处理),所以如果 51 | 有验证码提示了后面用例步骤就没办法执行了, 即使清楚cookies下次还是会提示,很烦, 所以我整个项目是多次打开浏览器的 52 | 能够防止一下这种情况 53 | .还有一个限制是在发送邮件的时候,如果发送过多次数,也会有验证,我就不细说了,请自行体会吧 54 | .最后说一句,clone本项目后,最好为本项目建立的空白的虚拟环境, 然后在虚拟环境中使用pip install -r requirements.txt自动安装依赖 55 | -------------------------------------------------------------------------------- /RunTestCase.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/15 16:14 4 | @Auth : linux超 5 | @File : RunTestCase.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | import sys 11 | import pytest 12 | 13 | from config.conf import ROOT_DIR, HTML_NAME 14 | 15 | # from util.sendMailForReprot import SendMailWithReport 16 | 17 | 18 | def main(): 19 | if ROOT_DIR not in sys.path: 20 | sys.path.append(ROOT_DIR) 21 | # 执行用例 22 | args = ['--reruns', '1', '--html=' + './report/' + HTML_NAME] 23 | pytest.main(args) 24 | # 发送邮件 这里我屏蔽了 自己添加自己的邮箱信息 25 | # SendMailWithReport.send_mail( 26 | # smtpServer, fromUser, fromPassWord, 27 | # toUser, subject, contents, 28 | # htmlName) 29 | 30 | 31 | if __name__ == '__main__': 32 | main() 33 | # 我的部分博客地址 34 | # https://www.cnblogs.com/linuxchao/p/linuxchao-pytest-report.html 35 | # https://www.cnblogs.com/linuxchao/p/linuxchao-pytest-configfile.html 36 | # https://www.cnblogs.com/linuxchao/p/linuxchao-pytest-conftest.html 37 | -------------------------------------------------------------------------------- /TestCases/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/12 14:09 4 | @Auth : linux超 5 | @File : __init__.py.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ -------------------------------------------------------------------------------- /TestCases/conftest.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/20 15:10 4 | @Auth : linux超 5 | @File : conftest.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | import pytest 11 | 12 | from Page.PageObject.LoginPage import LoginPage 13 | from Page.PageObject.HomePage import HomePage 14 | from Page.PageObject.ContactPage import ContactPage 15 | from Page.PageObject.SendMailPage import SendMailPage 16 | from util.parseConFile import ParseConFile 17 | 18 | 19 | do_conf = ParseConFile() 20 | # 从配置文件中获取正确的用户名和密码 21 | userName = do_conf.get_locators_or_account('126LoginAccount', 'username') 22 | passWord = do_conf.get_locators_or_account('126LoginAccount', 'password') 23 | 24 | 25 | # @pytest.fixture(scope='function') 26 | # def login(driver): 27 | # """除登录用例,每一个用例的前置条件""" 28 | # print('------------staring login------------') 29 | # login_action = LoginPage(driver, 30) 30 | # login_action.login(userName, passWord) 31 | # yield 32 | # print('------------end login------------') 33 | # driver.delete_all_cookies() 34 | 35 | @pytest.fixture(scope='class') 36 | def ini_pages(driver): 37 | login_page = LoginPage(driver) 38 | home_page = HomePage(driver) 39 | contact_page = ContactPage(driver) 40 | send_mail_page = SendMailPage(driver) 41 | yield driver, login_page, home_page, contact_page, send_mail_page 42 | 43 | 44 | @pytest.fixture(scope='function') 45 | def open_url(ini_pages): 46 | driver = ini_pages[0] 47 | login_page = ini_pages[1] 48 | # login_page.open_url() 49 | yield login_page 50 | driver.delete_all_cookies() 51 | 52 | 53 | @pytest.fixture(scope='class') 54 | def login(ini_pages): 55 | driver, login_page, home_page, contact_page, send_mail_page = ini_pages 56 | # login_page.open_url() 57 | login_page.login(userName, passWord) 58 | login_page.switch_default_frame() 59 | yield login_page, home_page, contact_page, send_mail_page 60 | driver.delete_all_cookies() 61 | 62 | 63 | @pytest.fixture(scope='function') 64 | def refresh_page(ini_pages): 65 | driver = ini_pages[0] 66 | yield 67 | driver.refresh() 68 | -------------------------------------------------------------------------------- /TestCases/test_contactCase.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/20 16:15 4 | @Auth : linux超 5 | @File : test_contactCase.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | import pytest 11 | 12 | from data.contact_data import ContactData 13 | 14 | 15 | @pytest.mark.conatctTest 16 | class TestAddContact(object): 17 | """添加联系人""" 18 | contact_data = ContactData 19 | success_data = contact_data.add_contact_success 20 | fail_data = contact_data.add_contact_fail 21 | 22 | @pytest.mark.parametrize('name, mail, star, phone, comment, expect', success_data) 23 | def test_add_contact_success(self, login, refresh_page, name, mail, star, phone, comment, expect): 24 | """测试添加联系人""" 25 | home_page = login[1] 26 | contact_page = login[2] 27 | home_page.select_menu(menu="mailList") 28 | contact_page.add_contact(name, mail, star, phone, comment) 29 | actual = contact_page.get_source() 30 | assert expect in actual, "添加联系人成功, 断言失败" 31 | 32 | @pytest.mark.parametrize('name, mail, star, phone, comment, expect', fail_data) 33 | def test_add_contact_fail(self, login, refresh_page, name, mail, star, phone, comment, expect): 34 | home_page = login[1] 35 | contact_page = login[2] 36 | home_page.select_menu(menu="mailList") 37 | contact_page.add_contact(name, mail, star, phone, comment) 38 | actual = contact_page.get_error_text() 39 | assert actual == expect, "添加联系人失败, 断言失败" 40 | 41 | 42 | if __name__ == '__main__': 43 | pytest.main(['-v', 'test_contactCase.py']) 44 | -------------------------------------------------------------------------------- /TestCases/test_loginCase.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/20 14:10 4 | @Auth : linux超 5 | @File : test_loginCase.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | import pytest 11 | 12 | from data.login_data import LoginData 13 | 14 | 15 | @pytest.mark.loginTest 16 | class TestLogin(object): 17 | """登录""" 18 | login_data = LoginData 19 | 20 | @pytest.mark.parametrize('username, password, expect', login_data.login_success_data) 21 | def test_login(self, open_url, username, password, expect): 22 | login_page = open_url 23 | login_page.login(username, password) 24 | login_page.switch_default_frame() 25 | actual = login_page.get_login_success_account() 26 | assert expect in actual, "登录成功, 断言失败" 27 | 28 | @pytest.mark.parametrize('username, password, expect', login_data.login_fail_data) 29 | def test_fail(self, open_url, username, password, expect): 30 | login_page = open_url 31 | login_page.login(username, password) 32 | actual = login_page.get_error_text() 33 | assert actual == expect, "登录失败, 断言失败" 34 | 35 | 36 | if __name__ == "__main__": 37 | pytest.main(['-v', 'test_loginCase.py']) 38 | -------------------------------------------------------------------------------- /TestCases/test_sendMailCase.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/20 10:04 4 | @Auth : linux超 5 | @File : test_sendMailCase.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | import pytest 11 | 12 | from data.send_mail_data import SendMailData 13 | 14 | 15 | @pytest.mark.sendMailTest 16 | class TestSendMail(object): 17 | """发送邮件""" 18 | mail_data = SendMailData 19 | send_success_data = mail_data.send_mail_success 20 | send_fail_address_is_none_data = mail_data.send_fail_address_is_none 21 | send_fail_address_is_invalid_data = mail_data.send_fail_address_is_invalid_data 22 | send_fail_subject_is_none_data = mail_data.send_fail_subject_is_none_data 23 | 24 | @pytest.mark.sendmail 25 | @pytest.mark.parametrize('address, subject, text, pfa, expect', send_success_data) 26 | def test_send_mail_success(self, login, refresh_page, address, subject, text, pfa, expect): 27 | home_page = login[1] 28 | send_mail_page = login[3] 29 | home_page.select_menu(menu="homePage") 30 | send_mail_page.send_mail(address, subject, text, pfa) 31 | send_mail_page.wait_success_info_element_located() 32 | actual = send_mail_page.get_source() 33 | assert expect in actual, "发送邮件成功, 断言失败" 34 | 35 | @pytest.mark.parametrize('address, subject, text, pfa, expect', send_fail_address_is_none_data) 36 | def test_send_fail_address_is_none(self, login, refresh_page, address, subject, text, pfa, expect): 37 | home_page = login[1] 38 | send_mail_page = login[3] 39 | home_page.select_menu(menu="homePage") 40 | send_mail_page.send_mail(address, subject, text, pfa) 41 | actual = send_mail_page.get_error_address_is_none() 42 | assert expect == actual, "发送邮件失败, 断言失败" 43 | 44 | @pytest.mark.parametrize('address, subject, text, pfa, expect', send_fail_address_is_invalid_data) 45 | def test_send_fail_address_invalid(self, login, refresh_page, address, subject, text, pfa, expect): 46 | home_page = login[1] 47 | send_mail_page = login[3] 48 | home_page.select_menu(menu="homePage") 49 | send_mail_page.send_mail(address, subject, text, pfa) 50 | actual = send_mail_page.get_error_popup_window() 51 | assert expect == actual, "发送邮件失败, 断言失败" 52 | 53 | @pytest.mark.parametrize('address, subject, text, pfa, expect', send_fail_subject_is_none_data) 54 | def test_send_fail_subject_is_none_data(self, login, refresh_page, address, subject, text, pfa, expect): 55 | home_page = login[1] 56 | send_mail_page = login[3] 57 | home_page.select_menu(menu="homePage") 58 | send_mail_page.send_mail(address, subject, text, pfa) 59 | actual = send_mail_page.get_error_popup_window() 60 | assert expect == actual, "发送邮件失败, 断言失败" 61 | 62 | 63 | if __name__ == '__main__': 64 | pytest.main(['-v', 'test_sendMailCase.py']) 65 | -------------------------------------------------------------------------------- /config/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/15 16:50 4 | @Auth : linux超 5 | @File : __init__.py.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ -------------------------------------------------------------------------------- /config/conf.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/20 16:50 4 | @Auth : linux超 5 | @File : conf.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | from datetime import datetime 11 | import os 12 | 13 | # 项目根目录 14 | ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 15 | # 报告目录 16 | REPORT_DIR = os.path.join(ROOT_DIR, 'report') 17 | # ui对象库config.ini文件所在目录 18 | CONF_PATH = os.path.join(ROOT_DIR, 'config', 'config.ini') 19 | # 测试数据所在目录 20 | DATA_Path = os.path.join(ROOT_DIR, 'data', 'tcData.xlsx') 21 | # 当前时间 22 | CURRENT_TIME = datetime.now().strftime('%H_%M_%S') 23 | 24 | # 邮件配置信息 25 | # 邮件服务器 26 | SMTP_SERVER = 'smtp.qq.com' 27 | # 发送者 28 | FROM_USER = '账号@qq.com' 29 | # 发送者密码 30 | FROM_PASSWORD = 'mhxvqpewblldbjhf' 31 | # 接收者 32 | TO_USER = ['账号@qq.com'] # 可以同时发送给多人,追加到列表中 33 | # 邮件标题 34 | SUBJECT = 'xx项目自动化测试报告' 35 | # 邮件正文 36 | CONTENTS = '测试报告正文' 37 | # 报告名称 38 | HTML_NAME = 'testReport{}.html'.format(CURRENT_TIME) 39 | print(HTML_NAME) -------------------------------------------------------------------------------- /config/config.ini: -------------------------------------------------------------------------------- 1 | [126LoginAccount];126邮箱正确的登录账号和密码;运行用例时请更换正确的用户名和密码 2 | username=linuxxiaochao 3 | password=xiaochao11520 4 | [HomePageElements];126邮箱首页菜单栏元素 5 | account=xpath->//span[@id="spnUid"] 6 | homePage=id->_mail_tabitem_0_3text 7 | mailList=id->_mail_tabitem_1_4text 8 | applicationCenter=id->_mail_tabitem_2_5text 9 | inBox=id->_mail_tabitem_3_6text 10 | [LoginPageElements];126邮箱登录页面的元素 11 | password_login_btn=xpath->//a[@id="switchAccountLogin"] 12 | frame=xpath->//div[@id="loginDiv"]/iframe 13 | username=xpath->//input[@name="email"] 14 | password=xpath->//input[@name="password"] 15 | loginBtn=xpath->//a[@id="dologin"] 16 | errorHead=xpath->//div[@class="ferrorhead"] 17 | [ContactPageElements];126邮箱添加联系人页面元素 18 | new_contact=xpath->//span[text()="新建联系人"] 19 | name=id->input_N 20 | mail=xpath->//div[@id="iaddress_MAIL_wrap"]//input[@class="nui-ipt-input"] 21 | star=xpath->//span[@class="nui-chk-text"]/preceding-sibling::span/b 22 | phone=xpath->//div[@id='iaddress_TEL_wrap']//input[@class='nui-ipt-input'] 23 | comment=id->input_DETAIL 24 | commit=xpath->//span[text()='确 定'] 25 | tooltip=xpath->//span[text()='请正确填写邮件地址。'] 26 | [SendMailPageElements];126邮箱发送邮件页面元素 27 | writeMail=xpath->//div[@id='dvNavContainer']//span[text()='写 信'] 28 | addressee=xpath->//input[@aria-label='收件人地址输入框,请输入邮件地址,多人时地址请以分号隔开'] 29 | subject=xpath->//input[contains(@id, '_subjectInput')] 30 | iframe=xpath->//iframe[@class='APP-editor-iframe'] 31 | text=xpath->/html/body 32 | sendBtn=xpath->//header//span[text()='发送'] 33 | send_success=xpath->//*[text()='发送成功'] 34 | uploadAttachment=xpath->//div[contains(@id,'_attachBrowserCloud')]/preceding-sibling::div[contains(@id, '_attachBrowser')]/input 35 | delete=xpath->//a[text()='删除'] 36 | error_info_address_is_none=xpath->//div[@id='zoomMonitorDiv']/following-sibling::div/span[@class='nui-tips-text'] 37 | error_info_popup_window=xpath->//div[@class='nui-msgbox-title'] -------------------------------------------------------------------------------- /conftest.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/12 14:10 4 | @Auth : linux超 5 | @File : conftest.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | import pytest 11 | from selenium import webdriver 12 | from py._xmlgen import html 13 | 14 | _driver = None 15 | 16 | 17 | # 测试失败时添加截图和测试用例描述(用例的注释信息) 18 | 19 | @pytest.mark.hookwrapper 20 | def pytest_runtest_makereport(item): 21 | """ 22 | 当测试失败的时候,自动截图,展示到html报告中 23 | :param item: 24 | """ 25 | pytest_html = item.config.pluginmanager.getplugin('html') 26 | outcome = yield 27 | report = outcome.get_result() 28 | extra = getattr(report, 'extra', []) 29 | 30 | if report.when == 'call' or report.when == "setup": 31 | xfail = hasattr(report, 'wasxfail') 32 | if (report.skipped and xfail) or (report.failed and not xfail): 33 | file_name = report.nodeid.replace("::", "_") + ".png" 34 | screen_img = _capture_screenshot() 35 | if file_name: 36 | html = '
Report generated on 19-Apr-2019 at 22:56:22 by pytest-html v1.20.0
402 |JAVA_HOME | 406 |C:\Program Files\Java\jdk1.8.0_181 |
Packages | 409 |{'pytest': '4.4.1', 'py': '1.6.0', 'pluggy': '0.9.0'} |
Platform | 412 |Windows-10-10.0.17134-SP0 |
Plugins | 415 |{'rerunfailures': '7.0', 'metadata': '1.8.0', 'html': '1.20.0'} |
Python | 418 |3.6.4 |
13 tests ran in 241.68 seconds.
421 |(Un)check the boxes to filter the results.
13 passed, 0 skipped, 0 failed, 0 errors, 0 expected failures, 0 unexpected passes, 0 rerun 422 |Result | 427 |Description | 428 |Test | 429 |Duration | 430 |Links |
---|---|---|---|---|
No results found. Try to check the filters | ||||
Passed | 436 |测试添加联系人 | 437 |TestCases/test_contactCase.py::test_NewContact[linux1-1@qq.com--13691579841-test1] | 438 |8.15 | 439 ||
442 | ---------------------------- Captured stdout setup ----------------------------- ------------open browser------------ 443 | ------------staring login------------ 444 | -------staring login------- 445 | info: string upload url "https://mail.126.com" 446 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 447 | info:clearing value 448 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 449 | info:input "linuxxiaochao" 450 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 451 | info:clearing value 452 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 453 | info:input "xiaochao11520" 454 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 455 | info:click "//a[@id="dologin"]" 456 | info:switch back to default iframe 457 | ---------end login--------- 458 | ----------------------------- Captured stdout call ----------------------------- info:click "_mail_tabitem_1_4text" 459 | --------string add contact-------- 460 | info:click "//span[text()="新建联系人"]" 461 | info:input "linux1" 462 | [Info:Starting find the element "input_N" by "id"!] 463 | info:input "1@qq.com" 464 | [Info:Starting find the element "//div[@id="iaddress_MAIL_wrap"]//input[@class="nui-ipt-input"]" by "xpath"!] 465 | info:input "13691579841" 466 | [Info:Starting find the element "//div[@id='iaddress_TEL_wrap']//input[@class='nui-ipt-input']" by "xpath"!] 467 | info:input "test1" 468 | [Info:Starting find the element "input_DETAIL" by "id"!] 469 | info:click "//span[text()='确 定']" 470 | --------end add contact-------- 471 | info:sleep "5" minutes 472 | info:assert "linux1" in page source 473 | | ||||
Passed | 477 |测试添加联系人 | 478 |TestCases/test_contactCase.py::test_NewContact[linux2-281754042@.com--13691579842-test1] | 479 |7.40 | 480 ||
483 | ---------------------------- Captured stdout setup ----------------------------- ------------staring login------------ 484 | -------staring login------- 485 | info: string upload url "https://mail.126.com" 486 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 487 | info:clearing value 488 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 489 | info:input "linuxxiaochao" 490 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 491 | info:clearing value 492 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 493 | info:input "xiaochao11520" 494 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 495 | info:click "//a[@id="dologin"]" 496 | info:switch back to default iframe 497 | ---------end login--------- 498 | ----------------------------- Captured stdout call ----------------------------- info:click "_mail_tabitem_1_4text" 499 | --------string add contact-------- 500 | info:click "//span[text()="新建联系人"]" 501 | info:input "linux2" 502 | [Info:Starting find the element "input_N" by "id"!] 503 | info:input "281754042@.com" 504 | [Info:Starting find the element "//div[@id="iaddress_MAIL_wrap"]//input[@class="nui-ipt-input"]" by "xpath"!] 505 | info:input "13691579842" 506 | [Info:Starting find the element "//div[@id='iaddress_TEL_wrap']//input[@class='nui-ipt-input']" by "xpath"!] 507 | info:input "test1" 508 | [Info:Starting find the element "input_DETAIL" by "id"!] 509 | info:click "//span[text()='确 定']" 510 | --------end add contact-------- 511 | info:sleep "5" minutes 512 | [Info:Starting find the element "//span[text()='请正确填写邮件地址。']" by "xpath"!] 513 | info: assert "请正确填写邮件地址。"=="请正确填写邮件地址。" 514 | | ||||
Passed | 518 |测试添加联系人 | 519 |TestCases/test_contactCase.py::test_NewContact[linux3-043@qq.cn--13691579843-test1] | 520 |7.35 | 521 ||
524 | ---------------------------- Captured stdout setup ----------------------------- ------------staring login------------ 525 | -------staring login------- 526 | info: string upload url "https://mail.126.com" 527 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 528 | info:clearing value 529 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 530 | info:input "linuxxiaochao" 531 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 532 | info:clearing value 533 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 534 | info:input "xiaochao11520" 535 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 536 | info:click "//a[@id="dologin"]" 537 | info:switch back to default iframe 538 | ---------end login--------- 539 | ----------------------------- Captured stdout call ----------------------------- info:click "_mail_tabitem_1_4text" 540 | --------string add contact-------- 541 | info:click "//span[text()="新建联系人"]" 542 | info:input "linux3" 543 | [Info:Starting find the element "input_N" by "id"!] 544 | info:input "043@qq.cn" 545 | [Info:Starting find the element "//div[@id="iaddress_MAIL_wrap"]//input[@class="nui-ipt-input"]" by "xpath"!] 546 | info:input "13691579843" 547 | [Info:Starting find the element "//div[@id='iaddress_TEL_wrap']//input[@class='nui-ipt-input']" by "xpath"!] 548 | info:input "test1" 549 | [Info:Starting find the element "input_DETAIL" by "id"!] 550 | info:click "//span[text()='确 定']" 551 | --------end add contact-------- 552 | info:sleep "5" minutes 553 | info:assert "linux3" in page source 554 | | ||||
Passed | 558 |测试添加联系人 | 559 |TestCases/test_contactCase.py::test_NewContact[linux4---13691579843-test1] | 560 |7.74 | 561 ||
564 | ---------------------------- Captured stdout setup ----------------------------- ------------staring login------------ 565 | -------staring login------- 566 | info: string upload url "https://mail.126.com" 567 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 568 | info:clearing value 569 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 570 | info:input "linuxxiaochao" 571 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 572 | info:clearing value 573 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 574 | info:input "xiaochao11520" 575 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 576 | info:click "//a[@id="dologin"]" 577 | info:switch back to default iframe 578 | ---------end login--------- 579 | ----------------------------- Captured stdout call ----------------------------- info:click "_mail_tabitem_1_4text" 580 | --------string add contact-------- 581 | info:click "//span[text()="新建联系人"]" 582 | info:input "linux4" 583 | [Info:Starting find the element "input_N" by "id"!] 584 | info:input "" 585 | [Info:Starting find the element "//div[@id="iaddress_MAIL_wrap"]//input[@class="nui-ipt-input"]" by "xpath"!] 586 | info:input "13691579843" 587 | [Info:Starting find the element "//div[@id='iaddress_TEL_wrap']//input[@class='nui-ipt-input']" by "xpath"!] 588 | info:input "test1" 589 | [Info:Starting find the element "input_DETAIL" by "id"!] 590 | info:click "//span[text()='确 定']" 591 | --------end add contact-------- 592 | info:sleep "5" minutes 593 | [Info:Starting find the element "//span[text()='请正确填写邮件地址。']" by "xpath"!] 594 | info: assert "请正确填写邮件地址。"=="请正确填写邮件地址。" 595 | | ||||
Passed | 599 |测试添加联系人 | 600 |TestCases/test_contactCase.py::test_NewContact[linux3-281754043@qq--13691579843-test1] | 601 |7.55 | 602 ||
605 | ---------------------------- Captured stdout setup ----------------------------- ------------staring login------------ 606 | -------staring login------- 607 | info: string upload url "https://mail.126.com" 608 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 609 | info:clearing value 610 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 611 | info:input "linuxxiaochao" 612 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 613 | info:clearing value 614 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 615 | info:input "xiaochao11520" 616 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 617 | info:click "//a[@id="dologin"]" 618 | info:switch back to default iframe 619 | ---------end login--------- 620 | ----------------------------- Captured stdout call ----------------------------- info:click "_mail_tabitem_1_4text" 621 | --------string add contact-------- 622 | info:click "//span[text()="新建联系人"]" 623 | info:input "linux3" 624 | [Info:Starting find the element "input_N" by "id"!] 625 | info:input "281754043@qq" 626 | [Info:Starting find the element "//div[@id="iaddress_MAIL_wrap"]//input[@class="nui-ipt-input"]" by "xpath"!] 627 | info:input "13691579843" 628 | [Info:Starting find the element "//div[@id='iaddress_TEL_wrap']//input[@class='nui-ipt-input']" by "xpath"!] 629 | info:input "test1" 630 | [Info:Starting find the element "input_DETAIL" by "id"!] 631 | info:click "//span[text()='确 定']" 632 | --------end add contact-------- 633 | info:sleep "5" minutes 634 | [Info:Starting find the element "//span[text()='请正确填写邮件地址。']" by "xpath"!] 635 | info: assert "请正确填写邮件地址。"=="请正确填写邮件地址。" 636 | | ||||
Passed | 640 |测试添加联系人 | 641 |TestCases/test_contactCase.py::test_NewContact[linux3-@qq.com--13691579843-test1] | 642 |7.57 | 643 ||
646 | ---------------------------- Captured stdout setup ----------------------------- ------------staring login------------ 647 | -------staring login------- 648 | info: string upload url "https://mail.126.com" 649 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 650 | info:clearing value 651 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 652 | info:input "linuxxiaochao" 653 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 654 | info:clearing value 655 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 656 | info:input "xiaochao11520" 657 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 658 | info:click "//a[@id="dologin"]" 659 | info:switch back to default iframe 660 | ---------end login--------- 661 | ----------------------------- Captured stdout call ----------------------------- info:click "_mail_tabitem_1_4text" 662 | --------string add contact-------- 663 | info:click "//span[text()="新建联系人"]" 664 | info:input "linux3" 665 | [Info:Starting find the element "input_N" by "id"!] 666 | info:input "@qq.com" 667 | [Info:Starting find the element "//div[@id="iaddress_MAIL_wrap"]//input[@class="nui-ipt-input"]" by "xpath"!] 668 | info:input "13691579843" 669 | [Info:Starting find the element "//div[@id='iaddress_TEL_wrap']//input[@class='nui-ipt-input']" by "xpath"!] 670 | info:input "test1" 671 | [Info:Starting find the element "input_DETAIL" by "id"!] 672 | info:click "//span[text()='确 定']" 673 | --------end add contact-------- 674 | info:sleep "5" minutes 675 | [Info:Starting find the element "//span[text()='请正确填写邮件地址。']" by "xpath"!] 676 | info: assert "请正确填写邮件地址。"=="请正确填写邮件地址。" 677 | | ||||
Passed | 681 |测试登录 | 682 |TestCases/test_loginCase.py::test_login[linux-] | 683 |19.87 | 684 ||
687 | ---------------------------- Captured stdout setup ----------------------------- ------------open browser------------ 688 | ----------------------------- Captured stdout call ----------------------------- -------staring login------- 689 | info: string upload url "https://mail.126.com" 690 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 691 | info:clearing value 692 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 693 | info:input "linux" 694 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 695 | info:clearing value 696 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 697 | info:input "" 698 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 699 | info:click "//a[@id="dologin"]" 700 | info:switch back to default iframe 701 | ---------end login--------- 702 | info:sleep "5" minutes 703 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 704 | [Info:Starting find the element "//div[@class="ferrorhead"]" by "xpath"!] 705 | info:switch back to default iframe 706 | info: assert "请输入密码" == "请输入密码" 707 | | ||||
Passed | 711 |测试登录 | 712 |TestCases/test_loginCase.py::test_login[-chao] | 713 |6.11 | 714 ||
717 | ----------------------------- Captured stdout call ----------------------------- -------staring login------- 718 | info: string upload url "https://mail.126.com" 719 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 720 | info:clearing value 721 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 722 | info:input "" 723 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 724 | info:clearing value 725 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 726 | info:input "chao" 727 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 728 | info:click "//a[@id="dologin"]" 729 | info:switch back to default iframe 730 | ---------end login--------- 731 | info:sleep "5" minutes 732 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 733 | [Info:Starting find the element "//div[@class="ferrorhead"]" by "xpath"!] 734 | info:switch back to default iframe 735 | info: assert "请输入帐号" == "请输入帐号" 736 | | ||||
Passed | 740 |测试登录 | 741 |TestCases/test_loginCase.py::test_login[l-chao] | 742 |6.15 | 743 ||
746 | ----------------------------- Captured stdout call ----------------------------- -------staring login------- 747 | info: string upload url "https://mail.126.com" 748 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 749 | info:clearing value 750 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 751 | info:input "l" 752 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 753 | info:clearing value 754 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 755 | info:input "chao" 756 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 757 | info:click "//a[@id="dologin"]" 758 | info:switch back to default iframe 759 | ---------end login--------- 760 | info:sleep "5" minutes 761 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 762 | [Info:Starting find the element "//div[@class="ferrorhead"]" by "xpath"!] 763 | info:switch back to default iframe 764 | info: assert "帐号或密码错误" == "帐号或密码错误" 765 | | ||||
Passed | 769 |测试登录 | 770 |TestCases/test_loginCase.py::test_login[-] | 771 |6.14 | 772 ||
775 | ----------------------------- Captured stdout call ----------------------------- -------staring login------- 776 | info: string upload url "https://mail.126.com" 777 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 778 | info:clearing value 779 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 780 | info:input "" 781 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 782 | info:clearing value 783 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 784 | info:input "" 785 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 786 | info:click "//a[@id="dologin"]" 787 | info:switch back to default iframe 788 | ---------end login--------- 789 | info:sleep "5" minutes 790 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 791 | [Info:Starting find the element "//div[@class="ferrorhead"]" by "xpath"!] 792 | info:switch back to default iframe 793 | info: assert "请输入帐号" == "请输入帐号" 794 | | ||||
Passed | 798 |测试发送邮件,包括带附件的邮件 | 799 |TestCases/test_sendMailCase.py::test_sendMail[281754043@qq.com-pytest测试主题1-pytest 测试邮件, 请勿回复!-0-] | 800 |8.34 | 801 ||
804 | ---------------------------- Captured stdout setup ----------------------------- ------------open browser------------ 805 | ------------staring login------------ 806 | -------staring login------- 807 | info: string upload url "https://mail.126.com" 808 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 809 | info:clearing value 810 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 811 | info:input "linuxxiaochao" 812 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 813 | info:clearing value 814 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 815 | info:input "xiaochao11520" 816 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 817 | info:click "//a[@id="dologin"]" 818 | info:switch back to default iframe 819 | ---------end login--------- 820 | ----------------------------- Captured stdout call ----------------------------- ------------string send mail--------------------- 821 | info:click "//div[@id='dvNavContainer']//span[text()='写 信']" 822 | info:input "281754043@qq.com" 823 | [Info:Starting find the element "//input[@aria-label='收件人地址输入框,请输入邮件地址,多人时地址请以分号隔开']" by "xpath"!] 824 | info:input "pytest测试主题1" 825 | [Info:Starting find the element "//input[contains(@id, '_subjectInput')]" by "xpath"!] 826 | info:switching to iframe "//iframe[@class="APP-editor-iframe"]" 827 | info:input "pytest 测试邮件, 请勿回复!" 828 | [Info:Starting find the element "/html/body" by "xpath"!] 829 | info:switch back to default iframe 830 | info:click "//header//span[text()='发送']" 831 | ------------end send mail--------------------- 832 | info:sleep "5" minutes 833 | | ||||
Passed | 837 |测试发送邮件,包括带附件的邮件 | 838 |TestCases/test_sendMailCase.py::test_sendMail[281754043@qq.com-pytest测试主题2-pytest 测试邮件, 请勿回复!-1-D:\KeyWordDriverTestFrameWork\geckodriver.log] | 839 |43.19 | 840 ||
843 | ---------------------------- Captured stdout setup ----------------------------- ------------staring login------------ 844 | -------staring login------- 845 | info: string upload url "https://mail.126.com" 846 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 847 | info:clearing value 848 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 849 | info:input "linuxxiaochao" 850 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 851 | info:clearing value 852 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 853 | info:input "xiaochao11520" 854 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 855 | info:click "//a[@id="dologin"]" 856 | info:switch back to default iframe 857 | ---------end login--------- 858 | ----------------------------- Captured stdout call ----------------------------- ------------string send mail--------------------- 859 | info:click "//div[@id='dvNavContainer']//span[text()='写 信']" 860 | info:input "281754043@qq.com" 861 | [Info:Starting find the element "//input[@aria-label='收件人地址输入框,请输入邮件地址,多人时地址请以分号隔开']" by "xpath"!] 862 | info:input "pytest测试主题2" 863 | [Info:Starting find the element "//input[contains(@id, '_subjectInput')]" by "xpath"!] 864 | info:switching to iframe "//iframe[@class="APP-editor-iframe"]" 865 | info:input "pytest 测试邮件, 请勿回复!" 866 | [Info:Starting find the element "/html/body" by "xpath"!] 867 | info:switch back to default iframe 868 | info:click "//div[@title="点击添加附件"]" 869 | info:pasting "D:\KeyWordDriverTestFrameWork\geckodriver.log" 870 | info:sleep "3" minutes 871 | info:keydown enter 872 | info:waiting "//a[text()='删除']" to be located 873 | error: found "//a[text()='删除']" timeout! Message: 874 | 875 | info:click "//header//span[text()='发送']" 876 | ------------end send mail--------------------- 877 | info:sleep "5" minutes 878 | | ||||
Passed | 882 |测试发送邮件,包括带附件的邮件 | 883 |TestCases/test_sendMailCase.py::test_sendMail[281754043@qq.com-pytest测试主题3-pytest 测试邮件, 请勿回复!-1-D:\KeyWordDriverTestFrameWork\geckodriver.log] | 884 |42.66 | 885 ||
888 | ---------------------------- Captured stdout setup ----------------------------- ------------staring login------------ 889 | -------staring login------- 890 | info: string upload url "https://mail.126.com" 891 | info:switching to iframe "//div[@id="loginDiv"]/iframe" 892 | info:clearing value 893 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 894 | info:input "linuxxiaochao" 895 | [Info:Starting find the element "//input[@name="email"]" by "xpath"!] 896 | info:clearing value 897 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 898 | info:input "xiaochao11520" 899 | [Info:Starting find the element "//input[@name="password"]" by "xpath"!] 900 | info:click "//a[@id="dologin"]" 901 | info:switch back to default iframe 902 | ---------end login--------- 903 | ----------------------------- Captured stdout call ----------------------------- ------------string send mail--------------------- 904 | info:click "//div[@id='dvNavContainer']//span[text()='写 信']" 905 | info:input "281754043@qq.com" 906 | [Info:Starting find the element "//input[@aria-label='收件人地址输入框,请输入邮件地址,多人时地址请以分号隔开']" by "xpath"!] 907 | info:input "pytest测试主题3" 908 | [Info:Starting find the element "//input[contains(@id, '_subjectInput')]" by "xpath"!] 909 | info:switching to iframe "//iframe[@class="APP-editor-iframe"]" 910 | info:input "pytest 测试邮件, 请勿回复!" 911 | [Info:Starting find the element "/html/body" by "xpath"!] 912 | info:switch back to default iframe 913 | info:click "//div[@title="点击添加附件"]" 914 | info:pasting "D:\KeyWordDriverTestFrameWork\geckodriver.log" 915 | info:sleep "3" minutes 916 | info:keydown enter 917 | info:waiting "//a[text()='删除']" to be located 918 | error: found "//a[text()='删除']" timeout! Message: 919 | 920 | info:click "//header//span[text()='发送']" 921 | ------------end send mail--------------------- 922 | info:sleep "5" minutes 923 | |