1,遇見問題
在進(jìn)行 web 自動化測試的時候,經(jīng)常會碰到一些加載非常慢的頁面。這些頁面加載之所以慢有很多種原因:
- 頁面本來就有非常多資源需要加載,通常是首頁;
- 頁面使用了一些不是很穩(wěn)定的外部依賴,比如調(diào)用了不成熟的 css 樣式庫和 js 庫;
- 公司服務(wù)器處理能力有限;
- 開發(fā)人員的代碼寫得不好,等等。
2,分析問題
如果我們想進(jìn)行自動化測試,首先需要通過 webdriver 的 get 方法打開頁面,但是因為頁面加載時間過長,后面的操作無法進(jìn)行,甚至直接報錯, 對自動化測試的運(yùn)行效率影響非常大。
class TestLogin(unittest.TestCase):
def test_login_success(self):
# 初始化瀏覽器
driver = webdriver.Chrome()
driver.implicitly_wait(20)
url = 'http://lemonban_url'
driver.get(url)
# 登錄
driver.find_element_by_name('phone').send_keys(current_phone)
pwd_elem = driver.find_element_by_name('password')
pwd_elem.send_keys(current_pwd)
pwd_elem.send_keys(Keys.ENTER)
# 實際結(jié)果
actual = driver.find_element_by_xpath('//img[@class="mr-5"]/..')
# 斷言
self.assertIn('小小鳥', actual.text)
當(dāng)在進(jìn)行實際結(jié)果獲取的時候,占用了大量時間等待首頁正確加載,雖然后面測試用例通過。但是造成了大量時間浪費(fèi),運(yùn)行一個測試用例花費(fèi) 26.5 秒。
3,解決問題
對于一些加載比較慢的資源,在進(jìn)行自動化測試的時候沒有必要等到所有的元素加載完成,再進(jìn)行元素定位。
設(shè)置一個超時時間,如果頁面加載超過了指定時間,手工終止頁面,相當(dāng)于用手點(diǎn)擊瀏覽器的 X 按鈕,讓頁面停止加載。
# 設(shè)置加載超時時間為 5 s
driver.set_page_load_timeout(5)
try:
return driver.get(url)
except TimeoutException:
# 調(diào)用 js 腳本終止頁面加載
driver.execute_script("window.stop()")
代碼有 3 個點(diǎn):
- 1, 設(shè)置超時時間為 5 秒
- 2, 執(zhí)行 driver.get(url) 時,頁面加載如果不超過 5 秒,不會報錯,超過 5 秒,會拋出超時異常
- 3, 使用 TimeoutException 捕獲超時異常。當(dāng)超時后,執(zhí)行 js 指定,終止頁面加載。
接下來,封裝頁面 get 方法:
class IndexPage():
url = 'http://lemonban'
def __init__(self, driver, load_timeout=5):
self.driver = driver
self.driver.set_page_load_timeout(load_timeout)
def get(self):
try:
return self.driver.get(self.url)
except TimeoutException:
self.driver.execute_script("window.stop()")
修改原來的自動化腳本:
class TestLogin(unittest.TestCase):
def test_login_success(self):
# 初始化瀏覽器
driver = webdriver.Chrome()
driver.implicitly_wait(20)
url = 'http://lemonban_url'
driver.get(url)
# 登錄
driver.find_element_by_name('phone').send_keys(current_phone)
pwd_elem = driver.find_element_by_name('password')
pwd_elem.send_keys(current_pwd)
pwd_elem.send_keys(Keys.ENTER)
# 實際結(jié)果
IndexPage(driver).get()
actual = driver.find_element_by_xpath('//img[@class="mr-5"]/..')
# 斷言
self.assertIn('小小鳥', actual.text)
4, 總結(jié)問題
其他的代碼都不需要發(fā)生變化,只需要在加載耗時的地方添加 IndexPage(driver).get() 讓頁面按照設(shè)置的超時時間加載就可以了。
新的測試時間為 11.3 秒, 測試效率提升將近 60%。不說了,我得趕緊把這個解決方案整合到簡歷里去。