日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用selenium + pytest + allure做WBE UI自动化

發布時間:2023/12/20 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用selenium + pytest + allure做WBE UI自动化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄結構

依然使用了常見的po 模式

  • 目錄結構
    • config
      • config.ini 修改目標路由與相關配置
    • elements
      • 抽象頁面空間元素
    • method
      • 抽象頁面方法
    • TestCase
      • 測試用例
    • utils
      • Assert 自定義斷言
      • chromedriver 瀏覽器驅動 需匹配版本 非linux 環境無視
      • Driver 初始化driver
      • graphical 圖片相對定位
      • log 日志
      • seleniumBase api封裝
      • seleniumOpt opt定義

初始化Driver

根據判斷運行環境 選擇不同的chrome driver 或者使用 ChromeDriverManager 自動下載

class Driver:@classmethoddef driver(cls):try:# select local or docker# if platform == "Darwin":# url = Config().get_conf("dockerHub", "url")# driver = webdriver.Remote(url, desired_capabilities=capabilities(),# options=options())# # else:if platform.system() == "Linux":executable_path = os.path.join(os.path.dirname(__file__), "chromedriver")driver = webdriver.Chrome(executable_path=executable_path, options=options())else:executable_path = ChromeDriverManager().install()driver = webdriver.Chrome(executable_path=executable_path, options=options())driver.implicitly_wait(20)log.info(f"driver:{driver.name}")return driverexcept BaseException as e:log.error(e)raise e

自定義driver 的options 配置

def options():"""瀏覽器設置:return:"""_options = ChromeOptions()# # 設置chrome為手機界面# mobileEmulation = Config().get_conf("seleniumOpt", "mobileEmulation")# if mobileEmulation == 'true':# mobile_emulation = {"deviceName": "Galaxy S5"}# _options.add_experimental_option("mobileEmulation", mobile_emulation)if platform.system() == 'Darwin':passelse:_options.add_argument('--headless')_options.add_argument('--no-sandbox')_options.add_argument('--disable-gpu')_options.add_argument('--disable-dev-shm-usage')return _options

Base類

封裝常用API 把driver 實例化傳入
查找元素盡量使用顯示等待 expected_conditions
使用了Faker 可隨意生成測試數據
查找元素失敗 使用allure 上傳截圖

class SeleniumBaseConfig:faker = Faker(locale="zh_CN")Assert = Assertlog = get_log()def __init__(self, driver: webdriver):""":param driver: 驅動"""self.driver = driverdef find_element(self, locator: tuple, timeout=5):"""find_element:param locator: (xpath,xxx)(id,xxx):param timeout: timeout:return:"""try:element = WebDriverWait(self.driver, timeout).until(EC.presence_of_element_located(locator))self.log.info(f"[{self.find_element.__name__}] locator: {locator} element: {str(element)}")return elementexcept WebDriverException as e:self.log.error(e)allure.attach(self.get_png(), "異常截圖", allure.attachment_type.PNG)allure.attach("未找到: {}, 詳細信息如下: {}".format(locator, e))raise e

自定Assert

很常規 沒什么可說的

class Assert:@staticmethoddef assert_unequal(exp, res):try:log.info("ASSERT UNEQUAL: EXPECT IS [{}] RESULT IS [{}]".format(exp, res))assert exp != resreturn Trueexcept AssertionError as e:log.error("ASSERT UNEQUAL ERROR: EXPECT IS [{}] RESULT IS [{}]".format(exp, res))raise e

關于頁面元素

根據op 依舊對頁面抽象成類 并繼承SeleniumBaseConfig
元素類1一對1配套

class RegisterMethod(SeleniumBaseConfig):def __init__(self, driver):super().__init__(driver)def register(self, mobile: str):"""注冊:param mobile:return:"""self.send_keys(RegisterLogin.INPUT_NUMBER, mobile)self.click(RegisterLogin.NEXT_STEP_BUTTON)time.sleep(1)

對應元素類

class Register:# ================== 公共 ================# 下一步NEXT_STEP_BUTTON = ("xpath", "//button")# 返回RETURN = ('xpath', '//p[@class="return-prev-step"]')# input 錯誤信息INPUT_ERROR_INFO = ("xpath", '//p[@class="default-input-error"]')# ================== home界面 ================CREATE_BUTTON = ("xpath", "//div[text()='創建']") # 創建buttonJOIN_BUTTON = ("xpath", "//div[text()='加入']") # 創建buttonINPUT_TEAM_NAME = ("xpath", '//input[@placeholder="請輸入團隊名稱"]') # 輸入團隊名稱INPUT_YOUR_NAME = ("xpath", '//input[@placeholder="請輸入你的姓名"]') # 輸入個人名稱

測試用例

@pytest.mark.P3@allure.title("創建新團隊:姓名輸入漢字、英文、數字字符")@pytest.mark.flaky(reruns=1, reruns_delay=2)def test_create_team_username(self):"""姓名輸入漢字、英文、數字字符1.register2.create team3.create_team_username"""pics = []self.driver.register(self.mobile)exp = "true"res = self.driver.check_button_disabled()self.driver.allure_report(self.test_create_team_username, pics, exp, res)self.driver.Assert.assert_equal(exp, res)

Config 配置

一般配置host 等數據 使用ConfigParser讀取寫入
config.ini

[loginParam] username = username password = 123456[domain] cm = xx class Config:def get_conf(self, title, value):"""read .ini:param title::param value::return:"""log.info("{} : {}:{}".format(self.get_conf.__name__, title, value))return self.config.get(title, value)def set_conf(self, title, value, text):"""change .ini:param title::param value::param text::return:"""log.info("{} : {}:{}:{}".format(self.set_conf.__name__, title, value, text))self.config.set(title, value, text)with open(self.config_path, 'w+') as f:return self.config.write(f)

main 啟動

使用sys.argv 獲取命令行自定義參數

if len(sys.argv) > 3:runCase = sys.argv[1] # P1 P2 P3 ALL 指定運行的用例等級if runCase != "ALL":case_path = f"-m={runCase}"xml = sys.argv[2] # 報告路徑if xml:xml_report_path = xmlBUILD_NUMBER = sys.argv[3]args = ["-s", "-v", "-n=auto", case_path, '--alluredir', xml_report_path, '--clean-alluredir']pytest.main(args=args)

圖片相對定位 獲得坐標

場景

canvas 頁面 無元素可定位

使用

先截取想要點擊的位置圖片 保存到本地
find_me 傳入driver 對象
通過 center_x 與center_y 屬性方法 獲得相對坐標

class GraphicalLocator():def __init__(self, img_path):self.locator = img_path# x, y position in pixels counting from left, top cornerself.x = Noneself.y = Noneself.img = cv2.imread(img_path)self.height = self.img.shape[0]self.width = self.img.shape[1]self.threshold = None@propertydef center_x(self):return self.x + int(self.width / 2) if self.x and self.width else None@propertydef center_y(self): return self.y + int(self.height / 2) if self.y and self.height else Nonedef find_me(self, drv): # Clear last found coordinatesself.x = self.y = None# Get current screenshot of a web pagescr = drv.get_screenshot_as_png()# Convert img to BytesIOscr = Image.open(BytesIO(scr))# Convert to format accepted by OpenCVscr = numpy.asarray(scr, dtype=numpy.float32).astype(numpy.uint8)# Convert image from BGR to RGB formatscr = cv2.cvtColor(scr, cv2.COLOR_BGR2RGB)# Image matching works only on gray images# (color conversion from RGB/BGR to GRAY scale)img_match = cv2.minMaxLoc(cv2.matchTemplate(cv2.cvtColor(scr, cv2.COLOR_RGB2GRAY),cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY),cv2.TM_CCOEFF_NORMED))# Calculate position of found elementself.x = img_match[3][0]self.y = img_match[3][1]# From full screenshot crop part that matches template imagescr_crop = scr[self.y:(self.y + self.height),self.x:(self.x + self.width)]# Calculate colors histogram of both template# and matching images and compare themscr_hist = cv2.calcHist([scr_crop], [0, 1, 2], None,[8, 8, 8], [0, 256, 0, 256, 0, 256])img_hist = cv2.calcHist([self.img], [0, 1, 2], None,[8, 8, 8], [0, 256, 0, 256, 0, 256])comp_hist = cv2.compareHist(img_hist, scr_hist,cv2.HISTCMP_CORREL)# Save treshold matches of: graphical image and image histogramself.threshold = {'shape': round(img_match[1], 2), 'histogram': round(comp_hist, 2)}# Return image with blue rectangle around matchreturn cv2.rectangle(scr, (self.x, self.y),(self.x + self.width, self.y + self.height),(0, 0, 255), 2)

pytest

pytest 有很多好用的功能、比如失敗重跑、多進程并行用例、fixture 測試
用例參數化等等
詳見 gitHUB-SeleniumUIAuto 中的 readme

總結

以上是生活随笔為你收集整理的使用selenium + pytest + allure做WBE UI自动化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。