write-graphql-test
Scaffold GraphQL API test files following project patterns — markers, fixtures, Allure decorators, Pydantic assertions, try-finally cleanup
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Scaffold GraphQL API test files following project patterns — markers, fixtures, Allure decorators, Pydantic assertions, try-finally cleanup
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Review test files for pattern compliance, code quality, correctness, coverage gaps, and best practices — produces actionable feedback
Scaffold E2E UI test files following project patterns — Playwright assertions, Page Objects, Components, markers, fixtures, Allure decorators, BrowserStorage
Scaffold REST API test files and factory fixture conftest files — admin auth, RestClient, factory fixtures with auto-teardown, Allure steps, CRUD patterns
Create Page Objects (MainLayout/CheckoutLayout subclasses) and UI Components (Component subclasses) with Playwright locators and data-test-id conventions
Create GraphQL Operations classes (BaseOperations subclass with auto-fragment injection) and Pydantic GqlModel types for response/input types
Migrate a Katalon REST API test module from vc-quality-gate-katalon into the refactored Pytest project — end-to-end flow from inventory to CI-verified PR
| name | write-graphql-test |
| description | Scaffold GraphQL API test files following project patterns — markers, fixtures, Allure decorators, Pydantic assertions, try-finally cleanup |
| argument-hint | <domain> <test-scenario> |
When writing a GraphQL test, follow these patterns exactly.
import allure
import pytest
from core.clients import GraphQLClient
from gql.operations import CartOperations # or domain-specific operations
from gql.types import Cart, CartItemInput # or domain-specific types
from tests.context import Context
from utils.line_item_utils import has_line_item # cart-specific helper
@allure.feature("<Domain> (GraphQL)") # e.g., "Cart (GraphQL)", "Order (GraphQL)"
@allure.title("<Action description>") # e.g., "Add bulk items to cart"
Use when the with_cart / with_user fixtures handle setup and teardown automatically.
_REGISTERED_USER = "acme_store_maintainer_1@acme.com"
_PRODUCT_ID = "product-acme-laptop-asus-zenbook-a14-ux3407"
@pytest.mark.graphql
@allure.feature("Cart (GraphQL)")
@allure.title("Anonymous cart creation")
@pytest.mark.with_cart([(_PRODUCT_ID, 1)])
def test_cart_anonymous(with_cart: Cart) -> None:
assert with_cart is not None
assert with_cart.is_anonymous is True
@pytest.mark.graphql
@allure.feature("Cart (GraphQL)")
@allure.title("Registered user cart creation")
@pytest.mark.with_user(_REGISTERED_USER)
@pytest.mark.with_cart([(_PRODUCT_ID, 1)])
def test_cart_registered_user(with_cart: Cart) -> None:
assert with_cart is not None
assert with_cart.is_anonymous is False
When to use: Test only needs a pre-seeded cart and/or authenticated user. No custom setup logic.
Use when you need custom setup, multiple operations, or assertions between operations.
_PRODUCT_1_ID = "product-acme-laptop-asus-zenbook-a14-ux3407"
_PRODUCT_2_ID = "product-acme-laptop-asus-vivobook-16-x1607qa"
_QUANTITY_1 = 3
_QUANTITY_2 = 4
@pytest.mark.graphql
@allure.feature("Cart (GraphQL)")
@allure.title("Add bulk items to cart")
def test_cart_add_bulk_items(graphql_client: GraphQLClient, ctx: Context) -> None:
cart_ops = CartOperations(client=graphql_client)
cart: Cart | None = None
try:
cart = cart_ops.add_items_to_cart(
store_id=ctx.store_id,
user_id=ctx.user_id,
culture_name=ctx.culture_name,
currency_code=ctx.currency_code,
items=[
CartItemInput(product_id=_PRODUCT_1_ID, quantity=_QUANTITY_1),
CartItemInput(product_id=_PRODUCT_2_ID, quantity=_QUANTITY_2),
],
)
assert has_line_item(cart.items, product_id=_PRODUCT_1_ID, quantity=_QUANTITY_1)
assert has_line_item(cart.items, product_id=_PRODUCT_2_ID, quantity=_QUANTITY_2)
finally:
if cart is not None:
cart_ops.delete_cart(cart_id=cart.id, user_id=ctx.user_id)
When to use: Custom multi-step operations, assertions on intermediate state, or resources that need manual cleanup.
| Fixture | Scope | Description |
|---|---|---|
graphql_client: GraphQLClient | function | Auto-closed via context manager |
ctx: Context | function | store_id, user_id, currency_code, culture_name, etc. |
with_cart: Cart | None | function (autouse) | Seeded from @pytest.mark.with_cart([(...)]) |
with_user: AuthProvider | function | Authenticated from @pytest.mark.with_user("email") |
dataset: dict | session | Raw test data from JSON files |
global_settings: GlobalSettings | session | Environment configuration |
# Pydantic model attribute access (typed)
assert cart.id is not None
assert cart.is_anonymous is True
assert cart.items_quantity == 1
assert cart.total.amount > 0
# Line item helper
from utils.line_item_utils import has_line_item
assert has_line_item(cart.items, product_id=_PRODUCT_ID, quantity=3)
# Error testing
from requests.exceptions import HTTPError
with pytest.raises(ValueError, match="GraphQL errors"):
cart_ops.get_cart(...)
@pytest.mark.graphql@allure.feature() and @allure.title()_PRODUCT_ID = "..."def test_...(fixtures) -> None:ctx fixture for store/user/currency/culture — don't hardcodewith_cart, with_user) over manual setupfinally blocks when using manual setupallure.step() for logical groupings when tests have multiple phases@pytest.mark.optional for tests that depend on an unstable/optional backend module bundle (e.g. quotes) — these can be excluded with -m 'not optional'