166
167 try:
168
169 self.find_element_p((By.XPATH, element_xp)).clear()
170
171 except AttributeError:
172
173 print(‘元素获得为空,无属性可用’)
174
175
176
177 # 输入框输入值
178
179 def send_kw(self, element_xp, kw):
180
181 try:
182
183 self.find_element_p((By.XPATH, element_xp)).send_keys(kw)
184
185 except AttributeError:
186
187 print(‘元素获得为空,无属性可用’)
188
189
190
191 # 模拟键盘向页面发送end指令(滑动到页面底部)
192
193 def page_end(self, table_xp):
194
195 try:
196
197 self.find_element_p((By.XPATH, table_xp)).send_keys(Keys.END)
198
199 except AttributeError:
200
201 print(‘元素获得为空,无属性可用’)
202
203
204
205 # 鼠标移动到指定元素上
206
207 def move_element(self, element_xp):
208
209 move = self.find_element_p((By.XPATH, element_xp))
210
211 ActionChains(self.driver).move_to_element(move).perform()
212
213
214
215 # 双击元素
216
217 def double_click(self, element):
218
219 ActionChains(self.driver).double_click(element).perform()
220
221
222
223 # 切换到指定窗口
224
225 def switch_window(self, num):
226
227 handles = self.driver.window_handles # 获取当前窗口句柄集合
228
229 try:
230
231 self.driver.switch_to.window(handles[num]) # 切换到指定窗口
232
233 except Exception:
234
235 raise
5、 loginPage.py内容:
1 from GAD_webUI.commen.universal_method import UniversalMethod
5 from GAD_webUI.pages.base_page import BasePage
10
11 class LoginPage(BasePage):
12
13 login_els = UniversalMethod.get_yaml_info(
14
15 r’D:G_webUIdatalogin.yaml’) # login_els是个字典
16
17
18
19 def login_GAD(self, username, password):
20
21 self.open_page() # 打开浏览器
22
23 self.send_kw(self.login_els[‘username’], username) # 输入用户名
24
25 self.send_kw(self.login_els[‘password’], password) # 输入密码
26
27 self.click(self.login_els[‘login_btn’]) # 点击登录
28
29 sleep(2)
30
31
32
33 error_el = self.find_element_p((By.XPATH, self.login_els[‘login_error’]))
34
35 if error_el:
36
37 return error_el.text
38
39 else:
40
41 print(‘登录成功’)
6、 test_login.py(测试类)内容:
1 import unittest
2
3 from time import sleep
4
5 from selenium import webdriver
6
7 from GAD_webUI.pages.login_page import LoginPage
8
9
10
11 class Login(unittest.TestCase):
12
13 driver = webdriver.Chrome()
14
15
16
17 @classmethod
18
19 def setUpClass(cls, ) -> None:
20
21 cls.login_page = LoginPage(cls.driver)
22
23
24
25 def test_login(self, username=‘v-luoyang’, password=‘123456’):
26
27 error_text = self.login_page.login_GAD(username, password)
28
29 self.assertFalse(error_text is not None, msg=error_text) # 如果错误信息存在,则登录失败,输出错误提示信息
30
31
32
33 @classmethod
34
35 def tearDownClass(cls) -> None:
36
37 sleep(5)
38
39 cls.driver.quit()
40
41
42
43 if name == ‘main’: # 执行all_test_run.py 时,需将该段注释掉
44
45 unittest.main()
7、 引入测试报告
在小节2中已经实现了。
result = BeautifulReport(UniversalMethod.createSuite()) # 创建测试套件容器
result.report(filename=now+‘G_smoke’, description=‘G冒烟测试’, report_dir=filename) # 生成测试报告
8、 执行完测试自动发送邮件(经尝试可用)
1 import os
2
3
4
5 “”"
6
7 这个文件主要是配置发送邮件的主题、正文等,将测试报告发送并抄送到相关人邮箱的逻辑。
8
9 “”"
10
11 import smtplib
12
13 from email.mime.text import MIMEText
14
15 from email.mime.multipart import MIMEMultipart
16
17
18
19 class SendEmail(object):
20
21 def init(self, username, passwd, recv, title, content,
22
23 file_path=None, ssl=False,
24
25 email_host=‘smtp.163.com’, port=25, ssl_port=465):
26
27 self.username = username # 用户名
28
29 self.passwd = passwd # 密码
30
31 self.recv = recv # 收件人,多个要传list [‘a@qq.com’,'b@qq.com]
32
33 self.title = title # 邮件标题
34
35 self.content = content # 邮件正文
36
37 self.file_path = file_path # 附件路径,如果不在当前目录下,要写绝对路径
38
39 self.email_host = email_host # smtp服务器地址
40
41 self.port = port # 普通端口
42
43 self.ssl = ssl # 是否安全链接
44
45 self.ssl_port = ssl_port # 安全链接端口
46
47
48
49 # 发送邮件
50
51 def send_email(self):
52
53 msg = MIMEMultipart()
54
55 msg.attach(MIMEText(self.content)) # 邮件正文的内容
56
57
58
59 # 构造附件
60
61 for f_path, file_dirs, files in os.walk(self.file_path):
62
63 for file in files:
64
65 msg.attach(self._att_html(os.path.join(f_path, file)))
66
67
68
69 msg[‘Subject’] = self.title # 邮件主题
70
71 msg[‘From’] = self.username # 发送者账号
72
73 msg[‘To’] = ‘,’.join(self.recv) # 接收者账号列表
74
75 if self.ssl:
76
77 self.smtp = smtplib.SMTP_SSL(self.email_host, port=self.ssl_port)
78
79 else:
80
81 self.smtp = smtplib.SMTP(self.email_host, port=self.port)
82
83 # 发送邮件服务器的对象
84
85 self.smtp.login(self.username, self.passwd)
86
87 try:
88
89 self.smtp.sendmail(self.username, self.recv, msg.as_string())
90
91 pass
92
93 except Exception as e:
94
95 print(‘出错了。。’, e)
96
97 else:
98
99 print(‘发送成功!’)
100
101 self.smtp.quit()
102
103
104
105 # 构造邮件附件
106
107 @staticmethod
108
109 def _att_html(filename):
110
111 # 构造附件
112
113 atthtml = MIMEText(open(filename, ‘rb’).read(), ‘base64’,
114
115 ‘utf-8’) # 文件放在同一路径,不放在同一路径改一下比如’D:/test/report.html
116
117 atthtml[“Content-Type”] = ‘application/octet-stream’
118
119 atthtml[“Content-Disposition”] = ‘attachment;filename = “GAD_Smoke_report.html”’
120
121 return atthtml
122
123
124
125
126 # 调用并发送邮件
127 if name == ‘main’:
128
129 m = SendEmail(
130
131 username=‘cicada_luo@163.com’, # 这里填发送者邮箱
132
133 passwd=‘TCBXOAOF…’, # 授权码还是什么忘记了
134
135 recv=[‘1761885773@qq.com’], # 接收者邮箱
136
137 title=‘G——smoke’,
138
139 content=‘G——smoke测试报告’,
140
141 file_path=‘D:G_webUI
eport’, # 发送的文件
142
143 email_host=‘smtp.163.com’,
144
145 ssl_port=465,
146
147 ssl=True,
148
149 )
150
151 m.send_email() # 发送邮件
9、 引入DDT
① 安装DDT,打开cmd,输入pip install ddt
② 在测试类上写上@ddt,表示该用例类需要进行数据驱动
③ 在测试方法上写上@file_data(file_path),表示引入外部文件进行数据驱动。
④ 如果步骤③传入的文件是yaml格式,那么用例方法参数需要用**args来接收文件的内容(表示接收文件的所有内容到该参数中) ;如果传入的文件是其他的格式,那么用一个参数接收即可(接收的是json数据格式的值)
1 import unittest
2
3
4
5 from ddt import file_data, ddt
6
7 from selenium import webdriver
8
9 from GAD_webUI.pages.login_page import LoginPage
10
11
12
13
14
15 @ddt
16
17 class test_Login(unittest.TestCase):
18
19
20
21 def setUp(self) -> None:
22
23 self.driver = webdriver.Chrome()
24
25 self.login_page = LoginPage(self.driver)
26
27
28
29 def tearDown(self) -> None:
30
31 self.driver.quit()
32
33
34
35 @file_data(r’D:G_webUIdata퇘login.yaml’)
36
37 def test_login(self, **kwargs):
38
39 print(kwargs)
40
41 error_text = self.login_page.login_GAD(kwargs[‘username’], kwargs[‘password’])
42
43 self.assertFalse(error_text is not None, msg=error_text) # 如果错误信息存在,则登录失败,输出错误提示信息
44
45 print(“------------------------------------”)
46
47
48
49
50
51 if name == ‘main’: # 执行all_test_run.py 时,需将该段注释掉
52
53 unittest.main()
五、所遇问题及解决思路
1、元素定位不到怎么办
表现形式为:程序抛出 NoSuchElementException 异常
解决思路:
① 检查元素定位属性值是否写错,很多时候错误都是因为粗心导致的。
② 添加等待。
有时,程序执行过快,导致程序已经执行完了,而元素还未加载出来,那么就会抛出异常,
我们添加等待时间即可。最粗暴的做法就是 sleep(3)—强制等待3秒,这样做使得程序运行时间较长,一般少用。最常用的是使用显示等待(搭配 until()方法、expected_conditions 类来使用)。例:
1 from selenium.common.exceptions import NoSuchElementException, TimeoutException
2 from selenium.webdriver.support import expected_conditions as EC
3
4
5 # 单个元素的定位方法3
6
7 def find_element_p(self, *args):
8
9 try:
10
11 return WebDriverWait(self.driver, 5, 0.5).until(EC.presence_of_element_located(*args))
12
13 except (NoSuchElementException, TimeoutException):
14
15 print(“超过元素定位等待时长,无法获取到该元素,请检查定位路径”)
③ 以上方法不行时,那么就再尝试使用其他方式进行元素定位(常见的元素定位方式可是有八种之多)
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数软件测试工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上软件测试开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
8322)]
[外链图片转存中…(img-IpLUzbbi-1712719898323)]
[外链图片转存中…(img-kaa3AkxI-1712719898323)]
[外链图片转存中…(img-moxkPmCe-1712719898323)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上软件测试开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注软件测试)
[外链图片转存中…(img-I8asaHy3-1712719898323)]