Playwright测试REST API
Playwright不仅可以测试Web应用,也可以访问REST API进行测试。考虑以下应用场景:
- 测试服务器端API。
- 在进行Web应用测试前,调用一些API探测服务器状态。
- 在Web应用测试后,调用一些API服务来进行数据验证。
后面的2个选项意味着可以在测试用例中组合Web和API的测试。
举例测试流程如下:
flowchart TD
prereq([连接登录Github]) --> create(["创建新Repro"])
create --> bug["创建一个bug"]
bug --> post([删除创建的Repro])
源码
import os
from typing import Generator
import pytest
from playwright.sync_api import Playwright, APIRequestContext, expect
GITHUB_API_TOKEN = "XXXXXXXXXX"
# GITHUB_API_TOKEN = os.getenv("GITHUB_API_TOKEN")
assert GITHUB_API_TOKEN, "GITHUB_API_TOKEN is not set"
# GITHUB_USER = os.getenv("GITHUB_USER")
GITHUB_USER = "xxxxxxxxx"
assert GITHUB_USER, "GITHUB_USER is not set"
GITHUB_REPO = "test" # 临时测试使用的repo名字
@pytest.fixture(scope="session")
def api_request_context(playwright: Playwright) -> Generator[APIRequestContext, None, None]:
headers = {
# We set this header per GitHub guidelines.
"Accept": "application/vnd.github.v3+json",
# Add authorization token to all requests.
# Assuming personal access token available in the environment.
"Authorization": f"token {GITHUB_API_TOKEN}",
}
request_context = playwright.request.new_context(
base_url="https://api.github.com", extra_http_headers=headers
)
yield request_context
request_context.dispose()
# Create repo
# ...
@pytest.fixture(scope="session", autouse=True)
def create_test_repository(
api_request_context: APIRequestContext,
) -> Generator[None, None, None]:
# Before all
new_repo = api_request_context.post("/user/repos", data={"name": GITHUB_REPO})
assert new_repo.ok
yield
# After all
deleted_repo = api_request_context.delete(f"/repos/{GITHUB_USER}/{GITHUB_REPO}")
assert deleted_repo.ok
def test_should_create_bug_report(api_request_context: APIRequestContext) -> None:
data = {
"title": "[Bug] report 1",
"body": "Bug description",
}
new_issue = api_request_context.post(f"/repos/{GITHUB_USER}/{GITHUB_REPO}/issues", data=data)
assert new_issue.ok
issues = api_request_context.get(f"/repos/{GITHUB_USER}/{GITHUB_REPO}/issues")
assert issues.ok
issues_response = issues.json()
issue = list(filter(lambda issue: issue["title"] == "[Bug] report 1", issues_response))[0]
assert issue
assert issue["body"] == "Bug description"
def test_should_create_feature_request(api_request_context: APIRequestContext) -> None:
data = {
"title": "[Feature] request 1",
"body": "Feature description",
}
new_issue = api_request_context.post(
f"/repos/{GITHUB_USER}/{GITHUB_REPO}/issues", data=data
)
assert new_issue.ok
issues = api_request_context.get(f"/repos/{GITHUB_USER}/{GITHUB_REPO}/issues")
assert issues.ok
issues_response = issues.json()
issue = list(
filter(lambda issue: issue["title"] == "[Feature] request 1", issues_response)
)[0]
assert issue
assert issue["body"] == "Feature description"
playwright.request.new_context类似requests库中的session的含义
加入web一起的组合用例
def test_last_created_issue_should_be_first_in_the_list(api_request_context: APIRequestContext, page: Page) -> None:
def create_issue(title: str) -> None:
data = {
"title": title,
"body": "Feature description",
}
new_issue = api_request_context.post(
f"/repos/{GITHUB_USER}/{GITHUB_REPO}/issues", data=data
)
assert new_issue.ok
create_issue("[Feature] request 1")
create_issue("[Feature] request 2")
page.goto(f"https://github.com/{GITHUB_USER}/{GITHUB_REPO}/issues")
first_issue = page.locator("a[data-hovercard-type='issue']").first
expect(first_issue).to_have_text("[Feature] request 2")
伪python爱好者,正宗测试实践者。