本文へ移動
cccskills
無料GitHub で公開

graphql-yoga-tests

Tests a GraphQL Yoga server (the-guild.dev runtime) with `yoga.fetch()` for in-process, no-network request simulation of queries and mutations, `@graphql-tools/executor-http` for subscription and incremental-delivery (streaming) tests, auth-header pass-through, and production-config gates for disabled introspection and persisted operations; also carries the Mercurius (Fastify GraphQL plugin) in-process `app.inject()` testing patterns in references/mercurius.md. Use to test a GraphQL Yoga or Mercurius server, write query, mutation, or subscription tests, or check production plugin config; for other runtimes use apollo-server-tests or hasura-tests instead, not this skill.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qaスター 13(GitHub 13 + cccskills 0)

実行スコア 未検証

インストール方法を見る

含まれるファイル(4)

  • SKILL.md7.5 KB
  • .tessl-plugin/plugin.json812 B
  • references/mercurius.md6.7 KB
  • references/production-config-tests.md1.7 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

graphql-yoga-tests

Overview

Per the-guild.dev/graphql/yoga-server/docs/features/testing: "Calling the yoga.fetch method does not send an actual HTTP request. It simulates the HTTP request which 100% conforms with how Request/Response work."

Structurally different from Apollo's executeOperation - Yoga's testing path goes through the HTTP transport layer including middleware, headers, and response codes. There is no separate "in-process" vs "HTTP-layer" choice.

When to use

  • Unit / integration tests for a Yoga-based GraphQL server.
  • Subscription tests (SSE / WS via Yoga).
  • Production-config gates for Yoga's plugin-based controls.

Authoring

Install

npm install --save-dev graphql-yoga @graphql-tools/executor-http

Basic test

Per Yoga docs:

import { createYoga, createSchema } from 'graphql-yoga';

const yoga = createYoga({
  schema: createSchema({
    typeDefs: /* GraphQL */ `
      type Query { greetings: String }
    `,
    resolvers: { Query: { greetings: () => 'Hello' } },
  }),
});

test('greetings', async () => {
  const response = await yoga.fetch('http://yoga/graphql', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ query: '{ greetings }' }),
  });
  const result = await response.json();
  expect(result.data.greetings).toBe('Hello');
});

The URL http://yoga/graphql is a placeholder - yoga.fetch doesn't make a network call, but the URL must parse.

HTTP executor for subscriptions

Per Yoga docs:

import { buildHTTPExecutor } from '@graphql-tools/executor-http';
import { parse } from 'graphql';

const executor = buildHTTPExecutor({ fetch: yoga.fetch });
const result = await executor({ document: parse(`{ greetings }`) });
expect(result.data.greetings).toBe('Hello');

For subscriptions (SSE):

const stream = await executor({ document: parse(subscriptionQuery) });
if (Symbol.asyncIterator in stream) {
  for await (const event of stream) {
    expect(event.data).toBeDefined();
    if (allEventsReceived) break;
  }
}

Auth header pass-through

const response = await yoga.fetch('http://yoga/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${testToken}`,
  },
  body: JSON.stringify({ query: '{ me { id } }' }),
});

Yoga's context-builder runs against the simulated request, so auth middleware is exercised.

Worked example

Integration scenario combining the operations above in one file: verify a { me { id } } query requires a bearer token, and that introspection is off in the production plugin set.

  1. Build the server with createYoga({ schema, plugins: [useDisableIntrospection()] }) and a context-builder that reads Authorization.
  2. yoga.fetch { me { id } } with no header; parse .json() and assert result.errors is present - the context / auth middleware rejected it.
  3. yoga.fetch the same query with Authorization: Bearer ${testToken}; assert result.data.me.id is returned.
  4. yoga.fetch an { __schema { types { name } } } query; assert result.errors[0].message matches /introspection/i.

Result: one file proves auth pass-through (tokenless rejected, valid token resolves) and the production introspection gate in-process, no network.

Running

Standard test commands

npm test

Production-config tests

Yoga's production gates - disable-introspection and persisted-operations - have their own plugin setup and strict-mode assertions. Full test patterns are in references/production-config-tests.md.

Parsing results

yoga.fetch returns a standard Response. Parse with .json() for non-streaming queries; iterate with the async-iterator for subscriptions.

The response shape:

{
  "data": { "greetings": "Hello" },
  "errors": [
    {
      "message": "...",
      "path": ["greetings"],
      "extensions": { "code": "..." }
    }
  ]
}

Yoga uses useMaskedErrors by default (per Yoga docs) - error messages are masked to "Unexpected error" in production unless the error has been marked safe. Test against this:

const resp = await yoga.fetch(/* ... */);
const result = await resp.json();
// Production: error message is "Unexpected error", original
// hidden in extensions if at all
expect(result.errors[0].message).toBe('Unexpected error.');

CI integration

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm ci
      - run: npm test
      - name: Production-mode tests
        env: { NODE_ENV: production }
        run: npx jest tests/production-config/

Anti-patterns

Anti-patternWhy it failsFix
Skipping yoga.fetch and using HTTP server directlySlower; same coverageyoga.fetch is purpose-built
Asserting on Yoga's default error string "Unexpected error." everywhereMisses real errors that aren't maskedUse useMaskedErrors({ errorMessage: 'Sanitised' }) and assert per-test
Skipping useDisableIntrospection in prod testsProduction introspection silently enabledMirror prod plugin set in test
Persisted-operations plugin without explicit allowArbitraryOperations: falseAuto-bypass on unrecognised hashUse strict mode
Subscription tests with await response.json()SSE/multipart streams aren't JSONUse buildHTTPExecutor + async iterator
Stale schema in testSchema drifts; tests pass against old shapeRebuild schema per test file or use beforeAll

Limitations

  • No real HTTP server. Tests that depend on the underlying HTTP framework's behaviour (e.g., Node http quirks, h2-upgrade scenarios) need a real server with node-fetch or supertest.
  • Subscription transports. Yoga supports SSE by default; WebSocket subscriptions need graphql-ws integration with its own test harness.
  • Error masking complexity. useMaskedErrors interacts with every test that asserts on errors; understand the project's configuration.
  • File uploads. Yoga's multipart-upload spec testing needs FormData not JSON.

References

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

Builds a CI gate that fails the build on **new** WCAG / a11y violations introduced by a PR while grandfathering pre-existing violations on a per-rule / per-page baseline. Aggregates verdicts from axe-core / pa11y / Lighthouse a11y / WAVE / IBM Equal Access scans. Use when a project has accumulated a11y debt and a strict "zero violations" gate would block every PR - the ratchet pattern lets the team ship while preventing regressions.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Workflow skill that builds an A/B-test validity checklist from an experiment proposal, walking the canonical design-correctness gates - pre-registered OEC/power/guardrails, randomization unit + SRM check, assignment integrity, telemetry, peeking discipline, novelty/primacy, post-experiment SRM re-check - into a per-experiment checklist + sign-off form. Use when launching, auditing, or governing an experiment. For pitfall mechanics (guardrails, peeking) see experiment-results-interpreter's references; to read an already-valid result use experiment-results-interpreter; for per-SDK harness tests use experiment-sdk-testing - this gates DESIGN, not SDK code.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

The single install-flow skill: the reference contract for the PWA install flow (installability gate fields, `beforeinstallprompt` handshake, per-platform paths - Android WebAPK / iOS Share menu / Firefox no-op - and the `display-mode` post-install signal, in references/install-flow-reference.md) plus the build-an-X workflow that emits the Add-to-Home-Screen suite. Walks the four-stage timeline, emitting one test per gate cell per [web.dev/articles/install-criteria][install-criteria], the deferred-prompt → `prompt()` → `userChoice` chain per [web.dev/articles/customize-install][customize-install], the iOS Safari manual-metadata branch (`apple-touch-icon`) per [web.dev/learn/pwa/installation][learn-pwa], and the post-install `(display-mode: standalone)` MQ assertion. Output: a Playwright spec with per-stage cells plus a coverage matrix. Use when a PWA's manifest, icons, or install handler change, when install conversion drops at an unknown stage, or when triaging a flaky install assertion.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Build-an-X workflow that uses an LLM to map existing tests to spec sections - given a spec doc + the test suite, the LLM identifies which tests cover which sections, surfaces uncovered sections (gap), and recommends specific tests to add. Output is a coverage matrix per spec ID. Scope is mapping tests that already exist and naming the gaps, not authoring tests for new acceptance criteria. Use when a spec doc and a test suite both exist but nobody can say which requirements are actually covered - before a release sign-off, an audit, or a decision about where to spend the next round of test effort.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Generates tests from natural-language specs (acceptance criteria, user stories, requirements) using an LLM, with confidence scoring per test case (LLM self-assessment plus heuristics: assertion quality, naming, completeness), batching uncertain cases for human review, and integration with the team's existing test framework. Use when the user asks to generate unit tests from acceptance criteria, convert user stories to test cases, automate test creation from requirements, or augment a spec-driven test suite with AI-generated stubs that are then curated before merge.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Configures Allure Report (test-runner adapter install, `allure-results` directory wiring, `categories.json` for failure classification, `history-trend.json` retention via the copy-history-between-runs pattern), runs the Allure CLI to convert `allure-results` to a static HTML site, and uploads the report as a CI artifact. Use when the team needs richer test reporting than JUnit XML - step-level attachments, per-test history, retry tracking, and severity / epic / feature labeling across framework-agnostic adapters (pytest, Jest, JUnit, TestNG, NUnit, Mocha). As a rich static HTML report generator, it is the open-source alternative to the sunset ExtentReports (JVM/.NET per-test HTML narrative); for hosted cross-run flakiness analytics rather than a static per-run report use currents-integration.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

testland のスキルをすべて見る

このスキルの問題を報告する