Web自动化实战:日志记录及测试报告优化

1.日志记录

python、pytest自身支持日志

接下来要做得事:记录

创建logger,通过logger记录日志细节(框架执行过程)

  1 import time
  2 
  3 from selenium.webdriver.common.by import By
  4 from selenium.webdriver.support.wait import WebDriverWait
  5 
  6 from commons.exchange import global_vars, injecting_vars
  7 from commons import pages
  8 import logging
  9 
 10 logger = logging.getLogger(__name__)
 11 
 12 
 13 class Word:
 14     el_submit = By.XPATH, '//button'
 15     el_count = By.XPATH, '/html/body/div[4]/div[3]/div/div[2]/ul/div/span[1]'
 16 
 17     def __init__(self, driver):  # __int__
 18         self.driver = driver  # 1. 保存driver对象
 19         self.wait = WebDriverWait(driver, 10)  # 2.保存wait对象
 20 
 21     def get_msg(self):  # 3.获取系统提示
 22         logger.info('正在获取系统提示...')
 23         msg = WebDriverWait(self.driver, 10).until(
 24             lambda d: d.find_element(By.XPATH, '//p[@class="prompt-msg"]').text)  # 函数不加括号
 25         logger.info(f'系统提示内容:{msg}')
 26         return msg
 27 
 28     def close_msg(self):  # 获取并关闭系统提示
 29         logger.info("获取并关闭提示")
 30         msg = self.get_msg()
 31         self.driver.find_element(By.XPATH, '//p[@class="prompt-msg"]/../../button').click()
 32         time.sleep(1)  # 等待提示彻底消失
 33 
 34         logger.info("系统提示已关闭")
 35         return msg
 36 
 37     def submit(self):
 38         logger.info(f"提交数据")
 39         self.driver.find_element(*self.el_submit).click()
 40         logger.info('提交成功')
 41         return self.get_msg()
 42 
 43     def refresh(self):
 44         logger.info('正在刷新页面...')
 45         self.driver.refresh()
 46         logger.info('页面刷新成功')
 47 
 48     def frame_exit(self):
 49         logger.info('正在退出iframe')
 50         self.driver.switch_to.frame(None)  # 退出iframe
 51         logger.info('退出iframe成功 ')
 52 
 53     def find_elements(self, by, value, index=0):
 54         logger.info(f'正在定位元素:{by=},{value=},{index=}')
 55 
 56         def f(x):
 57             try:
 58                 el = self.driver.find_elements(by, value)[index]
 59                 return True
 60             except:
 61                 pass
 62 
 63         self.wait.until(f)
 64         logger.info('等待结束')
 65         el = self.driver.find_elements(by, value)[index]
 66         logger.info(f"得到元素: {el.tag_name}({el.text})")
 67         return el
 68 
 69     def click_by_js(self, del_el):  # 4. 通过JS进行强制点击
 70         logger.info(f'正在通过JS强制点击:{del_el.tag_name}')
 71         self.driver.execute_script('arguments[0].click()', del_el)
 72         logger.info(f'JS强制点击成功')
 73 
 74     def click_by_wait(self, el):  # 根据xpath,进行实现
 75         logger.info(f"正在通过等待进行点击{el.tag_name}")
 76         self.wait.until(lambda x: el.is_enabled())
 77         el.click()
 78         logger.info(f'等待并点击成功')
 79 
 80     def get_count(self):
 81         logger.info(f'正在获取数据条数:{self.el_count}')
 82         el = self.driver.find_element(*self.el_count)
 83         count_text = el.text
 84         count_text = count_text.replace("", "").replace("条数据", "").strip()
 85         logger.info(f'获得数据量:{count_text}')
 86         return count_text
 87 
 88     def sleep(self, x):
 89         """强制等待x秒"""
 90         logger.info(f'正在sleep:{x}秒')
 91         time.sleep(float(x))
 92         logger.info('sleep结束')
 93 
 94     def goto(self, url):
 95         """进行页面跳转"""
 96         logger.info(f'正在页面跳转:{url=}')
 97         self.driver.get(url)
 98         logger.info('页面跳转成功')
 99 
100     def click(self, xpath):
101         """点击指定的元素"""
102         logger.info(f'定位并点击元素:{xpath}')
103         # 1. 定位元素
104         el = self.driver.find_element(By.XPATH, xpath)
105         # 2. 点击元素
106         self.click_by_wait(el)
107         logger.info('定位并点击完成')
108 
109     def send_keys(self, xpath, content):
110         """对指定的元素进行输入"""
111         logger.info(f'定位并输入内容:{xpath=},{content=}')
112         # 1. 定位元素
113         el = self.driver.find_element(By.XPATH, xpath)
114         logger.info(f'定位到元素:{el.tag_name}')
115         # 2. 输入内容
116         el.send_keys(content)
117         logger.info('定位并输入成功')
118 
119     def save_attr(self, xpath, attr, var_name):
120         """保存指定元素的属性"""
121         logger.info(f'定位并保存元素的属性:{xpath=},{attr=},{var_name=}')
122         # 1. 定位元素
123         el = self.driver.find_element(By.XPATH, xpath)
124         logger.info(f'定位到元素:{el.tag_name}')
125         # 2. 获取属性
126         value = el.get_attribute(attr)
127         logger.info(f'获得属性成功:{value}')
128         # 3. 保存到变量中
129 
130         global_vars[var_name] = value
131         logger.info('定位并保存元素属性成功')
132 
133     def save_text(self, xpath, var_name):
134         """保存指定元素的文本"""
135         logger.info(f'定位并保存元素的文本:{xpath=},{var_name=}')
136         # 1. 定位元素
137         el = self.driver.find_element(By.XPATH, xpath)
138         logger.info(f'定位到元素:{el.tag_name}')
139         # 2. 获取文本
140         value = el.text
141         logger.info(f'获得文本成功:{value}')
142         # 3. 保存到变量中
143         global_vars[var_name] = value
144         logger.info('定位并保存元素文本成功')
145 
146     def save_msg(self, var_name):
147         """保存系统提示"""
148         logger.info(f'保存系统提示到变量:{var_name}')
149         # 1. 获取系统提示
150         msg = self.close_msg()
151 
152         # 2. 把提示保存到变量
153         global_vars[var_name] = msg
154         logger.info('保存系统提示到变量成功')
155 
156     def assert_equal(self, a, b):
157         # 兼容性考虑:
158         #   任何一个关键字,都有可能使用参变量
159         #   任何一个关键字参数,都有可能使用变量
160         a = injecting_vars(a)
161         b = injecting_vars(b)
162 
163         logger.info(f'相等断言:{a}=={b}')
164         assert a == b
165         logger.info('相等断言成功')
166 
167     def assert_not_equal(self, a, b):
168         a = injecting_vars(a)
169         b = injecting_vars(b)
170         logger.info(f'不相等断言:{a}!={b}')
171         assert a != b
172         logger.info('不相等断言成功')
173 
174     def pom(self, page_name, method, *args):
175         """调用指定的POM,完成自动化"""
176         # 1.根据PO类名,找到类,进行实例化
177         logger.info(f'调用POM:{page_name=},{method=},{args}')
178 
179         page_class = getattr(pages, page_name)
180 
181         page = page_class(self.driver)
182         # 2.对示例对象,根据方法名,找到方法,进行调用
183         method_func = getattr(page, method)
184         # 3.调用方法是传递参数(长度绑定)
185         # 位置参数转关键字参数
186         my_args = []
187         my_kwargs = {}
188         for arg in args:
189             if not isinstance(arg, str):
190                 my_args.append(arg)  # 如果没有,作为普通的位置参数
191             elif "===" not in arg:  # 判断是否包含特殊符号
192                 my_args.append(arg)  # 如果没有,作为普通的位置参数
193             else:  # 如果有,转为关键字参数(字典)
194                 k, v = arg.split("===")
195                 my_kwargs[k] = v
196         method_func(*my_args, **my_kwargs)
197         logger.info('POM调用成功')

2.优化报告

2.1 用例关系

allure报告,可以使用allure标注

在excel种使用allure标准:在标记列,写入allure_xx格式

 2.2 UI画面截图

1     if key_word_name not in ['assert_equal','assert_not_equal','sleep']: #不进行截图的关键字
2         #关键字调用之后,进行截图
3         img=driver.get_screenshot_as_png() #图片二进制内容
4 
5         #把图片附加到allure中
6         allure.attach(img,f'{step["序号"]}_{step["步骤名称"]}')
  1. 控制浏览器截取画面
    1. 什么时候截图?:每一个步骤执行之后截图
  2. 把图片保存到allure中
  3. 判断是否需要截图
    1. 部分关键字不需要截图:['assert_equal','assert_not_equal','sleep']

 3.集中配置

可能会发生变化的内容,放置在同一个位置,进行集中管理

  • 项目地址
  • 账号/密码
  • excel用例fixture的关键字:driver
  • 手动注入的变量
  • 显示等待时间
 1 """
 2 @Filename: /settings
 3 @Author:李国生
 4 @Time:2024-02-29 14:14
 5 @Describe: 项目配置文件
 6 """
 7 
 8 username='' #测试账号
 9 password = '' #测试密码
10 
11 base_url='' #项目环境变量
12 driver_base_name='driver' #excel用例的driver基础名称
13 
14 test_vars={} #自动注入的变量
15 wait_time=10 #显示等待时间10秒
16 
17 msg_xpath='//p[@class="prt-msg"]' #系统提示的xpath

注意:

写注释(用途、影响、使用位置)

保存精简

后期固定的内容,可以从setting中移除

 

posted @ 2024-02-29 12:29  万溪汇海  阅读(27)  评论(0编辑  收藏  举报