Pytest UI自动化测试实战实例_ui自动化 账号密码验证码的测试用例

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

8.通过yagmail第三方库,编写发送报告接口,测试工作完成后自动发送测试报告

代码分析目录结构

 
 1 PytestAutoTestFrameWork
 2 |—|config
 3 |——|__init__.py
 4 |——|conf.py
 5 |——|config.ini
 6 |—|data
 7 |——|__init__.py
 8 |——|tcData.xlsx
 9 |—Page
10 |——|PageObject.py
11 |———|__init__.py
12 |———|ContactPage.py
13 |———|HomePage.py
14 |———|LoginPage.py
15 |———|SendMailPage.py
16 |——|__init__.py
17 |——|BasePage.py
18 |—|report
19 |—|TestCases
20 |——|__init__.py
21 |——|conftest.py
22 |——|test_confactCase.py
23 |——|test_loginCase.py
24 |——|test_sendMailCase.py
25 |—|util
26 |——|__init__.py
27 |——|clipboard.py
28 |——|keyboard.py
29 |——|parseConFile.py
30 |——|parseExcelFile.py
31 |——|sendMailForReport.py
32 |—|conftest.py
33 |—|pytest.ini
34 |—|RunTestCase.py
代码实现

通过126邮箱测试范围分析,我们需要通过设计剪切板,模拟键盘完成附件上传操作,因此我们首先来编写这两个方法

 
 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 getText():
19         '''获取剪切板的内容'''
20         WC.OpenClipboard()
21         value = WC.GetClipboardData(win32con.CF_TEXT)
22         WC.CloseClipboard()
23         return value
24 
25     @staticmethod
26     def setText(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     from selenium import webdriver
36 
37     value = 'python'
38     driver = webdriver.Firefox()
39     driver.get('http://www.baidu.com')
40     query = driver.find_element_by_id('kw')
41     ClipBoard.setText(value)
42     clValue = ClipBoard.getText()
43     query.send_keys(clValue.decode('utf-8'))
 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 keyDown(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 keyUp(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 oneKey(key):
47         """模拟单个按键"""
48         key = key.lower()
49         KeyBoard.keyDown(key)
50         time.sleep(2)
51         KeyBoard.keyUp(key)
52 
53     @staticmethod
54     def twoKeys(key1, key2):
55         """模拟组合按键"""
56         key1 = key1.lower()
57         key2 = key2.lower()
58         KeyBoard.keyDown(key1)
59         KeyBoard.keyDown(key2)
60         KeyBoard.keyUp(key1)
61         KeyBoard.keyUp(key2)
62 
63 
64 if __name__ == '__main__':
65     from selenium import webdriver
66     driver = webdriver.Firefox()
67     driver.get('http://www.baidu.com')
68     driver.find_element_by_id('kw').send_keys('python')
69     KeyBoard.twoKeys('ctrl', 'a')
70     KeyBoard.twoKeys('ctrl', 'x')

通过测试项目设计,我们需要把测试数据存放在Excel文件中,把页面操作元素存在UI对象库中也就是一个配置文件,那么我们需要对Excel 和 ini文件解析,因此我们开始编写这两个方法,设计UI对象库和测试数据文件

 
  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 excelPath
 12 
 13 
 14 class ParseExcel(object):
 15 
 16     def __init__(self):
 17         self.wk = load_workbook(excelPath)
 18         self.excelFile = excelPath
 19 
 20     def getSheetByName(self, sheetName):
 21         """获取sheet对象"""
 22         sheet = self.wk[sheetName]
 23         return sheet
 24 
 25     def getRowNum(self, sheet):
 26         """获取有效数据的最大行号"""
 27         return sheet.max_row
 28 
 29     def getColsNum(self, sheet):
 30         """获取有效数据的最大列号"""
 31         return sheet.max_column
 32 
 33     def getRowValues(self, sheet, rowNum):
 34         """获取某一行的数据"""
 35         maxColsNum = self.getColsNum(sheet)
 36         rowValues = []
 37         for colsNum in range(1, maxColsNum + 1):
 38             value = sheet.cell(rowNum, colsNum).value
 39             if value is None:
 40                 value = ''
 41             rowValues.append(value)
 42         return tuple(rowValues)
 43 
 44     def getColumnValues(self, sheet, columnNum):
 45         """获取某一列的数据"""
 46         maxRowNum = self.getRowNum(sheet)
 47         columnValues = []
 48         for rowNum in range(2, maxRowNum + 1):
 49             value = sheet.cell(rowNum, columnNum).value
 50             if value is None:
 51                 value = ''
 52             columnValues.append(value)
 53         return tuple(columnValues)
 54 
 55     def getValueOfCell(self, sheet, rowNum, columnNum):
 56         """获取某一个单元格的数据"""
 57         value = sheet.cell(rowNum, columnNum).value
 58         if value is None:
 59             value = ''
 60         return value
 61 
 62     def getAllValuesOfSheet(self, sheet):
 63         """获取某一个sheet页的所有测试数据,返回一个元祖组成的列表"""
 64         maxRowNum = self.getRowNum(sheet)
 65         columnNum = self.getColsNum(sheet)
 66         allValues = []
 67         for row in range(2, maxRowNum + 1):
 68             rowValues = []
 69             for column in range(1, columnNum + 1):
 70                 value = sheet.cell(row, column).value
 71                 if value is None:
 72                     value = ''
 73                 rowValues.append(value)
 74             allValues.append(tuple(rowValues))
 75         return allValues
 76 
 77 
 78 if __name__ == '__main__':
 79     # excel = ParseExcel()
 80     # sheet = excel.getSheetByName('login')
 81     # print('行号:', excel.getRowNum(sheet))
 82     # print('列号:', excel.getColsNum(sheet))
 83     #
 84     # rowvalues = excel.getRowValues(sheet, 1)
 85     # columnvalues = excel.getColumnValues(sheet, 2)
 86     # valueofcell = excel.getValueOfCell(sheet, 1, 2)
 87     # allvalues = excel.getAllValuesOfSheet(sheet)
 88     #
 89     # print('第{}行数据{}'.format(1, rowvalues))
 90     # print('第{}列数据{}'.format(2, columnvalues))
 91     # print('{}{}单元格的内容{}'.format(1, 2, valueofcell))
 92     # print('login{}'.format(allvalues))
 93 
 94     excel = ParseExcel()
 95     sheet = excel.getSheetByName('mail')
 96     print('行号:', excel.getRowNum(sheet))
 97     print('列号:', excel.getColsNum(sheet))
 98 
 99     allvalues = excel.getAllValuesOfSheet(sheet)
100 
101     print('sendmail{}'.format(allvalues))
 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 configDir
12 
13 
14 class ParseConFile(object):
15 
16     def __init__(self):
17         self.file = configDir
18         self.conf = configparser.ConfigParser()
19         self.conf.read(self.file, encoding='utf-8')
20 
21     def getAllSections(self):
22         """获取所有的section,返回一个列表"""
23         return self.conf.sections()
24 
25     def getAllOptions(self, section):
26         """获取指定section下所有的option, 返回列表"""
27         return self.conf.options(section)
28 
29     def getLocatorsOrAccount(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 getOptionValue(self, section):
41         """获取指定section下所有的option和对应的数据,返回字典"""
42         value = dict(self.conf.items(section))
43         return value
44 
45 
46 if __name__ == '__main__':
47     cf = ParseConFile()
48     print(cf.getAllSections())
49     print(cf.getAllOptions('126LoginAccount'))
50     print(cf.getLocatorsOrAccount('126LoginAccount', 'username'))
51     print(cf.getOptionValue('126LoginAccount'))
1 [126LoginAccount];126邮箱正确的登录账号和密码;运行用例时请更换正确的用户名和密码
 2 username=linuxxiaochao
 3 password=xiaochao11520
 4 [HomePageElements];126邮箱首页菜单栏元素
 5 homePage=id->_mail_tabitem_0_3text
 6 mailList=id->_mail_tabitem_1_4text
 7 applicationCenter=id->_mail_tabitem_2_5text
 8 inBox=id->_mail_tabitem_3_6text
 9 [LoginPageElements];126邮箱登录页面的元素
10 frame=xpath->//div[@id="loginDiv"]/iframe
11 username=xpath->//input[@name="email"]
12 password=xpath->//input[@name="password"]
13 loginBtn=xpath->//a[@id="dologin"]
14 ferrorHead=xpath->//div[@class="ferrorhead"]
15 [ContactPageElements];126邮箱添加联系人页面元素
16 new_contact=xpath->//span[text()="新建联系人"]
17 name=id->input_N
18 mail=xpath->//div[@id="iaddress_MAIL_wrap"]//input[@class="nui-ipt-input"]
19 star=xpath->//span[@class="nui-chk-text"]/preceding-sibling::span/b
20 phone=xpath->//div[@id='iaddress_TEL_wrap']//input[@class='nui-ipt-input']
21 comment=id->input_DETAIL
22 commit=xpath->//span[text()='确 定']
23 tooltip=xpath->//span[text()='请正确填写邮件地址。']
24 [SendMailPageElements];126邮箱发送邮件页面元素
25 writeMail=xpath->//div[@id='dvNavContainer']//span[text()='写 信']
26 addressee=xpath->//input[@aria-label='收件人地址输入框,请输入邮件地址,多人时地址请以分号隔开']
27 subject=xpath->//input[contains(@id, '_subjectInput')]
28 iframe=xpath->//iframe[@class="APP-editor-iframe"]
29 text=xpath->/html/body
30 sendBtn=xpath->//header//span[text()='发送']
31 expect=xpath->//h1[contains(@id,'_succInfo')]
32 uploadAttachment=xpath->//div[@title="点击添加附件"]
33 delete=xpath->//a[text()='删除']
新建excel文件,分3个sheet,分别为:login,contact,mail #每个sheet中数据可自行填写,驱动测试用例执行不同的数据进行测试

login

contact

 mail

数据,UI对象库,解析方法都已经有了,接下来通过PageObject模式设计编写每个页面的操作及封装126邮箱的功能,以便后续设计用例调用

 
  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 import expected_conditions as EC
 12 from selenium.webdriver.support.wait import WebDriverWait as wd
 13 from selenium.webdriver.common.by import By
 14 from selenium.common.exceptions import NoSuchWindowException, TimeoutException, \
 15     NoAlertPresentException, NoSuchFrameException
 16 from selenium import webdriver
 17 
 18 from util.clipboard import ClipBoard
 19 from util.keyboard import KeyBoard
 20 from util.parseConFile import ParseConFile
 21 from util.parseExcelFile import ParseExcel
 22 
 23 
 24 class BasePage(object):
 25     """
 26     结合显示等待封装一些selenium 内置方法
 27     """
 28     cf = ParseConFile()
 29     excel = ParseExcel()
 30 
 31     def __init__(self, driver, outTime=30):
 32         self.byDic = {
 33         'id': By.ID,
 34         'name': By.NAME,
 35         'class_name': By.CLASS_NAME,
 36         'xpath': By.XPATH,
 37         'link_text': By.LINK_TEXT
 38         }
 39         self.driver = driver
 40         self.outTime = outTime
 41 
 42     def findElement(self, by, locator):
 43         """
 44         find alone element
 45         :param by: eg: id, name, xpath, css.....
 46         :param locator: id, name, xpath for str
 47         :return: element object
 48         """
 49         try:
 50             print('[Info:Starting find the element "{}" by "{}"!]'.format(locator, by))
 51             element = wd(self.driver, self.outTime).until(lambda x : x.find_element(by, locator))
 52         except TimeoutException as t:
 53             print('error: found "{}" timeout!'.format(locator), t)
 54         except NoSuchWindowException as e:
 55             print('error: no such "{}"'.format(locator), e)
 56         except Exception as e:
 57             raise e
 58         else:
 59             # print('[Info:Had found the element "{}" by "{}"!]'.format(locator, by))
 60             return element
 61 
 62     def findElements(self, by, locator):
 63         """
 64         find group elements
 65         :param by: eg: id, name, xpath, css.....
 66         :param locator: eg: id, name, xpath for str
 67         :return: elements object
 68         """
 69         try:
 70             print('[Info:start find the elements "{}" by "{}"!]'.format(locator, by))
 71             elements = wd(self.driver, self.outTime).until(lambda x : x.find_element(by, locator))
 72         except TimeoutException as t:
 73             print(t)
 74         except NoSuchWindowException as e:
 75             print(e)
 76         except Exception as e:
 77             raise e
 78         else:
 79             # print('[Info:Had found the elements "{}" by "{}"!]'.format(locator, by))
 80             return elements
 81 
 82     def isElementExsit(self, by, locator):
 83         """
 84         assert element if exist
 85         :param by: eg: id, name, xpath, css.....
 86         :param locator: eg: id, name, xpath for str
 87         :return: if element return True else return false
 88         """
 89         if by.lower() in self.byDic:
 90             try:
 91                 wd(self.driver, self.outTime).\
 92                     until(EC.visibility_of_element_located((self.byDic[by], locator)))
 93             except TimeoutException:
 94                 print('Error: element "{}" time out!'.format(locator))
 95                 return False
 96             except NoSuchWindowException:
 97                 print('Error: element "{}" not exsit!'.format(locator))
 98                 return False
 99             return True
100         else:
101             print('the "{}" error!'.format(by))
102 
103     def isClick(self, by, locator):
104         """判断是否可点击,返回元素对象"""
105         if by.lower() in self.byDic:
106             try:
107                 element = wd(self.driver, self.outTime).\
108                     until(EC.element_to_be_clickable((self.byDic[by], locator)))
109             except Exception:
110                 return False
111             return element
112         else:
113             print('the "{}" error!'.format(by))
114 
115     def isAlertAndSwitchToIt(self):
116         """
117         assert alert if exsit
118         :return: alert obj
119         """
120         try:
121             re = wd(self.driver, self.outTime).until(EC.alert_is_present())
122         except NoAlertPresentException:
123             return False
124         except Exception:
125             return False
126         return re
127 
128     def switchToFrame(self, by, locator):
129         """判断frame是否存在,存在就跳到frame"""
130         print('info:switching to iframe "{}"'.format(locator))
131         if by.lower() in self.byDic:
132             try:
133                 wd(self.driver, self.outTime).\
134                     until(EC.frame_to_be_available_and_switch_to_it((self.byDic[by], locator)))
135             except TimeoutException as t:
136                 print('error: found "{}" timeout!'.format(locator), t)
137             except NoSuchFrameException as e:
138                 print('error: no such "{}"'.format(locator), e)
139             except Exception as e:
140                 raise e
141         else:
142             print('the "{}" error!'.format(by))
143 
144     def switchToDefaultFrame(self):
145         """返回默认的frame"""
146         print('info:switch back to default iframe')
147         try:
148             self.driver.switch_to.default_content()
149         except Exception as e:
150             print(e)
151 
152     def getAlertText(self):
153         """获取alert的提示信息"""
154         if self.isAlertAndSwitchToIt():
155             alert = self.isAlertAndSwitchToIt()
156             return alert.text
157         else:
158             return None
159 
160     def getElementText(self, by, locator, name=None):
161         """获取某一个元素的text信息"""
162         try:
163             element = self.findElement(by, locator)
164             if name:
165                 return element.get_attribute(name)
166             else:
167                 return element.text
168         except:
169             print('get "{}" text failed return None'.format(locator))
170             return None
171 
172     def loadUrl(self, url):
173         """加载url"""
174         print('info: string upload url "{}"'.format(url))
175         self.driver.get(url)
176 
177     def getSource(self):
178         """获取页面源码"""
179         return self.driver.page_source
180 
181     def sendKeys(self, by, locator, value=''):
182         """写数据"""
183         print('info:input "{}"'.format(value))
184         try:
185             element = self.findElement(by, locator)
186             element.send_keys(value)
187         except AttributeError as e:
188             print(e)
189 
190     def clear(self, by, locator):
191         """清理数据"""
192         print('info:clearing value')
193         try:
194             element = self.findElement(by, locator)
195             element.clear()
196         except AttributeError as e:
197             print(e)
198 
199     def click(self, by, locator):
200         """点击某个元素"""
201         print('info:click "{}"'.format(locator))
202         element = self.isClick(by, locator)
203         if element:
204             element.click()
205         else:
206             print('the "{}" unclickable!')
207 
208     def sleep(self, num=0):
209         """强制等待"""
210         print('info:sleep "{}" minutes'.format(num))
211         time.sleep(num)
212 
213     def ctrlV(self, value):
214         """ctrl + V 粘贴"""
215         print('info:pasting "{}"'.format(value))
216         ClipBoard.setText(value)
217         self.sleep(3)
218         KeyBoard.twoKeys('ctrl', 'v')
219 
220     def enterKey(self):
221         """enter 回车键"""
222         print('info:keydown enter')
223         KeyBoard.oneKey('enter')
224 
225     def waitElementtobelocated(self, by, locator):
226         """显示等待某个元素出现,且可见"""
227         print('info:waiting "{}" to be located'.format(locator))
228         try:
229             wd(self.driver, self.outTime).until(EC.visibility_of_element_located((self.byDic[by], locator)))
230         except TimeoutException as t:
231             print('error: found "{}" timeout!'.format(locator), t)
232         except NoSuchWindowException as e:
233             print('error: no such "{}"'.format(locator), e)
234         except Exception as e:
235             raise e
236 
237     def assertValueInSource(self, value):
238         """断言某个关键字是否存在页面源码中"""
239         print('info:assert "{}" in page source'.format(value))
240         source = self.getSource()
241         assert value in source, '关键字"{}"不存在源码中!'.format(value)
242 
243     def assertStringContainsValue(self, String, value):
244         """断言某段字符串包含另一个字符串"""
245         print('info:assert "{}" contains "{}"'.format(String, value))
246         assert value in String, '"{}"不包含"{}"!'.format(String, value)
247 
248 
249     @staticmethod
250     def getSheet(sheetName):
251         """获取某个sheet页的对象"""
252         sheet = BasePage.excel.getSheetByName(sheetName)
253         return sheet
254 
255 
256 if __name__ == "__main__":
257     driver = webdriver.Firefox()
258     frame = ('xpath', '//div[@id="loginDiv"]/ifram')
259     wait = BasePage(driver)
260     driver.get('https://mail.126.com/')
261     wait.switchToFrame(*frame)
262     username = wait.findElement('xpath', '//input[@name="email"]')
263     username.send_keys('账号')
264     if wait.isElementExsit('xpath', '//input[@name="password"]'):
265         wait.findElement('xpath', '//input[@name="password"]').send_keys('xiaochao11520')
266     wait.click('xpath', '//a[@id="dologin"]')

 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 
12 
13 class HomePage(BasePage):
14     # 配置文件读取元素
15     homePage = BasePage.cf.getLocatorsOrAccount('HomePageElements', 'homePage')
16     mailList = BasePage.cf.getLocatorsOrAccount('HomePageElements', 'mailList')
17     applicationCenter = BasePage.cf.getLocatorsOrAccount('HomePageElements', 'applicationCenter')
18     inBox = BasePage.cf.getLocatorsOrAccount('HomePageElements', 'inBox')
19     '''首页菜单选项'''
20     def selectMenu(self, Menu='mailList'):
21         """邮箱首页选择菜单"""
22         if Menu == 'mailList':
23             self.click(*HomePage.mailList)
24         elif Menu == 'homePage':
25             self.click(*HomePage.homePage)
26         elif Menu == 'applicationCenter':
27             self.click(*HomePage.applicationCenter)
28         elif Menu == 'inBox':
29             self.click(*HomePage.inBox)
30         else:
31             raise ValueError('''
32             菜单选择错误!
33             homePage->首页
34             mailList->通讯录
35             applicationCenter->应用中心
36             inBox->收件箱''')
37 
38 if __name__=='__main__':
39     from selenium import webdriver
40     from Page.PageObject.LoginPage import LoginPage
41     driver = webdriver.Firefox()
42     login = LoginPage(driver)
43     login.login('账号', 'xiaochao11520')
44 
45     home = HomePage(driver)
46     home.selectMenu()
 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 
12 
13 class LoginPage(BasePage):
14 
15     # 配置文件读取元素
16     frame = BasePage.cf.getLocatorsOrAccount('LoginPageElements', 'frame')
17     username = BasePage.cf.getLocatorsOrAccount('LoginPageElements', 'username')
18     password = BasePage.cf.getLocatorsOrAccount('LoginPageElements', 'password')
19     loginBtn = BasePage.cf.getLocatorsOrAccount('LoginPageElements', 'loginBtn')
20     ferrorHead = BasePage.cf.getLocatorsOrAccount('LoginPageElements', 'ferrorHead')  # 登录失败提示
21 
22     def login(self, userName, passWord):
23         '''登录'''
24         print('-------staring login-------')
25         self.loadUrl('https://mail.126.com')
26         self.switchToFrame(*LoginPage.frame)
27         self.clear(*LoginPage.username)
28         self.sendKeys(*LoginPage.username, userName)
29         self.clear(*LoginPage.password)
30         self.sendKeys(*LoginPage.password, passWord)
31         self.click(*LoginPage.loginBtn)
32         self.switchToDefaultFrame()
33         print('---------end login---------')
34 
35     # add at 2019/04/19
36     def assertTextEqString(self, expected, name = None):
37         '''断言提示信息是否与期望的值相等'''
38         self.switchToFrame(*LoginPage.frame)
39         text = self.getElementText(*LoginPage.ferrorHead, name)
40         self.switchToDefaultFrame()
41         print('info: assert "{}" == "{}"'.format(text, expected))
42         assert text == expected, '{} != {}'.format(text, expected)
43 
44 if __name__=="__main__":
45     from selenium import webdriver
46     driver = webdriver.Firefox()
47     login = LoginPage(driver, 30)
48     login.login('lin', '')
49     login.assertTextEqString('请输入密码')
 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 
12 
13 class ContactPage(BasePage):
14     # 配置文件读取元素
15     new_contact = BasePage.cf.getLocatorsOrAccount('ContactPageElements', 'new_contact')
16     name = BasePage.cf.getLocatorsOrAccount('ContactPageElements', 'name')
17     mail = BasePage.cf.getLocatorsOrAccount('ContactPageElements', 'mail')
18     star = BasePage.cf.getLocatorsOrAccount('ContactPageElements', 'star')
19     phone = BasePage.cf.getLocatorsOrAccount('ContactPageElements', 'phone')
20     comment = BasePage.cf.getLocatorsOrAccount('ContactPageElements', 'comment')
21     commit = BasePage.cf.getLocatorsOrAccount('ContactPageElements', 'commit')
22     errortip = BasePage.cf.getLocatorsOrAccount('ContactPageElements', 'tooltip')  # 错误提示
23 
24     def newContact(self, Name, Mail, Star, Phone, Comment):
25         """添加联系人"""
26         print('--------string add contact--------')
27         self.click(*ContactPage.new_contact)
28         self.sendKeys(*ContactPage.name, Name)
29         self.sendKeys(*ContactPage.mail, Mail)
30         if Star == '1':
31             self.click(*ContactPage.star)
32         self.sendKeys(*ContactPage.phone, Phone)
33         self.sendKeys(*ContactPage.comment, Comment)
34         self.click(*ContactPage.commit)
35         print('--------end add contact--------')
36 
37     def assertErrorTip(self, excepted):
38         """断言联系人添加失败时是否有提示信息"""
39         text = self.getElementText(*ContactPage.errortip)
40         print('info: assert "{}"=="{}"'.format(text, excepted))
41         assert text == excepted
42 
43 if __name__ == '__main__':
44     from selenium import webdriver
45     from Page.PageObject.LoginPage import LoginPage
46     from Page.PageObject.HomePage import HomePage
47     driver = webdriver.Firefox()
48     home = HomePage(driver)
49     login = LoginPage(driver)
50     contact = ContactPage(driver)
51 
52     login.login('账号', 'xiaochao11520')
53     home.selectMenu()
54     contact.newContact('281754041@qq.com')
 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 
12 
13 class SendMailPage(BasePage):
14     # 配置文件读取元素
15     writeMail = BasePage.cf.getLocatorsOrAccount('SendMailPageElements', 'writeMail')
16     addressee = BasePage.cf.getLocatorsOrAccount('SendMailPageElements', 'addressee')
17     subject = BasePage.cf.getLocatorsOrAccount('SendMailPageElements', 'subject')
18     iframe = BasePage.cf.getLocatorsOrAccount('SendMailPageElements', 'iframe')
19     text = BasePage.cf.getLocatorsOrAccount('SendMailPageElements', 'text')
20     sendBtn = BasePage.cf.getLocatorsOrAccount('SendMailPageElements', 'sendBtn')
21     expect = BasePage.cf.getLocatorsOrAccount('SendMailPageElements', 'expect')
22     uploadAttachment = BasePage.cf.getLocatorsOrAccount('SendMailPageElements', 'uploadAttachment')
23     delete = BasePage.cf.getLocatorsOrAccount('SendMailPageElements', 'delete')
24 
25     def sendMail(self, Address, Subject, Text, PFA=''):
26         """发送邮件功能"""
27         print('------------string send mail---------------------')
28         self.click(*SendMailPage.writeMail)
29         self.sendKeys(*SendMailPage.addressee, Address)
30         self.sendKeys(*SendMailPage.subject, Subject)
31         self.switchToFrame(*SendMailPage.iframe)
32         self.sendKeys(*SendMailPage.text, Text)
33         self.switchToDefaultFrame()
34         if PFA:
35             self.click(*SendMailPage.uploadAttachment)
36             self.ctrlV(PFA)
37             self.enterKey()
38             self.waitElementtobelocated(*SendMailPage.delete)
39         self.click(*SendMailPage.sendBtn)
40         print('------------end send mail---------------------')
41 
42 if __name__=='__main__':
43     from Page.PageObject.LoginPage import LoginPage
44     from selenium import webdriver
45     driver = webdriver.Firefox()
46 
47     login = LoginPage(driver)
48     login.login('账号', 'xiaochao11520')
49     sendMail = SendMailPage(driver)
50     sendMail.sendMail('281754043@qq.com', 'pytest', 'pytest实战实例', 1, 'D:\KeyWordDriverTestFrameWork\geckodriver.log')

所有的准备工作都已经做好了,还有一个问题,我们的添加联系人和发送邮件应该是否应该在已经登录的前提下测试呢?答案是肯定的。所以我们在用例同目录下新建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 from Page.PageObject.LoginPage import LoginPage
12 
13 
14 # 从配置文件中获取正确的用户名和密码
15 userName = LoginPage.cf.getLocatorsOrAccount('126LoginAccount', 'username')
16 passWord = LoginPage.cf.getLocatorsOrAccount('126LoginAccount', 'password')
17 @pytest.fixture(scope='function')
18 def login(driver):
19     '''除登录用例,每一个用例的前置条件'''
20     print('------------staring login------------')
21     loginFunc = LoginPage(driver, 30)
22     loginFunc.login(userName, passWord)
23     yield
24     print('------------end login------------')
25     driver.delete_all_cookies()

ok,开始编写测试用例啦

 
 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 from Page.PageObject.LoginPage import LoginPage
12 
13 
14 @pytest.mark.loginTest
15 class TestLogin(object):
16 
17     # 测试数据
18     loginSheet = LoginPage.getSheet('login')
19     data = LoginPage.excel.getAllValuesOfSheet(loginSheet)
20 


![img](https://img-blog.csdnimg.cn/img_convert/e9fb2253bc5ca63129620a64238aef66.png)
![img](https://img-blog.csdnimg.cn/img_convert/be853122cc0b11641e76f136bc44e680.png)
![img](https://img-blog.csdnimg.cn/img_convert/f0c715c580279b9357ab803cef743068.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618631832)**

   driver.delete_all_cookies()

ok,开始编写测试用例啦

 
 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 from Page.PageObject.LoginPage import LoginPage
12 
13 
14 @pytest.mark.loginTest
15 class TestLogin(object):
16 
17     # 测试数据
18     loginSheet = LoginPage.getSheet('login')
19     data = LoginPage.excel.getAllValuesOfSheet(loginSheet)
20 


[外链图片转存中...(img-rg3OEBsd-1715820901586)]
[外链图片转存中...(img-R0vvmVda-1715820901586)]
[外链图片转存中...(img-7Ddq0cgL-1715820901587)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618631832)**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值