Selenium基于Python web自动化基础二 -- 免登录、等待及unittest单元测试框架
一、免登录
在进行测试的过程中难免会遇到登录的情况,给测试工作添加了工作量,本文仅提供一些思路供参考
解决方式:手动请求中添加cookies、火狐的profile文件记录信息实现、人工介入、万能验证码、去掉验证码、cookie写入yaml文件
1、手动在请求中添加cookies信息
1 url = "http://www.baidu.com" 2 driver = webdriver.Firefox() 3 driver.get(url) 4 time.sleep(3) 5 #添加cookies的方式 6 7 c1 = {'domain': '.baidu.com', 8 'name':'BDUSS', 9 'value': 'dyRlBucW9WOUhpNXducElPT1dlVHN1SFdFZUllTkJ-TEg5djNAAVe6gcaGFuc2hvdWthaQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHa68lh2uvJYU2', 10 'path': '/', 11 'httpOnly': True, 12 'secure':False 13 } 14 driver.add_cookie(c1)
"""
# 追加cookie,同上
cookies = [{'domain':'baidu.com','httpOnly':False……}]
for cookie in cookies:
driver.add_cookie(cookie)
"""
15 time.sleep(3) 16 # print(driver.get_cookies()) #得到当前cookies信息 17 # driver.delete_all_cookies() #删除所有cookies信息 18 driver.refresh() 19 time.sleep(5) 20 21 driver.quit()
2、火狐的profile文件记录信息实现
1 #利用火狐profile文件的方式(前提:必须先手动登录一下,且需要勾选记住信息) 2 profile_ff = "C:/Users/Hanxiaobei/AppData/Roaming/Mozilla/Firefox/Profiles/ytw908g4.default" 3 4 fp = webdriver.FirefoxProfile(profile_ff) 5 driver = webdriver.Firefox(fp) 6 url = "http://www.baidu.com" 7 driver.get(url) 8 time.sleep(5) 9 driver.quit()
3、人工介入
1 driver.find_element_by_link_text("登录").click() 2 driver.find_element_by_id("TANGRAM__PSP_8__userName").send_keys("hankai") 3 driver.find_element_by_id("TANGRAM__PSP_8__password").send_keys("hankai") 4 time.sleep(15) #导入等待时间人工输入验证码 5 driver.find_element_by_id("TANGRAM__PSP_8__submit").click() 6 7 time.sleep(5) 8 driver.quit()
4、万能验证码、去掉验证码
万能验证码、去掉验证码需要开发的配合
5、cookie写入yaml文件
1 import os 2 import yaml 3 import time 4 import pytest 5 from selenium.webdriver import TouchActions 6 from selenium.webdriver.common.by import By 7 from selenium import webdriver 8 from selenium.webdriver.common.keys import Keys 9 from selenium.webdriver.common.action_chains import ActionChains 10 from selenium.webdriver.support import expected_conditions 11 from selenium.webdriver.support.wait import WebDriverWait 12 13 class Test_a: 14 def setup(self): 15 executable_path = r'C:\Users\love8\PycharmProjects\seleniumauto\lib\chromedriver.exe' 16 opt = webdriver.ChromeOptions() 17 opt.debugger_address = '127.0.0.1:9222' 18 self.driver = webdriver.Chrome(options=opt, executable_path=executable_path) 19 self.driver.implicitly_wait(3) 20 # self.driver.maximize_window() 21 22 @pytest.mark.skip 23 def test_print_save_cookie(self): 24 """ 25 # 企业微信扫码登录,停留30秒知道点击通讯录元素可见。30秒的时间可以手动进行扫码 26 self.driver.get('https://work.weixin.qq.com/') 27 self.driver.find_element(By.LINK_TEXT, '企业登录').click() 28 WebDriverWait(self.driver, 30).until( 29 expected_conditions.element_to_be_clickable((By.XPATH, '//*[@id="menu_contacts"]'))) 30 self.driver.find_element(By.XPATH, '//*[@id="menu_contacts"]').click() 31 """ 32 # 调试下把已登录的cookie信息保存在yaml文件中 33 self.driver.get('https://work.weixin.qq.com/wework_admin/frame#contacts') 34 self.driver.find_element(By.XPATH, '//*[@id="menu_contacts"]').click() 35 # print(self.driver.get_cookies()) 36 cookie = self.driver.get_cookies() 37 # 三方库为pyyaml!pip install pyyaml 38 with open('cookie.yaml','w',encoding="UTF-8")as f: 39 yaml.dump(cookie,f) 40 41 @pytest.mark.skip 42 def test_cookie(self): 43 # 把cookie信息加入driver中看是否还是登录状态 44 self.driver.get('https://work.weixin.qq.com/wework_admin/loginpage_wx') 45 cookies = [{'domain': '.qq.com', 'expiry': 1635588643, 'httpOnly': False, 'name': '_gat', 'path': '/', 'secure': False, 'value': '1'}, {'domain': '.work.weixin.qq.com', 'httpOnly': False, 'name': 'wwrtx.cs_ind', 'path': '/', 'secure': False, 'value': ''}, {'domain': '.work.weixin.qq.com', 'httpOnly': False, 'name': 'wxpay.vid', 'path': '/', 'secure': False, 'value': '1688854646270804'}, {'domain': '.work.weixin.qq.com', 'httpOnly': False, 'name': 'wxpay.corpid', 'path': '/', 'secure': False, 'value': '1970325126485660'}, {'domain': '.work.weixin.qq.com', 'httpOnly': False, 'name': 'wwrtx.vid', 'path': '/', 'secure': False, 'value': '1688854646270804'}, {'domain': '.work.weixin.qq.com', 'httpOnly': True, 'name': 'wwrtx.vst', 'path': '/', 'secure': False, 'value': 'WrfbRBRLmmI3aJcydeEs4Gi0xlnnDFcerptN6SeDCz_ApHD4T254onRGHu5510SaRq1d4gnRTeHwAmVa_9nHcXfxIuWVNenR_I_xbR7Sit3LwsSHhlQvzCy3asXqBeWvjFeSJQRkkgtA2m22QuIvUNVMGiOrSaeDUjV08pZ2wcGn-fFVmOZYZI1zEJhByx_Z8waNTrgzvxFXhTK46ZL5JTPp18bWlWYgYN_jzc_osXC3NSTUklyMpBbZRUZnQYagFnIm2M3YPFlhHLAQ7VaPfw'}, {'domain': '.work.weixin.qq.com', 'expiry': 1667123870, 'httpOnly': False, 'name': 'Hm_lvt_9364e629af24cb52acc78b43e8c9f77d', 'path': '/', 'secure': False, 'value': '1635586713,1635586823,1635587813,1635587871'}, {'domain': '.work.weixin.qq.com', 'httpOnly': True, 'name': 'wwrtx.ref', 'path': '/', 'secure': False, 'value': 'direct'}, {'domain': '.work.weixin.qq.com', 'httpOnly': True, 'name': 'wwrtx.ltype', 'path': '/', 'secure': False, 'value': '1'}, {'domain': '.work.weixin.qq.com', 'httpOnly': False, 'name': 'wwrtx.d2st', 'path': '/', 'secure': False, 'value': 'a7108404'}, {'domain': '.work.weixin.qq.com', 'httpOnly': False, 'name': 'Hm_lpvt_9364e629af24cb52acc78b43e8c9f77d', 'path': '/', 'secure': False, 'value': '1635587871'}, {'domain': '.work.weixin.qq.com', 'httpOnly': True, 'name': 'wwrtx.refid', 'path': '/', 'secure': False, 'value': '30966507183469273'}, {'domain': '.work.weixin.qq.com', 'httpOnly': True, 'name': 'wwrtx.sid', 'path': '/', 'secure': False, 'value': 'jB8YiSNmItShJwaOXMquxO9alkGfhfRg_JwSJxy6nPKXsb-5k1RE3vOG_vTfWhWn'}, {'domain': '.qq.com', 'expiry': 1698660583, 'httpOnly': False, 'name': '_ga', 'path': '/', 'secure': False, 'value': 'GA1.2.2011331839.1635586714'}, {'domain': '.work.weixin.qq.com', 'expiry': 1667122712, 'httpOnly': False, 'name': 'wwrtx.c_gdpr', 'path': '/', 'secure': False, 'value': '0'}, {'domain': '.work.weixin.qq.com', 'httpOnly': True, 'name': 'wwrtx.logined', 'path': '/', 'secure': False, 'value': 'true'}, {'domain': '.qq.com', 'expiry': 1635674983, 'httpOnly': False, 'name': '_gid', 'path': '/', 'secure': False, 'value': 'GA1.2.607246320.1635586714'}, {'domain': '.work.weixin.qq.com', 'expiry': 1638180583, 'httpOnly': False, 'name': 'wwrtx.i18n_lan', 'path': '/', 'secure': False, 'value': 'zh'}] 46 for cookie in cookies: 47 self.driver.add_cookie(cookie) 48 self.driver.get('https://work.weixin.qq.com/wework_admin/frame#contacts') 49 self.driver.find_element(By.XPATH, '//*[@id="menu_contacts"]').click() 50 51 @pytest.mark.skip 52 def test_login(self): 53 # 直接使用保存在yaml文件中的cookie信息,看是否可以正常登录 54 self.driver.switch_to.window(self.driver.window_handles[0]) 55 self.driver.get('https://work.weixin.qq.com/wework_admin/loginpage_wx') 56 with open('cookie.yaml',encoding="UTF-8")as fp: 57 yaml_data = yaml.safe_load(fp) 58 for cookie in yaml_data: 59 self.driver.add_cookie(cookie) 60 time.sleep(3) 61 self.driver.get('https://work.weixin.qq.com/wework_admin/frame#index') 62 time.sleep(5)
二、等待
1、time模块
1 import time 2 3 time.sleep(5)
2、隐形等待
1 driver.implicitly_wait(20)
3、显性等待
# 第一种显示等待编写方式:匿名函数返回元素 WebDriverWait(self.driver,10).until(lambda driver:driver.find_element(By.XPATH, '//*[@id="ember202"]/td[1]/span/a')).click() # 第二种显示等待编写方式:定义函数判断元素是否大于1,大于1代表存在元素,然后进行操作 def wait(x): return len(self.driver.find_elements(By.XPATH, '//*[@id="ember202"]/td[1]/span/a')) >= 1 WebDriverWait(self.driver,10).until(wait) self.driver.find_element(By.XPATH,'//*[@id="ember202"]/td[1]/span/a').click() # 第三种显示等待编写方式:自带函数判断是否可点击,然后进行操作 WebDriverWait(self.driver,10).until(expected_conditions.element_to_be_clickable((By.XPATH,'//*[@id="ember202"]/td[1]/span/a'))) self.driver.find_element(By.XPATH, '//*[@id="ember202"]/td[1]/span/a').click()
三、unittest单元测试框架
简单的unittest框架代码如下:
1 import unittest,time 2 from selenium import webdriver 3 from selenium.webdriver.common.by import By 4 class Baidu(unittest.TestCase): 5 def setUp(self): 6 self.driver = webdriver.Chrome() 7 url = "http://www.baidu.com" 8 self.driver.get(url) 9 self.driver.implicitly_wait(20) 10 self.verificationErrors = [] 11 12 def tearDown(self): 13 self.driver.quit() 14 self.assertEqual([],self.verificationErrors,msg="验证失败") 15 16 def test_search(self): 17 self.driver.find_element(By.ID,"kw").send_keys("hanxiaobei") 18 self.driver.find_element(By.ID,"su").click() 19 time.sleep(5) 20 21 if __name__ == "__main__":
第一种形式: 22 #unittest.main()
第二种形式:
1 suite = unittest.TestSuite() 2 suite.addTest(Baidu("test_search")) 3 4 runner = unittest.TextTestRunner() 5 runner.run(suite)
可生成html报告的unittest框架代码如下:
1 from selenium import webdriver 2 import time 3 import unittest 4 import HTMLTestRunner 5 6 class Test_case(unittest.TestCase): 7 """测试类""" 8 def setUp(self): 9 self.url = "http://www.baidu.com" 10 self.driver = webdriver.Firefox() 11 self.driver.implicitly_wait(20) 12 self.verificationErrors = [] 13 14 def tearDown(self): 15 self.driver.quit() 16 self.assertEqual([],self.verificationErrors) 17 18 def test_sou1(self): 19 """测试搜索演示1""" 20 self.driver.get(self.url) 21 self.driver.find_element_by_id("kw").send_keys("测试") 22 self.driver.find_element_by_id("su").click() 23 self.driver.close() 24 time.sleep(5) 25 def test_sou2(self): 26 """测试搜索演示2""" 27 self.driver.get(self.url) 28 self.driver.find_element_by_id("k").send_keys("自动化测试") 29 self.driver.find_element_by_id("su").click() 30 self.driver.close() 31 time.sleep(5) 32 33 #生成一个运行测试用例集合 34 suite = unittest.TestSuite() 35 suite.addTest(Test_case('test_sou1')) 36 suite.addTest(Test_case('test_sou2')) 37 38 ''' 39 生成基于html的测试报告: 40 1定义一个文件的路径 41 2以写的方式进行打开文件 42 3调用htmltestrunner的方法生成测试报告 43 4运行测试集合 44 5关闭文件 45 ''' 46 report_file=".\\20170423_report.html" 47 fp = open(report_file,"wb") 48 runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title="搜索",description="测试搜索结果") 49 runner.run(suite) 50 fp.close()