背景
為了更好的發展自身的測試技能,應對測試行業以及互聯網行業的迭代變化。自學python以及自動化測試。
雖然在2017年已經開始接觸了selenium,期間是斷斷續續執行自動化測試,因為還有其他測試任務,培訓任務要執行…
前期建議大家能夠學習python基本語法(python基礎教程)
任務
搭建自動化測試框架,并能有效方便的進行測試,維護成本也要考慮其中。
過程
我的自動化框架可能不成熟,因為是自學的。請多包涵。也請大佬指導~

common
包含:基本的公共方法類,比如HTML報告、Log處理、發送郵件、基本頁面對象等
其中pageObject里面是對各個測試系統操作頁面的一個封裝,以后用例的方法直接繼承即可??啥啻握{用,維護起來比較方便。
conf
基本的系統參數配置信息,可以包含url,正確用戶的信息,簡單日志級別,某些輸出位置,郵件信息等
data
對于數據驅動或者其他測試用例中需要測試的數據,之后測試用例流程不變,可以直接在文檔中進行測試數據的修改。暫時采用excel。也可以采用csv,xml等等方法
log
日志輸出,暫時包括了 log輸出,htmlreport輸出以及img的保存。
test
其中包含testcase以及testsuite兩個模塊
testcase 負責編寫測試用例如果某個功能有多個py文件編寫可以再新建一個目錄。
testsuite 就是測試套件,可以按需求進行選擇需要的測試項(包含測試用例以及測試類)
注意:使用ddt則不可以再使用addTest方式單獨添加測試用例了。
1
代碼部分
- common中的BasePage
class BasePage():
global logg
logg = LogHandler().logger
def __init__(self,driver,url=None):
self.wd = driver
self.wd.implicitly_wait(5)
self.actions = ActionChains(self.wd)
if url :
self.url = url
else:
self.url = self.server_url_conf()
#瀏覽器行為的一些方法
def get_conf_url(self):
self.wd.get(self.url)
self.wd.maximize_window()
logg.debug("enter conf_url : " + str(self.url))
def brower_close(self):
return self.wd.close()
def brower_quit_all(self):
return self.wd.quit()
... 下面還有刷新,前進后退等
#定位 這里通過 By.xx 方法
def find_web_element(self,*loc):
#self.wd.find_element(*loc)
return self.wd.find_element(*loc)
#元素操作
def type_text(self,loc,text):
return self.wd.find_element(*loc).send_keys(text)
def clear_text(self,*loc):
return self.wd.find_element(*loc).clear()
def submit_func(self,*loc):
return self.wd.find_element(*loc).submit()
def click_btn(self,*loc):
return self.wd.find_element(*loc).click()
#鼠標相關
def mouse_move_to_element(self,*loc):
elem = self.find_web_element(*loc)
self.actions.move_to_element(elem).perform()
... 下面還有點擊,雙擊,右擊的一些方法
#獲取信息行為
def get_web_url(self):
return self.wd.current_url
def get_title(self):
return self.wd.title
def get_element_text(self,*loc):
return self.find_web_element(*loc).text
#元素是否存在 是 True
def check_element_isexist(self,loc):
isexist = False
try:
EC.presence_of_element_located(loc)(self.wd)
isexist = True
except Exception as e:
isexist = False
logg.debug(' isexist or not :',exc_info = True)
return isexist
def check_element_has_text(self,loc,text):
pass #省略
def check_element_isdisplayed(self,*loc):
pass #省略
#生成圖
def __inser_img(self,passorfailed,imgname):
time_loc = time.strftime("%m%d_%H%M%S",time.localtime())
file_path = os.path.abspath(__file__)
file_path = os.path.join(file_path+"/../../log/%s_%s.png" %(imgname,time_loc))
self.wd.get_screenshot_as_file(file_path)
logg.debug('insert_%s_img %s ' %(passorfailed,(file_path)))
def insert_error_img(self,imgname):
self.__inser_img("error",imgname)
def insert_success_img(self,imgname):
self.__inser_img("success",imgname)
def insert_debug_img(self,imgname):
self.__inser_img("debug",imgname)
def server_url_conf(self):
self.host = readconfig.ReadConfig().getserver('host')
self.port = readconfig.ReadConfig().getserver('port')
urlvalue = self.host + ":" + self.port
return urlvalue
if __name__ == '__main__':
test = BasePage(webdriver.Chrome())
test.get_conf_url()
common中登錄頁的頁面對象
包含了頁面的一些方法比如
輸入用戶名,輸入密碼,點擊登錄
test中的 logintestcase
則直接使用 登錄頁面對象的 輸入用戶名,輸入密碼,點擊登錄即可
后期維護,如果元素變動,則只需要修改頁面對象代碼而對用例則無需修正
class AioLogin(BasePage):
global logg
logg = LogHandler().getlog()
username_loc = (By.NAME, "username")
password_loc = (By.CSS_SELECTOR, "input[type='password']")
login_loc = (By.CLASS_NAME, "login-btn")
login_loc_oem = (By.ID,"submit")
check_login_loc = (By.CLASS_NAME,"error-tip")
elements = [username_loc,password_loc,login_loc,check_login_loc]
log_menu = (By.CSS_SELECTOR,"[name='log']")
logg.debug(elements)
def set_username(self,username):
self.clear_text(*self.username_loc) #直接使用BasePage的方法
self.type_text(self.username_loc,username)
logg.info('Enter username: ' + username)
sleep(0.1)
... 其他
logintest
這里使用了ddt數據驅動方法
from ddt import data,ddt,unpack
@ddt
class TestLogin(unittest.TestCase):
global logg
logg = LogHandler().getlog()
@classmethod #該類方法,執行中只會啟動一次。區別于setUp的 每個用例都執行一遍
def setUpClass(cls):
cls.test = aiologinpage.AioLogin(webdriver.Chrome())
cls.test.get_conf_url()
# print('start TestSearch')
@classmethod
def tearDownClass(cls):
# TestLogin().logg.info("brower quit")
TestLogin().test.brower_close()
pass
logindata = ReadExcel().getValue('login')
@data(*logindata)
@unpack #當有多組數據時,需要unpack
def testcase2(self,username,passwd,result):
logg.info(username+" " + passwd +" " +str(result))
self.test.set_username(username) #用例直接使用登錄頁面對象,后期除了修改測試用例,否則無需變動
self.test.set_password(passwd)
self.test.type_login_btn()
# 斷言登錄結果和預期結果是否一致
self.assertTrue(self.test.check_login_result(result),
msg="\r login_test fail \r username :%s \r passwd : %s " %(username,passwd))
if __name__ == '__main__':
unittest.main()
其他頁面
比如我有個 創建設備分組的頁面
我必須要先登錄才可以執行下面的操作
此時,可以從conf中獲取成功登錄的用戶名和密碼,把correct_login方法寫在登錄頁面對象中。
def correct_login(self): self.get_conf_url() self.userpasswd = self.correct_userpasswd_conf() self.set_username(self.userpasswd[0]) self.set_password(self.userpasswd[1]) self.type_login_btn()
之后,其他頁面初始化時候直接調用這個correct_login即可登錄
測試套件添加方法
TestSuite方法
#添加一個類
st1 = unittest.makeSuite(TestLogin)
#單獨添加多個用例
st = unittest.TestSuite(map(TestClassName,[‘testcase1',‘testcase2']))
st = unittest.TestSuite(TestClaseeName(‘testcase1'))#添加一個或者多個測試用例
st2 = unittest.TestSuite()
st2.addTests(map(TestCaseClassName,[‘testcase2',‘testcase1']))
st2.addTest(TestCaseClassName(‘testcase1'))
#添加一個類
st2.addTest(unittest.makeSuite(TestClassName))TestLoader 方法
discovery 發現腳本
st = unittest.TestLoader().discovery(“dir_path”,pattern=“a*.py”)#loadTestFromTestCase 加載 測試類
st1 = unittest.TestLoader().loadTestsFromTestCase(TestLoginCheck)
st2 = unittest.TestLoader().loadTestsFromTestCase(TestLogin)
stt = unittest.TestSuite()
stt.addTests([st1,st2])
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。