1.2、火狐的profile文件記錄信息實現 1.4、萬能驗證碼、去掉驗證碼 萬能驗證碼、去掉驗證碼需要開發的配合 2、等待 2.1、time模塊 2.2、隱式等待 2.3、顯式等待 3、unittest單元測試框架 簡單的unittest框架代碼如下: 可生成html報告的unittest框架代碼 ...
1、免登錄
在進行測試的過程中難免會遇到登錄的情況,給測試工作添加了工作量,本文僅提供一些思路供參考
解決方式:手動請求中添加cookies、火狐的profile文件記錄信息實現、人工介入、萬能驗證碼、去掉驗證碼
1.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) 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()
1.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()
1.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()
1.4、萬能驗證碼、去掉驗證碼
萬能驗證碼、去掉驗證碼需要開發的配合
2、等待
2.1、time模塊
1 import time 2 3 time.sleep(5)
2.2、隱式等待
1 driver.implicitly_wait(20)
2.3、顯式等待
1 url = "http://www.baidu.com" 2 driver = webdriver.Firefox() 3 driver.get(url) 4 #顯性等待 5 kk = WebDriverWait(driver,10).until(lambda driver:driver.find_element_by_id("kw"),message="worry!") 6 kk.send_keys("測試")
3、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 第一種形式: 23 #unittest.main() 24 25 第二種形式: 26 suite = unittest.TestSuite() 27 suite.addTest(Baidu("test_search")) 28 29 runner = unittest.TextTestRunner() 30 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()
5、PO模型
PO就是一個設計思想,將代碼以頁面為單位進行組織,針對這個頁面上的所有信息、相關操作都放到一個類中,從而使具體的測試用例變成了簡單的調用和驗證操作。
優點:進行了拆分和分層
缺點:對於複雜的業務page層變了,case也需要去改動
PO模型的目錄結構:
其中,base_page是login_page、search_page的基礎。test_login調用login_page,login_page調用base_page,同理test_search。
PO代碼示例:
base_page.py
1 from selenium.webdriver.support.wait import WebDriverWait 2 3 ''' 4 這個類主要是完成所有頁面的一些公共方法的封裝 5 ''' 6 class Action(object): 7 #初始化 8 def __init__(self,se_driver): 9 self.driver = se_driver 10 11 #定義open方法 12 def open(self,url): 13 self.driver.get(url) 14 self.driver.maximize_window() 15 16 #重寫元素定位的方法 17 def find_element(self,*loc): 18 try: 19 WebDriverWait(self.driver,20).until(lambda driver:driver.find_element(*loc).is_displayed()) 20 return self.driver.find_element(*loc) 21 except Exception as e: 22 print("未找到%s"%(self,loc)) 23 24 #定義script方法,用於執行js腳本 25 def script(self,src): 26 self.driver.execute_script(src) 27 28 #重寫send_keys方法 29 def send_keys(self,loc,value,clear_first=True,clik_first=True): 30 try: 31 if clik_first: 32 self.find_element(*loc).click() 33 if clear_first: 34 self.find_element(*loc).clear() 35 self.find_element(*loc).send_keys(value) 36 except AttributeError: 37 print("未找到%s"%(self,loc))
login_page.py
1 from selenium.webdriver.common.by import By 2 from seleniumframework.PO import base_page 3 import time 4 5 class LoginPage(base_page.Action): 6 link_loc = (By.LINK_TEXT,"登錄") 7 name_loc = (By.ID,"TANGRAM__PSP_8__userName") 8 password_loc = (By.ID,"TANGRAM__PSP_8__password") 9 submit_loc = (By.ID,"TANGRAM__PSP_8__submit") 10 11 username_top = (By.LINK_TEXT,"hanxiaobei") 12 13 14 def click_link(self): 15 self.find_element(*self.link_loc).click() 16 time.sleep(3) #等待3秒,等待登錄彈窗載入完成 17 18 def run_case(self,value1,value2): 19 self.find_element(*self.name_loc).send_keys(value1) 20 self.find_element(*self.password_loc).send_keys(value2) 21 time.sleep(20) #手動輸入驗證碼 22 self.find_element(*self.submit_loc).click() 23 time.sleep(5) #等待5秒,登錄後的頁面載入完成 24 25 def get_username(self): 26 return self.find_element(*self.username_top).text
test_login.py
1 import unittest 2 from selenium import webdriver 3 from seleniumframework.PO.login_page import LoginPage 4 import time 5 6 class TestBaiduLogin(unittest.TestCase): 7 """UI自動化登錄""" 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 time.sleep(5) 16 self.driver.quit() 17 # self.assertEqual([],self.verificationErrors) 18 19 def test_login(self): 20 """百度登錄""" 21 sp = LoginPage(self.driver) 22 sp.open(self.url) 23 sp.click_link() 24 sp.run_case("hanxiaobei","xxxxxxx") 25 self.assertEqual(sp.get_username(),"hanxiaobei",msg="驗證失敗!")
main.py 運行的主入口
1 import unittest 2 import HTMLTestRunner 3 4 #相對路徑 5 testcase_path = ".\\testcase" 6 report_path = ".\\report\\report.html" 7 def creat_suite(): 8 uit = unittest.TestSuite() 9 discover = unittest.defaultTestLoader.discover(testcase_path,pattern="test_*.py") 10 for test_suite in discover: 11 # print(test_suite) 12 for test_case in test_suite: 13 uit.addTest(test_case) 14 return uit 15 16 suite = creat_suite() 17 fp = open(report_path,"wb") 18 runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title="測試結果",description="測試搜索結果") 19 runner.run(suite) 20 fp.close()
解決報告命名的問題:
1 now = time.strftime("%Y-%m-%d-%H-%M-%S",time.localtime(time.time())) 2 print(now) 3 report_path = ".\\report\\"+now+"report.html"
測試報告截圖:
search_page.py
1 from selenium.webdriver.common.by import By 2 from seleniumframework.PO import base_page 3 4 #繼承base後既可以調用base的方法也可自己添加新的方法 5 class SearchPage(base_page.Action): 6 7 #通過id進行定位元素 8 search_loc = (By.ID,"kw") 9 10 def run_case(self,value): 11 #第一種利用原生的send_keys方法 12 self.find_element(*self.search_loc).send_keys(value) 13 14 #第二種利用二次封裝的send_keys方法 15 # self.send_keys(self.search_loc,value)
test_search.py
1 import unittest 2 from selenium import webdriver 3 from seleniumframework.PO.search_page import SearchPage 4 import time 5 6 class TestBaiduSearch(unittest.TestCase): 7 """UI自動化搜索""" 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 time.sleep(5) 16 self.driver.quit() 17 self.assertEqual([],self.verificationErrors) 18 19 def test_search(self): 20 """搜索測試關鍵字""" 21 sp = SearchPage(self.driver) 22 sp.open(self.url) 23 sp.run_case("測試")