Python的selenium自動化測試腳本(關於web版數據庫客戶端)

Python的selenium自動化測試腳本

本次主題是測試新版的一個web版的數據庫客戶端,適用於各種主流數據庫,測試的目的:主要測試各種sql的執行情況,後根據結果針對性的優化;附上運行錄屏地址

總體思路步驟:
1.加載不同數據庫類型的測試案例,組成不同list;
2.登錄系統,由於無法點擊到執行sql頁面,所以指定輸入網址到達指定頁面;
3.清空所有執行窗口,由於系統自動保存執行窗口,所以輸入窗口刷新到統一的狀態;
4.循環點擊數據庫標籤,打開這個數據庫的sql執行窗口,根據數據庫類型選擇測試案例;
5.循環sql執行:循環測試案例,其中重複操作爲—點擊編輯框,輸入sql,點擊運行,獲取結果,清空輸入的sql,刷新窗口;
6.結果處理:獲取的結果和測試案例信息組成新的list,寫入結果文件,異常結果截圖保存文件目錄;
7.循環測試所有的數據源,循環結束,sql結束;

本次開發總結,會在代碼塊做註釋:
1.在有些標籤無法點擊或者無法獲取時,可以繞開點擊,如果有固定網址一樣可以輸入網址到達指定頁面;
2.在菜單欄固定區域的標籤獲取時,可以用循環判斷標籤內容,後期變動或者修改簡單;
3.如果一個功能按鈕可能出現在多個標籤位置時,可以嘗試用try捕捉,但是如果是3個位置時,還未想到辦法;
4.對於需要顯示等待的事件或者結果,也可以判斷反饋結果,如果有結果就跳出while True,如果沒有結果循環等待;
5.對於變化的標籤時,如果我們每次操作固定,那就可以讓變化的便籤都刷新成統一狀態,這樣便於操作,因爲我們的目的是測試sql的執行結果,要的是結果而不是這個頁面變化而產生的BUG;

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from lxml.html import fromstring, tostring
from lxml import etree
import time
import xlrd
from xlrd import xldate_as_tuple
import csv
import numpy as np
import os
from datetime import datetime, date, timedelta



def check_executesql(screenshot_path,mysql_testsqllist,oracle_testsqllist,db2_testsqllist):
#在執行平臺,查詢各個sql結果,有結果的獲取結果存入excel文檔,異常信息進行截圖及獲取信息;
    sqllist=[]
    sqltoday=str(time.strftime('%Y-%m-%d-%h:%m',time.localtime()))
    sqlday=str(time.strftime('%Y-%m-%d',time.localtime()))
    # input()
    filename='tablespace-'+sqltoday
    sqllist=["sql",filename]
    driver=webdriver.Chrome()
    # driver=webdriver.Firefox()
    driver.get("http://9.1.10.129:8888/login/")
    #將瀏覽器最大化顯示
    driver.maximize_window()
    # 填充用戶名 密碼 驗證碼
    # driver.find_element_by_id("username").send_keys("pengwu")
    # driver.find_element_by_id("password").send_keys("123456")
    
    driver.find_element_by_xpath('//input[@placeholder="請輸入用戶名"]').send_keys('test')
    driver.find_element_by_xpath('//input[@placeholder="請輸入密碼"]').send_keys('123456')
    # 點擊登錄 登陸成功
    # driver.find_element_by_class_name("ant-btn ant-btn-primary ant-btn-lg").click()
    driver.find_element_by_xpath("//button").click()
    time.sleep(2)
    #這個用到1,由於無法點擊到目標標籤,沒轍只能數據網址跳轉到指定頁面
    driver.get("http://9.1.10.129:8888/hermes/workspace/")
    time.sleep(3)
    # 點擊工作臺,用循環式,利於後期遷移或修改
    benchs=driver.find_elements_by_xpath('//ul[@role="menubar"]/div')
    for bench in benchs:
        benchvalue=bench.text
        # 所有執行平臺標籤
        # print('執行平臺標籤',benchvalue)
        #獲取文件
        if '工作臺'==benchvalue:
            bench.click()
            time.sleep(2)
            #所有數據源標籤名稱
            databases=driver.find_elements_by_xpath('//div[@class="tree_3hqfs"]/main/section[1]/div/div')
            print('數據源個數:',len(databases))
            sqllist=[]
            for i in range(1,len(databases)+1):
                # 每次選擇新的數據源前,先把輸入框全部刪除
                # 由於獲取編輯框數量隨着關閉減少,所以按照標籤個數刪除異常,所以永遠刪除標籤爲3的編輯框,直到編輯框個數爲0;
                sqlexecutes=driver.find_elements_by_xpath('//div[@class="ivu-tabs-nav-wrap"]/div/div')
                print('清空sql執行區域個數:',len(sqlexecutes)-2)
                for x in range(len(sqlexecutes)-2):
                    se=driver.find_elements_by_xpath('//div[@class="ivu-tabs-nav-wrap"]/div/div')
                    if len(se)>2:
                        driver.find_element_by_xpath('//div[@class="ivu-tabs-nav-wrap"]/div/div[3]').click()
                        driver.find_element_by_xpath('//div[@class="ivu-tabs-nav-wrap"]/div/div[3]/div/i').click()
                        
                dbname=driver.find_element_by_xpath('//div[@class="tree_3hqfs"]/main[%i]/section[1]//span' % i).text
                print('數據源標籤名稱:',dbname)
                time.sleep(2)
                driver.current_window_handle
                # 點擊數據源,打開編輯框
                driver.find_element_by_xpath('//div[@class="tree_3hqfs"]/main[%s]/section[1]' % i).click()
                # 獲取數據庫類型
                dbtype=driver.find_elements_by_xpath('//div[@class="ivu-split-vertical"]/div[1]/section/div/section[2]/span')
                typels=[ d.text for d in dbtype]
                print('數據庫信息',typels)
                # print(typels[-1].split(":")[-1].strip())
                if typels[-1].split(":")[-1].strip()=='mysql':
                    sqllist=mysql_testsqllist
                elif typels[-1].split(":")[-1].strip()=='oracle':
                    sqllist=oracle_testsqllist
                elif typels[-1].split(":")[-1].strip()=='db2':
                    sqllist=db2_testsqllist
                # 組裝結果集文件名稱及填充表頭
                result_filename=screenshot_path+dbname+'-'+typels[-1].split(":")[-1].strip()+'.csv'
                print('保存結果集文件',result_filename)
                writecsv([sqllist[0]],result_filename)
                for i in range(1,len(sqllist)):
                    resultlist=[]
                    # 點擊編輯框
                    driver.find_element_by_xpath('//div[@class="editor_2FiuW"]').click()
                    time.sleep(1)
                    # print('點擊編輯框')
                    driver.find_element_by_xpath('//textarea[@autocorrect="false"]').send_keys(sqllist[i][2])
                    time.sleep(1)
                    try:
                        #由於執行按鈕動態變化,所以需要設置2個,
                        # print('點擊執行執行按鈕')
                        driver.find_element_by_xpath('//div[@class="ivu-split-vertical"]/div[1]/section/div/section[1]/span/span/div[2]').click()
                    except Exception as e:
                        driver.find_element_by_xpath('//div[@class="ivu-split-vertical"]/div[1]/section/div/section[1]/div[1]').click()
                    time.sleep(1)
                    try:
                        # 不一定有二次確認的按鈕
                        driver.find_element_by_xpath('//div[@role="tooltip" and @x-placement="bottom"]//button[2]').click()
                        time.sleep(2)
                    except Exception as e:
                        print('無二次確認按鈕')
                        # pictures=driver.get_screenshot_as_file(screenshot_path+dbname+'-1.png')
                    #循環等待結果,
                    while True:
                        result=driver.find_element_by_xpath('//div[@class="bottom-tab_3KIIY"]/div/div[2]').text
                        if result:
                            result=result.replace("\n",' ').strip()
                            # print(result)
                            #判讀關鍵字截圖
                            tr='耗時' in result
                            if not tr:
                                pname=screenshot_path+dbname+'-'+typels[-1].split(":")[-1].strip()+'-'+str(int(sqllist[i][0]))+'.png'
                                print('異常執行結果截圖:',pname)
                                pictures=driver.get_screenshot_as_file(pname)
                            break
                    # 填充結果集數據
                    resultlist.append([str(int(sqllist[i][0])),sqllist[i][1],sqllist[i][2],sqllist[i][3],result])
                    print(resultlist)
                    writecsv(resultlist,result_filename)
                    # 清理輸入框中的sql信息
                    driver.find_element_by_xpath('//div[@class="editor_2FiuW"]').click()
                    driver.find_elements_by_xpath('//div[@class="ivu-split-vertical"]/div[1]/section/div/section[1]/div')[-2].click()
                    # 刷新獲取焦點,清空結果集數據,將輸入框刷新成統一狀態便於操作
                    driver.refresh()
                    time.sleep(2)
                    #點擊數據庫的編輯框標籤
                    driver.find_element_by_xpath('//div[@class="ivu-tabs-nav-wrap"]/div/div[3]').click()
            break
    print('工作臺的所有sql測試完畢,關閉瀏覽器!')
    driver.quit()


def readexl(filename):
    print('加載測試文件',filename)
    data=xlrd.open_workbook(filename)
    table=data.sheets()[0]
    # print(table.name,table.nrows,table.ncols)
    x=table.nrows
    y=table.ncols
    print('文件行列,rows:',x,',cols:',y)
    # print('標題:',table.cell(0,0).value)
    resultlist=[]
    for i in range(0,x):
        ls=[]
        for j in range(0,y):
            type=table.cell(i,j).ctype
            cell=table.cell_value(i,j)
            # print(cell,end=" ")
            ls.append(cell)
        resultlist.extend([ls])
    return resultlist

def readcsv_data(database_file):
    #讀取文件csv格式
    # print('讀取文件csv格式,加入數據篩選',database_file)
    # filepath,tempfilename=os.path.split(database_file)
    # filename,extension=os.path.splitext(tempfilename)
    # filename,d=filename.split("-")
    database_list=[]
    #讀取文件,獲取id和系統名稱字典
    # print('讀取文件',database_file,'\n')
    with open(database_file,encoding='utf-8') as csvfile:
        csv_reader = csv.reader(csvfile)  # 使用csv.reader讀取csvfile中的文件
        birth_header = next(csv_reader)  # 讀取第一行每一列的標題
        for row in csv_reader:  # 將csv 文件中的數據保存到birth_data中
            database_list.append(row)
    print('讀取文件',database_file,'獲取數據文件行數:',len(database_list),'\n')
    return database_list

def writecsv(lists,file):
#寫入到csv文件中
    with open(file,'a+', newline='') as csvwrite:
        csv_write=csv.writer(csvwrite)
        for ls in lists:
            csv_write.writerow(ls)

def main():
    # 截圖保存位置
    screenshot_path='D:\\SQLEXECUTE\\'
    #獲取各種數據庫測試樣例
    mysql_testfile='D:\\SQLEXECUTE\\mysql測試樣例.xlsx'
    oracle_testfile='D:\\SQLEXECUTE\\oracle測試樣例.xlsx'
    db2_testfile='D:\\SQLEXECUTE\\db2測試樣例.xlsx'
    
    mysql_testsqllist=readexl(mysql_testfile)
    oracle_testsqllist=readexl(oracle_testfile)
    db2_testsqllist=readexl(db2_testfile)
    check_executesql(screenshot_path,mysql_testsqllist,oracle_testsqllist,db2_testsqllist)

if __name__=='__main__':
    main()


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章