Pytest UI自动化测试实战实例,2024软件测试春招面试真题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

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

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

如果你需要这些资料,可以添加V获取:vip1024b (备注软件测试)
img

正文

| 7 | 安装yagmail发送报告库 | pip install yagmail |
| 8 | 确保已配置火狐或谷歌浏览器及对应驱动 | |
| 9 | 确保已经正确配置好发送邮件的邮箱 | |

项目简介

测试地址

https://mail.126.com

测试范围

1.126电子邮箱登录功能测试-验证正确帐号密码登录成功-验证错误用户名密码登录失败(有很多情况,用例里面做了充分的校验)

2.126电子邮箱添加联系人功能测试-验证正确填写必填项数据添加联系人成功-验证缺省必填项数据添加联系人失败-验证必填项字段数据格式错误添加联系人失败

3.126电子邮箱发送邮件功能测试-验证普通邮件发送成功-验证带附件邮件发送成功

项目设计

1.python编程语言设计测试脚本

2.webdriver驱动浏览器并操作页面元素

3.二次封装webdriver Api 操作方法

4.采用PageObject设计模式,设计测试业务流程

5.通过UI对象库存储页面操作元素

6.通过数据文件存储数据,读取数据,参数化测试用例并驱动测试执行

7.通过第三方插件pytest-html生成测试报告

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’, ‘’)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
# 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’, ‘’)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
[外链图片转存中…(img-hAxw1ZCj-1713345512584)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

pytest ui自动化测试实战主要包括安装并配置环境、练习pytest基本使用、练习selenium基本使用以及使用pytest和selenium实现UI自动化测试四个部分。在练习pytest基本使用中,我们可以通过编写简单的用例格式来实现对测试目的和要求的覆盖。而在练习selenium基本使用中,我们可以使用脚本语言来模拟用户行为操作,接近真实用户场景,实现对web页面的自动化测试。通过这些实践,我们可以了解基于pytest和selenium的UI自动化测试的基本思路,并熟悉这两种测试工具的基本操作。此外,pytest还是一个非常成熟的Python测试框架,它具有简单的用例编写格式和丰富的插件,如pytest-html和pytest-rerunfailures等,可以生成漂亮的测试报告并实现失败用例的重复执行。通过实战,我们可以基本掌握pytest的使用方法。另外,还可以基于pytest实现测试用例收集方案、自定义参数化方案、页面元素定位数据存储方案、测试用例数据存储和维护方案等,以避免重复设计和维护复杂的问题。此外,还可以修改定制并汉化html测试报告,使其更加简洁、美观、易读。同时,还可以封装集成selenium、appium、minium和WinAppDriver等工具,以更好地支持不同平台和应用的自动化测试。总之,通过pytest ui自动化测试实战,我们可以全面了解和掌握UI自动化测试的基本原理和实践技巧。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* [软件测试案例|使用 pytest+selenium 进行UI自动化测试](https://blog.csdn.net/qq_41640218/article/details/124031645)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [基于pytest设计自动化测试框架实战](https://blog.csdn.net/hotswwkyo/article/details/103211805)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值