selenium+python之自動換測試用例執行


1.一個用例為一個完整的場景,從用戶登陸系統到最終退出並關閉瀏覽器。

2.一個用例只驗證一個功能點,不要試圖在用戶登陸系統后把所有的功能都驗證一遍。

3.盡可能少的編寫逆向邏輯用例。一方面因為逆向邏輯的用例很多(例如。手機號輸錯有十幾種情況);另外一方面自動化本身比較脆弱,復雜的逆向邏輯用例實現起來比較麻煩且容易出錯。

4.用例與用例之間盡量避免產生依賴。

5.一條測試用例完成測試后需要對測試場景進行還原,以避免影響其他測試用例的執行。

driver.py

 1 from selenium.webdriver import Remote
 2 from selenium import webdriver
 3 
 4 
 5 # 啟動瀏覽器驅動
 6 def browser():
 7     # driver = webdriver.Firefox()
 8     host = '127.0.0.1:4444'  # 運行主機:端口號(本機默認:127.0.0.1:4444)
 9     dc = {'browserName': 'firefox'}  # 指定瀏覽器('chrome','firefox')
10     driver = Remote(command_executor = 'http://' + host + '/wd/hub,desired_capabilities = dc')
11     return driver
12 if __name__ == '__main__':
13     dr = browser()
14     dr.get('http://www.baidu.com')
15     dr.quit()

 定義瀏覽器驅動函數browser()該函數可以進行配置,根據我們的需求,配置測試用例在不同的主機及瀏覽器下運行。

2.自定義測試框架類:

 1 from selenium import webdriver
 2 from .driver import browser
 3 import unittest
 4 import os
 5 
 6 
 7 class MyTest (unittest.TestCase):
 8     def setUp(self):
 9         self.driver = browser ()
10         self.driver.implicitly_wait (10)
11         self.driver.maximize_window ()
12 
13     def tearDown(self):
14         self.driver.quit ()

定義MyTest()類用於繼承unittest.TestCase類,因為創建的所有測試類中setUp()與tearDown()方法所做的事情相同。所以將他們抽象為MyTest()類,好處就是編寫測試用例不再去考慮這兩個方法的實現。

3.定義截圖函數

獲取路徑參考:https://www.cnblogs.com/wuxie1989/p/5623435.html

from selenium import webdriver
import os


# 截圖函數
def insert_img(driver, file_name):
# 獲取路徑名:os.path.dirname() 獲取文件所在目錄的完整路徑:os.path.dirname(__file__)
base_dir = os.path.dirname(os.path.dirname(__file__))
print(base_dir)
base_dir = str(base_dir) # 將地址轉為字符串
print(base_dir)
base_dir = base_dir.replace('/', '\\')
print(base_dir)
base = base_dir.split('/test_case')[0] # 以/test_case為分隔符,取第一個分割的部分
print(base)
file_path = base + "\\report\\image\\" + file_name
print(file_path)
driver.save_screenshot(file_path)


if __name__ == '__main__':
driver = webdriver.Firefox()
driver.get("https://www.baidu.com")
insert_img(driver, 'baidu.png')
driver.quit()

創建截圖函數insert_img(),為了保持自動化項目的移植性,采用相對路徑的方法hi將測試截圖保存到.\report\image\目錄中

注:運行代碼沒有錯,但是卻無法獲得截圖保存路徑?????(望知道原因的留言指點)

編寫Page Object

首先創建基礎類:E:\python\mztestpro\bbs\test_case\page_obj\base.py

 

class Page (object):
"""
頁面基礎類,用於所有頁面的繼承
"""
bbs_url = 'http://bbs.meizu.cn'

def __init__(self, selenium_driver, base_url=bbs_url, parent=None):
self.base_url = base_url
self.driver = selenium_driver
self.timeout = 30
self.parent = parent

def __open(self, url):
url = self.base_url + url
self.driver.get(url)
assert self.on_page(), 'did not land on %s' % url

def find_element(self, *loc):
return self.driver.find_element(*loc)

def open(self):
self.__open(self.url)

def on_page(self):
return self.driver.current_url == (self.base_url + self.url)

def script(self, src):
return self.driver.execute_script(src)

 創建頁面基礎類,通過_init_()方法初始化參數:瀏覽器驅動,URL地址,超時時長等。定義的基本方法:open()用於打開BBS地址;find_element()和find_element()分別用來定位單個與多個

元素;創建script()方法可以更簡便的調用JavaScript代碼。

創建BBS登錄對象類:

E:\python\mztestpro\bbs\test_case\page_obj\loginPage.py

 1 from selenium.webdriver.common.action_chains import ActionChains
 2 from selenium.webdriver.common.by import By
 3 from time import sleep
 4 import base
 5 
 6 
 7 class login (base.Page):
 8     """
 9     用戶登錄界面
10     """
11     url = '/'
12     # Action
13     bbs_login_user_loc = (By.XPATH, "//div[@id='mzCust']/div/img")
14     bbs_login_button_loc = (By.ID, "mzLogin")
15 
16     def bbs_login(self):
17         self.find_element (*self.bbs_login_user_loc).click ()
18         sleep (3)
19         self.find_element (*self.bbs_login_button_loc).click ()
20 
21     login_username_loc = (By.ID, "account")
22     login_password_loc = (By.ID, "password")
23     bbs_login_button_loc = (By.ID, "login")
24 
25     # 登錄用戶名
26     def login_username(self, username):
27         self.find_element (*self.login_username_loc).send_keys (username)
28 
29     # 登錄密碼
30     def login_password(self, password):
31         self.find_element (*self.login_password_loc).send_keys (password)
32 
33     # 登錄按鈕
34     def login_button(self):
35         self.find_element (*self.login_password_loc).click ()
36 
37     # 定義統一登錄接口
38     def user_login(self, username="username", password="111"):
39         # 獲取用戶名與登錄密碼
40         self.open ()
41         self.bbs_login ()
42         self.login_username (username)
43         self.login_password (password)
44         self.login_button ()
45         sleep (1)
46 
47     user_error_hint_loc = (By.XPATH, "//span[@for = 'account']")
48     pawd_error_hint_loc = (By.XPATH, "//span[@for = 'password']")
49     user_login_success_loc = (By.ID, "mzCustName")
50 
51     # 用戶名錯誤提示
52     def user_error_hint(self):
53         return self.find_element (*self.user_error_hint_loc).text
54         # 密碼錯誤提示
55 
56     def paw_error_hint(self):
57         return self.find_element (*self.pawd_error_hint_loc).text
58 
59     # 登錄成功用戶名
60     def user_login_success(self):
61         return self.find_element (*self.user_login_success_loc).text
62 
63 創建登錄頁面對象,對用戶登錄面上的用戶名/密碼輸入框,登錄按鈕和提示信息等元素的定位進行封裝。除此之外,還創建user_login()方法作為系統統一登錄的入口。關於對操作步驟的封裝
64 既可以放在page object當中,也可以放在測試用例當中。這主要根據具體需求來衡量。這里之所以存放在Page_object當中,主要考慮到還有其他用例會挑用到該登錄方法。
65 為username和password
66 入參設置了默認值是為了方便其他測試y用例在調用user_login()時不用再傳遞登錄用戶信息,因為該系統大多用例的執行使用該賬號即可,同時也方便了在這賬號失效時的修改。

編寫測試用例

編寫測試用例時會集中精力考慮用例的設計和實現。

 路徑:E:\python\mztestpro\bbs\test_case\login_sta.py

此處注意文件名的創建。例如:假設登錄頁的對象名為loginPage.py,那么關於測試登錄的文件應該命名為login_sta.py,方便用例報錯時問題的追蹤。

 1 import random
 2 import sys
 3 import unittest
 4 from time import sleep
 5 
 6 sys.path.append("./models")
 7 
 8 import myTest
 9 import function
10 from myunit import *
11 
12 sys.path.append("./page_obj")
13 from loginPage import *
14 
15 
16 class loginTest(myunit.myTest):
17     """ 社區登錄測試 """
18 
19     # 測試用戶登錄
20     def user_login_verify(self, username="", password=""):
21         login(self.driver).user_login(username, password)
22 
23     def test_login(self):
24         """用戶名、密碼為空登錄"""
25         self.user_login_verify()
26         po = login(self.driver)
27         self.assertEqual(po.user_error_hint(), "賬號不能為空")
28         self.assertEqual(po.pawd_error_hint(), "密碼不能為空")
29         function.insert_img(self.driver, "user_pawd_empty.jpg")
30 
31     def test_login2(self):
32         """用戶名正確,密碼為空登錄"""
33         self.user_login_verify(username="py1test")
34         po = login(self.driver)
35         self.assertEqual(po.pawd_error_hint(), "密碼不能為空")
36         function.insert_img(self.driver, "pawd_empty.jpg")
37 
38     def test_login3(self):
39         """用戶名為空,密碼正確"""
40         self.user_login_verify(password="abc123456")
41         po = login(self.driver)
42         self.assertEqual(po.user_error_hint(), "賬號不能為空")
43         function.insert_img(self.driver, "user_empty.jpg")
44 
45     def test_login4(self):
46         """用戶名與密碼不匹配"""
47         character = random.choice('wqwertyuiop')
48         username = "zhangsan" + character
49         self.user_login_verify(username=username, password='123456')
50         po = login(self.driver)
51         self.assertEqual(po.pawd_error_hint(), "密碼與賬號不匹配")
52         function.insert_img(self.drive.jpg)
53 
54     def test_login5(self):
55         """用戶名、密碼正確"""
56         self.user_login_verify(username="zhangsan", password="123456")
57         sleep(2)
58         po = login(self.driver)
59         self.assertEqual(po.user_login_success(), "張三")
60         function.insert_img(self.driver, "user_pawd_ture.jpg")
61 
62 
63 if __name__ == "__main__":
64     unittest.main()

注:上面代碼運行會有報錯,可以引入模塊換為:

import random
import sys
import unittest
from time import sleep

from test_case.page_obj.loginPage import login
from test_case.models.function import insert_img
from test_case.models.myunit import MyTest

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM