├── util ├── __init__.py ├── clipboard.py ├── sendMailForReprot.py ├── parseConFile.py ├── keyboard.py └── parseExcelFile.py ├── data ├── attachment ├── tcData.xlsx ├── __init__.py ├── contact_data.py ├── login_data.py └── send_mail_data.py ├── .gitignore ├── .gitattributes ├── pytest.ini ├── Page ├── __init__.py ├── PageObject │ ├── __init__.py │ ├── HomePage.py │ ├── ContactPage.py │ ├── LoginPage.py │ └── SendMailPage.py └── BasePage.py ├── TestCases ├── __init__.py ├── test_loginCase.py ├── test_contactCase.py ├── conftest.py └── test_sendMailCase.py ├── config ├── __init__.py ├── conf.py └── config.ini ├── requirements.txt ├── RunTestCase.py ├── README.md ├── conftest.py └── report └── testReport22_52_18.html /util/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/attachment: -------------------------------------------------------------------------------- 1 | 本文件作为测试发送带附件的邮件 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ##ignore these files## 2 | assets 3 | .pytest_cache 4 | .idea 5 | *.log 6 | venv -------------------------------------------------------------------------------- /data/tcData.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/13691579846/PytestAutoTestFrameWork/HEAD/data/tcData.xlsx -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.py linguist-language=python 2 | *.html linguist-language=python 3 | *.css linguist-language=python 4 | *.xlsx linguist-language=python 5 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | addopts=-vqs 3 | testpaths=./TestCases 4 | markers= 5 | loginTest: Run login test cases 6 | contactTest: Run add contact test cases 7 | sendMailTest: Run send mail test cases -------------------------------------------------------------------------------- /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 | """ -------------------------------------------------------------------------------- /data/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/22 17:14 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/__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 | """ -------------------------------------------------------------------------------- /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 | """ -------------------------------------------------------------------------------- /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 | """ -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | atomicwrites==1.3.0 2 | attrs==19.1.0 3 | colorama==0.4.1 4 | et-xmlfile==1.0.1 5 | importlib-metadata==0.19 6 | jdcal==1.4.1 7 | more-itertools==7.2.0 8 | openpyxl==2.6.2 9 | packaging==19.1 10 | pluggy==0.12.0 11 | py==1.8.0 12 | pyparsing==2.4.2 13 | pypiwin32==223 14 | pytest==5.0.1 15 | pytest-html==1.21.1 16 | pytest-metadata==1.8.0 17 | pytest-rerunfailures==7.0 18 | pywin32==224 19 | selenium==3.141.0 20 | six==1.12.0 21 | urllib3==1.25.3 22 | wcwidth==0.1.7 23 | yagmail==0.11.220 24 | zipp==0.5.2 25 | -------------------------------------------------------------------------------- /util/clipboard.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/15 12:04 4 | @Auth : linux超 5 | @File : clipboard.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | import win32con 11 | import win32clipboard as wc 12 | 13 | 14 | class ClipBoard(object): 15 | """设置剪切板内容和获取剪切板内容""" 16 | 17 | @staticmethod 18 | def get_text(): 19 | """获取剪切板的内容""" 20 | wc.OpenClipboard() 21 | value = wc.GetClipboardData(win32con.CF_TEXT) 22 | wc.CloseClipboard() 23 | return value 24 | 25 | @staticmethod 26 | def set_text(value): 27 | """设置剪切板的内容""" 28 | wc.OpenClipboard() 29 | wc.EmptyClipboard() 30 | wc.SetClipboardData(win32con.CF_UNICODETEXT, value) 31 | wc.CloseClipboard() 32 | 33 | 34 | if __name__ == '__main__': 35 | pass 36 | -------------------------------------------------------------------------------- /data/contact_data.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/8/4 14:03 4 | @Auth : linux超 5 | @File : contact_data.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | @QQ : 28174043@qq.com 9 | @GROUP: 878565760 10 | ------------------------------------ 11 | """ 12 | 13 | 14 | class ContactData(object): 15 | """添加联系人测试数据""" 16 | 17 | add_contact_success = [ 18 | ( 19 | "linux1", 20 | "281754041@qq.com", 21 | "1", 22 | "13691579841", 23 | "添加联系人1", 24 | "281754041@qq.com" 25 | ) 26 | ] 27 | add_contact_fail = [ 28 | ( 29 | "linux2", 30 | "@qq.com", 31 | "0", 32 | "13691579842", 33 | "添加联系人2", 34 | "请正确填写邮件地址。" 35 | ) 36 | ] 37 | 38 | 39 | if __name__ == '__main__': 40 | pass 41 | -------------------------------------------------------------------------------- /data/login_data.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/8/4 13:05 4 | @Auth : linux超 5 | @File : login_data.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | @QQ : 28174043@qq.com 9 | @GROUP: 878565760 10 | ------------------------------------ 11 | """ 12 | 13 | 14 | class LoginData(object): 15 | """用户登录测试数据""" 16 | 17 | login_success_data = [ 18 | ( 19 | "linuxxiaochao", 20 | "xiaochao11520", 21 | "linuxxiaochao@126.com" 22 | ) 23 | ] 24 | 25 | login_fail_data = [ 26 | ( 27 | "linuxxiaochao", 28 | "", 29 | "请输入密码" 30 | ), 31 | ( 32 | "", 33 | "xiaochao11520", 34 | "请输入帐号" 35 | ), 36 | ( 37 | "linux", 38 | "xiaochao", 39 | "帐号或密码错误" 40 | ) 41 | ] 42 | 43 | 44 | if __name__ == '__main__': 45 | pass 46 | -------------------------------------------------------------------------------- /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) -------------------------------------------------------------------------------- /util/sendMailForReprot.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/16 15:38 4 | @Auth : linux超 5 | @File : sendMailForReprot.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | 11 | import yagmail 12 | 13 | 14 | class SendMailWithReport(object): 15 | """发送邮件""" 16 | 17 | @staticmethod 18 | def send_mail(smtp_server, from_user, from_pass_word, to_user, subject, contents, file_name): 19 | # 初始化服务器等信息 20 | yag = yagmail.SMTP(from_user, from_pass_word, smtp_server) 21 | # 发送邮件 22 | yag.send(to_user, subject, contents, file_name) 23 | 24 | 25 | if __name__ == '__main__': 26 | SendMailWithReport.send_mail('smtp.qq.com', 27 | '账号@qq.com', 28 | 'mhxvqpewblldbjhf', 29 | '账号@qq.com', 30 | 'python自动化测试', 31 | '邮件正文', 32 | '17_12_07.html') 33 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /util/parseConFile.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/18 10:54 4 | @Auth : linux超 5 | @File : parseConFile.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | import configparser 11 | from config.conf import CONF_PATH 12 | 13 | 14 | class ParseConFile(object): 15 | 16 | def __init__(self): 17 | self.file = CONF_PATH 18 | self.conf = configparser.ConfigParser() 19 | self.conf.read(self.file, encoding='utf-8') 20 | 21 | def get_all_sections(self): 22 | """获取所有的section,返回一个列表""" 23 | return self.conf.sections() 24 | 25 | def get_all_options(self, section): 26 | """获取指定section下所有的option, 返回列表""" 27 | return self.conf.options(section) 28 | 29 | def get_locators_or_account(self, section, option): 30 | """获取指定section, 指定option对应的数据, 返回元祖和字符串""" 31 | try: 32 | locator = self.conf.get(section, option) 33 | if ('->' in locator): 34 | locator = tuple(locator.split('->')) 35 | return locator 36 | except configparser.NoOptionError as e: 37 | print('error:', e) 38 | return 'error: No option "{}" in section: "{}"'.format(option, section) 39 | 40 | def get_option_value(self, section): 41 | """获取指定section下所有的option和对应的数据,返回字典""" 42 | value = dict(self.conf.items(section)) 43 | return value 44 | 45 | 46 | if __name__ == '__main__': 47 | pass 48 | -------------------------------------------------------------------------------- /util/keyboard.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/15 12:05 4 | @Auth : linux超 5 | @File : keyboard.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | 11 | # 模拟按键 12 | import win32api 13 | import win32con 14 | import time 15 | 16 | 17 | class KeyBoard(object): 18 | """模拟按键""" 19 | # 键盘码 20 | vk_code = { 21 | 'enter': 0x0D, 22 | 'tab': 0x09, 23 | 'ctrl': 0x11, 24 | 'v': 0x56, 25 | 'a': 0x41, 26 | 'x': 0x58 27 | } 28 | 29 | @staticmethod 30 | def key_down(key_name): 31 | """按下键""" 32 | key_name = key_name.lower() 33 | try: 34 | win32api.keybd_event(KeyBoard.vk_code[key_name], 0, 0, 0) 35 | except Exception as e: 36 | print('未按下enter键') 37 | print(e) 38 | 39 | @staticmethod 40 | def key_up(key_name): 41 | """抬起键""" 42 | key_name = key_name.lower() 43 | win32api.keybd_event(KeyBoard.vk_code[key_name], 0, win32con.KEYEVENTF_KEYUP, 0) 44 | 45 | @staticmethod 46 | def one_key(key): 47 | """模拟单个按键""" 48 | key = key.lower() 49 | KeyBoard.key_down(key) 50 | time.sleep(2) 51 | KeyBoard.key_up(key) 52 | 53 | @staticmethod 54 | def two_keys(key1, key2): 55 | """模拟组合按键""" 56 | key1 = key1.lower() 57 | key2 = key2.lower() 58 | KeyBoard.key_down(key1) 59 | KeyBoard.key_down(key2) 60 | KeyBoard.key_up(key1) 61 | KeyBoard.key_up(key2) 62 | 63 | 64 | if __name__ == '__main__': 65 | pass 66 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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'] -------------------------------------------------------------------------------- /data/send_mail_data.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/8/4 14:44 4 | @Auth : linux超 5 | @File : send_mail_data.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | @QQ : 28174043@qq.com 9 | @GROUP: 878565760 10 | ------------------------------------ 11 | """ 12 | 13 | 14 | class SendMailData(object): 15 | """发送邮件测试数据""" 16 | 17 | send_mail_success = [ 18 | ( 19 | "281754043@qq.com", 20 | "测试发送普通测试邮件", 21 | "测试发送普通测试邮件", 22 | "", 23 | "发送成功" 24 | ), 25 | ( 26 | "281754043@qq.com", 27 | "测试发送带附件的邮件", 28 | "测试发送带附件的邮件", 29 | "D:\\PytestAutoTestFrameWork\\data\\attachment", 30 | "发送成功" 31 | ), 32 | ( 33 | "281754043@qq.com", 34 | "", 35 | "测试发送带附件的邮件且主题为空", 36 | "D:\\PytestAutoTestFrameWork\\data\\attachment", 37 | "发送成功" 38 | ) 39 | ] 40 | 41 | send_fail_address_is_none = [ 42 | ( 43 | "", 44 | "测试收件人地址为空", 45 | "测试收件人地址为空", 46 | "D:\\PytestAutoTestFrameWork\\data\\attachment", 47 | "请填写收件人地址后再发送" 48 | ) 49 | ] 50 | 51 | send_fail_subject_is_none_data = [ 52 | ( 53 | "281754043@qq.com", 54 | "", 55 | "测试邮件主题为空:不能添加附件", 56 | "", 57 | "确定真的不需要写主题吗?" 58 | ) 59 | ] 60 | 61 | send_fail_address_is_invalid_data = [ 62 | ( 63 | "281754043", 64 | "测试收件人格式不正确", 65 | "测试收件人格式不正确", 66 | "D:\\PytestAutoTestFrameWork\\data\\attachment", 67 | "以下邮箱地址无效,将无法成功收到邮件" 68 | ) 69 | ] 70 | 71 | 72 | if __name__ == '__main__': 73 | pass 74 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /util/parseExcelFile.py: -------------------------------------------------------------------------------- 1 | """ 2 | ------------------------------------ 3 | @Time : 2019/4/22 16:12 4 | @Auth : linux超 5 | @File : parseExcelFile.py 6 | @IDE : PyCharm 7 | @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 | ------------------------------------ 9 | """ 10 | from openpyxl import load_workbook 11 | from config.conf import DATA_Path 12 | 13 | 14 | class ParseExcel(object): 15 | 16 | def __init__(self): 17 | self.wk = load_workbook(DATA_Path) 18 | self.excelFile = DATA_Path 19 | 20 | def get_sheet_by_name(self, sheet_name): 21 | """获取sheet对象""" 22 | sheet = self.wk[sheet_name] 23 | return sheet 24 | 25 | def get_row_num(self, sheet): 26 | """获取有效数据的最大行号""" 27 | return sheet.max_row 28 | 29 | def get_cols_num(self, sheet): 30 | """获取有效数据的最大列号""" 31 | return sheet.max_column 32 | 33 | def get_row_values(self, sheet, row_num): 34 | """获取某一行的数据""" 35 | max_cols_num = self.get_cols_num(sheet) 36 | row_values = [] 37 | for colsNum in range(1, max_cols_num + 1): 38 | value = sheet.cell(row_num, colsNum).value 39 | if value is None: 40 | value = '' 41 | row_values.append(value) 42 | return tuple(row_values) 43 | 44 | def get_column_values(self, sheet, column_num): 45 | """获取某一列的数据""" 46 | max_row_num = self.get_row_num(sheet) 47 | column_values = [] 48 | for rowNum in range(2, max_row_num + 1): 49 | value = sheet.cell(rowNum, column_num).value 50 | if value is None: 51 | value = '' 52 | column_values.append(value) 53 | return tuple(column_values) 54 | 55 | def get_value_of_cell(self, sheet, row_num, column_num): 56 | """获取某一个单元格的数据""" 57 | value = sheet.cell(row_num, column_num).value 58 | if value is None: 59 | value = '' 60 | return value 61 | 62 | def get_all_values_of_sheet(self, sheet): 63 | """获取某一个sheet页的所有测试数据,返回一个元祖组成的列表""" 64 | max_row_num = self.get_row_num(sheet) 65 | column_num = self.get_cols_num(sheet) 66 | all_values = [] 67 | for row in range(2, max_row_num + 1): 68 | row_values = [] 69 | for column in range(1, column_num + 1): 70 | value = sheet.cell(row, column).value 71 | if value is None: 72 | value = '' 73 | row_values.append(value) 74 | all_values.append(tuple(row_values)) 75 | return all_values 76 | 77 | 78 | if __name__ == '__main__': 79 | pass 80 | -------------------------------------------------------------------------------- /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 | | ||||