В данной статье отражена попытка применить модель детекции для UI-тестирования.

Предполагалось, что внедрение ML должно позволить (даже при полном изменении интерфейса) не переписывать автотесты и полностью исключить человеческий фактор при UI-тестировании.

Для автоматизации UI-тестировании использовались следующие инструменты:

  • Selenium – инструмент для автоматизации действий с браузером;

  • Pytest – инструмент для выполнения и проверки тестовых сценариев;

  • ML – обученная модель машинного обучения.

Для эксперимента была выбрана модель YOLOv8m. Для обучения модели применялся датасет от компании Ultralytics – Website Screenshots Datase, который представляет собой набор данных скриншотов 1 206 веб-сайтов. К большому сожалению в данном датасете наибольшую часть классов представляют собой button (кнопки), что сильно сказалось на качестве распознавания других классов.

Обучение модели:

!nvidia-smi
import os
HOME = os.getcwd()
print(HOME)
!pip install ultralytics==8.0.196
from IPython import display
display.clear_output()
import ultralytics
ultralytics.checks()
from ultralytics import YOLO
from IPython.display import display, Image
!mkdir {HOME}/datasets
!pip install roboflow --quiet
!pip install roboflow
from roboflow import Roboflow
rf = Roboflow(api_key="5Mar5Cz54g9Sq0KSRc8x")
project = rf.workspace("roboflow-gw7yv").project("website-screenshots")
dataset = project.version(1).download("yolov8")
!yolo task=detect mode=train model=yolov8m.pt data={dataset.location}/data.yaml epochs=50 imgsz=800 plots=True
!ls {HOME}/runs/detect/train/
Image(filename=f'{HOME}/runs/detect/train/confusion_matrix.png', width=600)
Image(filename=f'{HOME}/runs/detect/train/results.png', width=600)
Image(filename=f'{HOME}/runs/detect/train/val_batch0_pred.jpg', width=600)
!yolo task=detect mode=val model={HOME}/runs/detect/train/weights/best.pt data={dataset.location}/data.yaml
from google.colab import drive
drive.mount('/content/drive')
import shutil
import os
os.getcwd()
sourcePath = "/content/runs/detect/train/weights/best.pt"
destinationPath = "/content/drive/MyDrive/best.pt"
shutil.copyfile(sourcePath, destinationPath)
!yolo task=detect mode=predict model={HOME}/runs/detect/train/weights/best.pt conf=0.25 source={dataset.location}/test/images save=True
import glob
from IPython.display import Image, display
for image_path in glob.glob(f'{HOME}/runs/detect/predict/*.jpg')[:3]:
      display(Image(filename=image_path, width=600))
      print("\n")
project.version(dataset.version).deploy(model_type="yolov8", model_path=f"{HOME}/runs/detect/train/")
model = project.version(dataset.version).model
import os, random
test_set_loc = dataset.location + "/test/images/"
random_test_image = random.choice(os.listdir(test_set_loc))
print("running inference on " + random_test_image)
pred = model.predict(test_set_loc + random_test_image, confidence=40, overlap=30).json()
pred
from ultralytics import YOLO
model.export()

Упрощенно процесс автоматизации UI-тестирования выглядит следующим образом (на примере распознавания кнопок):

1.      С помощью Selenium создается скриншот веб-сайта.

2.      Полученный скриншот сохраняется, а затем передается в обученную модель.

3.      Модель находит нужные классы.

4.      Затем, модель определяет  координаты всех распознанных изображе��ий и возвращает результат в виде json формата с указанием центра координат объекта –  x и y  и ширину и высоту распознанного объекта.

5.      Найденные координаты передаются в Selenium и с помощью Pytest проверяется корректность работы найденного объекта.

Тестирование работы кнопки с помощью предварительно обученной модели YOLOv8m:

from selenium import webdriver
from selenium.webdriver.common.by import By 
import time
from selenium.webdriver.common.action_chains import ActionChains
import pytest
import json
from PIL import Image
import easyocr
from ultralytics import YOLO
@pytest.fixture
def browser():
    driver = webdriver.Firefox()
    yield driver
    driver.quit()
def test_ckic(browser):
    browser.set_window_size(1024,768)
    browser.get("https://guru.qahacking.ru")
    path = "sait_1.png"
    browser.save_screenshot(path)
    model = YOLO('best.pt')
    prediction = model.predict(path)
    for r in prediction:
        x=r.tojson()
    elements = json.loads(x)
    text=[]
    button=[]
    for i in elements:
        if i['name']=='text':
            text.append(i)
        if i['name']=='button':
            button.append(i)
    im = Image.open(path)
    for i in button:
        x1=int(i['box']['x1'])
        x2=int(i['box']['x2'])
        y1=int(i['box']['y1'])
        y2=int(i['box']['y2'])
        im_crop = im.crop((x1, y1, x2, y2))
        im_crop.save('imeg.png')
        print(easyocr.Reader(["ru"]).readtext('imeg.png', detail=0, paragraph=True, text_threshold=0.8))    
    actions = ActionChains(browser)
    actions.move_by_offset(x1, y1).perform()
    time.sleep(5)
    actions.click().perform()
    time.sleep(5)
    assert browser.current_url == 'https://ermita.one/matricy-kompetencij/'

Спасибо за внимание.

Комментарии (0)