AI를 활용한 셀프 힐링 Selenium 프레임워크 구축

발행: (2026년 4월 26일 AM 09:23 GMT+9)
5 분 소요
원문: Dev.to

Source: Dev.to

AI를 활용한 자체 복구 Selenium 프레임워크 구축 커버 이미지

“셀프 힐링”이 실제 의미하는 바

  • 런타임에 깨진 로케이터를 감지합니다
  • 대체 전략(또는 AI 순위)을 사용하여 올바른 요소를 찾습니다
  • 옵션으로 소스의 로케이터를 업데이트하여 동일한 오류가 반복되지 않도록 합니다

이는 불안정한 테스트 재시도와 다릅니다 — 증상을 억제하는 것이 아니라 근본 원인을 해결하고 있습니다.

핵심 패턴: 로케이터 폴백 체인

from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException

LOCATOR_STRATEGIES = [
    (By.ID, "submit-btn"),
    (By.CSS_SELECTOR, "button[data-testid='submit']"),
    (By.XPATH, "//button[contains(text(),'Submit')]"),
    (By.CSS_SELECTOR, "form button[type='submit']"),
]

def find_element_with_healing(driver):
    for strategy, locator in LOCATOR_STRATEGIES:
        try:
            el = driver.find_element(strategy, locator)
            print(f"Located using: {strategy}{locator}")
            return el
        except NoSuchElementException:
            continue
    raise Exception("Element not found via any strategy")

각 로케이터는 우선순위 목록을 가지고 있습니다. 기본 로케이터가 실패하면 다음 전략으로 순차적으로 넘어갑니다.

AI 추가: 유사도 점수를 통한 후보 순위 매기기

똑똑한 버전은 무작정 되돌아가지 않고 페이지의 후보들을 점수화하여 가장 일치하는 항목을 선택합니다. 간단한 접근법으로 DOM 속성 유사도를 활용합니다:

from difflib import SequenceMatcher
from selenium.webdriver.common.by import By

def similarity(a, b):
    return SequenceMatcher(None, a, b).ratio()

def find_best_candidate(driver, target_attributes: dict):
    candidates = driver.find_elements(By.CSS_SELECTOR, "*")
    best_score = 0
    best_element = None

    for el in candidates:
        score = 0
        for attr, value in target_attributes.items():
            el_attr = el.get_attribute(attr) or ""
            score += similarity(el_attr, value)

        if score > best_score:
            best_score = score
            best_element = el

    return best_element if best_score > 0.6 else None

# Usage
element = find_best_candidate(driver, {
    "id": "submit-btn",
    "class": "btn-primary",
    "type": "submit"
})

실제 운영 환경에서는 유사도 점수 계산기를 임베딩 모델(OpenAI, Sentence Transformers)로 교체하여 요소 컨텍스트의 의미적 유사성을 비교하도록 합니다 — 단순히 속성 문자열만 비교하는 것이 아니라.

루프 닫기: 자동 업데이트 로케이터

마지막 단계는 승리한 로케이터를 테스트 구성 파일에 다시 기록하여 이후 실행에서 직접 사용할 수 있게 하는 것입니다:

import json

def update_locator_store(key, strategy, locator, path="locators.json"):
    with open(path, "r+") as f:
        store = json.load(f)
        store[key] = {"strategy": strategy, "locator": locator}
        f.seek(0)
        json.dump(store, f, indent=2)

이 과정을 CI 파이프라인과 결합하여 로케이터가 복구될 때 PR이나 댓글을 자동으로 생성하도록 하면, 팀이 수동 개입 없이도 가시성을 확보할 수 있습니다.

언제 Not to Use This

Self‑healing은 복잡성을 추가합니다. 앱에 안정적인 디자인 시스템과 체계적인 data-testid 사용이 있다면, 아마도 필요하지 않을 것입니다. 이 패턴이 가장 가치 있는 경우는 다음과 같습니다:

  • 불안정한 DOM 구조를 가진 레거시 앱
  • 개발자와 QA가 분리된 팀
  • 테스트 소유권 없이 UI를 자주 재디자인하는 경우

더 나아가기 위한 팁

  • Healenium — 기존 Selenium 설정에 최소한의 코드 변경으로 자체 치유 기능을 추가하는 오픈소스 프록시
  • Sentence Transformers — 코사인 유사도는 SequenceMatcher보다 더 나은 의미 매칭을 제공합니다
  • 모든 치유 이벤트를 대시보드에 기록하세요 — 설계 불안정 패턴을 빠르게 파악할 수 있습니다
0 조회
Back to Blog

관련 글

더 보기 »