일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Pulumi
- Argo
- CI/CD
- Kopf
- 카오스 엔지니어링
- mlops
- opensearch
- Kubeflow
- blue/green
- argocd
- keda
- argo rollout
- Kubernetes
- kubernetes operator
- operator
- Model Serving
- Kubernetes 인증
- serving
- gitea
- knative
- CANARY
- nginx ingress
- opentelemetry
- seldon core
- gitops
- Continuous Deployment
- 오퍼레이터
- MLflow
- Litmus
- tekton
- Today
- Total
Kubernetes 이야기
Playwright와 Python 사용 방법 본문
Playwright는 다음을 참고한다. 이번에는 Python을 활용하여 Playwright 를 사용하는 방법에 대해 알아보자.
Playwright에서 예제를 보면 다음과 같이 스크립트를 생성한다.
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
context = browser.new_context()
page = context.new_page()
fixture
pytest-playwright 플러그인은 fixture를 사용하여 python의 자동처리를 지원할 수 있도록 한다.
fixture에는 Session 브라우저 범위가 있다. 이것은 모든 테스트가 하나의 브라우저 인스턴스를 공유한다는 의미이다.
또한 테스트가 완료된 후 모든 것을 자동으로 정리한다. 즉 브라우저를 명시적으로 닫을 필요는 없다.
from playwright.sync_api import Page
def test_http_get(page):
page.goto('https://httpbin.org')
Playwright는 selector를 사용하여 페이지의 모든 요소를 찾을 수 있다. selector 에는 다음과 같은 유형이 있다.
- Text
- CSS
- XPath
- N-th element
- React
- Vue
- ID attributes
[xpath 예]
page.locator('xpath=//*[@id="operations-tag-HTTP_Methods"]/a').click()
[실행]
pytest test.py --headed
brower context 정의 예제
@pytest.fixture(scope="session")
def browser_context_args(browser_context_args, playwright):
return {
**browser_context_args,
"ignore_https_errors": True,
"locale": "ko-KR",
"timezone_id": "Asia/Seoul",
"viewport": {
"width": 1920,
"height": 1080,
}
}
assert
Playwright로 수행한 테스트 결과에 대해 검증하는 것은 매우 중요한 일이다. 검증을 위해 expect 함수를 사용한다.
[테스트 시나리오]
HTTP Methods 에서 /get method를 선택하여 실행하면 200 code가 리턴되는지 검증한다.
from playwright.sync_api import expect, Page
def test_http_get(page):
page.goto('https://httpbin.org')
page.locator('xpath=//*[@id="operations-tag-HTTP_Methods"]/a').click()
page.locator('xpath=//*[@id="operations-HTTP Methods-get_get"]/div[1]/div').click()
page.locator('xpath=//*[@id="operations-HTTP Methods-get_get"]/div[2]/div/div[1]/div[1]/div[2]/button').click()
page.locator('xpath=//*[@id="operations-HTTP Methods-get_get"]/div[2]/div/div[2]/button[1]').click()
expect(page.locator('xpath=//*[@id="operations-HTTP Methods-get_get"]/div[2]/div/div[3]/div[2]/div/div/table/tbody/tr/td[1]')).to_contain_text('200')
#expect(page.locator('#operations-HTTP\ Methods-get_get > div:nth-child(2) > div > div.responses-wrapper > div.responses-inner > div > div > table > tbody > tr > td.col.response-col_status')).to_have_value('200')
[실행결과]
# pytest test.py
test.py . [100%]
======================================================== 1 passed in 8.74s ========================================================
만약 500으로 체크한다면, 다음과 같은 오류가 발생한다.
est.py:11: AssertionError
===================================================== short test summary info =====================================================
FAILED test.py::test_http_get[chromium] - AssertionError: Locator expected to contain text '500'
======================================================= 1 failed in 10.81s ========================================================
Assertions 은 https://playwright.dev/python/docs/test-assertions 를 참고한다.
Refactoring
Playwriget 호출시마다 원시적인 방법을 사용한다면 코드 중복이 이어질 수 있다. 예를들어 테스트하려면 페이지 기능이 회원과 게시판이 있다고 가정해 보자.
게시판에 회원이 글을 올릴때 회원정보를 필요로 할 수 있다. (혹은 게시글 등록 전 회원 등록 후 게시글 등록 시나리오 등을 만들 수 있다. )
예) Member Class
from playwright.sync_api import Page
class MemberPage:
URL = 'https://www.example.com'
def __init__(self, page: Page) -> None:
self.page = page
self.insert_button = page.locator('#insert_button')
self.insert_text_id = page.locator('#insert_text_id')
self.insert_text_name = page.locator('#insert_text_name')
self.insert_submit_button = page.locator('#insert_submit_button')
self.search_input = page.locator('#search_form_input')
self.search_button = page.locator('#search_button')
self.search_result = page.locator('a[data-id="result-member"]')
def load(self) -> None:
self.page.goto(self.URL)
def search(self, search_word: str) -> None:
self.search_input.fill(search_word)
self.search_button.click()
self.search_result =
def insert(self, id: str, name: str) -> None:
self.insert_button.click()
self.insert_text_id.fill(id)
self.insert_text_name.fill(name)
self.insert_submit_button.click()
def result_link_members(self) -> List[str]:
self.result_links.nth(4).wait_for()
return self.result_links.all_text_contents()
def result_link_members_contain_phrase(self, phrase: str, minimum: int = 1) -> bool:
titles = self.result_link_members()
matches = [t for t in titles if phrase.lower() in t.lower()]
return len(matches) >= minimum
필요한 Class를 만들었으면, 테스트코드는 다음과 같이 호출한다. (예시)
import pytest
from pages.member import MemberPage
from playwright.sync_api import expect, Page
MEMBERS = [
("1","member1"),
("2","member2")
]
@pytest.mark.parametrize("id, name", MEMBERS)
def test_member (
id: str,
name: str,
page: Page,
member_page: MemberPage) -> None:
member_page.load()
member_page.insert(id, name)
member_page.search(name)
assert member_page.result_link_member_contain_phrase(name)
'개발 > python' 카테고리의 다른 글
ChatGPT API 사용 (0) | 2023.03.27 |
---|---|
mitmproxy을 사용하여 K8S API Server Reverse Proxy 설정하기 (0) | 2023.02.22 |
playwright를 활용한 e2e 테스트 (0) | 2023.02.15 |
Python에서 gRPC 구현 (0) | 2023.02.13 |
Kopf ( 예제 ) (1) | 2023.02.05 |