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

grpc-streaming-test-author

The single gRPC-streaming test home: builds streaming-RPC test suites from a proto definition. Classifies each RPC by pattern (unary, server-streaming, client-streaming, bidi), then emits the required categories per pattern - ordering preservation, completion semantics (server close after stream end, client half-close), cancellation, deadline handling, partial-stream failure. Produces skeletons for Go (bufconn + Send/Recv), Python (iterators), JVM (StreamObserver), Node (call.write/end); carries the 17-code gRPC status catalog (retry semantics per AIP-194, grpc-gateway HTTP mapping) in references/status-codes.md and the wire-level / live-server streaming patterns (deadline propagation, server-side cancellation, metadata, ghz load) in references/wire-level-testing.md. Use when adding tests for a new or existing streaming RPC, auditing a suite for uncovered categories, or asserting status-code behavior. Different test surface from grpc-mock (the in-process harness itself).

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

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

実行スコア 未検証

インストール方法を見る

含まれるファイル(6)

  • SKILL.md11.4 KB
  • .tessl-plugin/plugin.json1.1 KB
  • references/status-codes-metadata-load.md1.9 KB
  • references/status-codes.md12.2 KB
  • references/test-skeletons.md3.7 KB
  • references/wire-level-testing.md8.2 KB

SKILL.md(原文)

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

grpc-streaming-test-author

Overview

Streaming RPCs are where gRPC clients and servers most often diverge from the proto contract - message ordering, completion signalling, cancellation, and partial-failure semantics are all testable surfaces. gRPC defines four streaming patterns - unary, server-streaming, client-streaming, bidirectional - per grpc.io/docs/what-is-grpc/core-concepts/; Step 1 classifies each RPC by pattern.

This skill walks through producing a comprehensive test suite from the proto file. It composes grpc-mock for the test harness and references/status-codes.md for status-code assertions; live-server (non-bufconn) patterns are in references/wire-level-testing.md.

When to use

  • Adding tests for a new streaming RPC.
  • Auditing an existing streaming-RPC test suite - is each pattern's required category covered?
  • Investigating a streaming-RPC bug - minimal repro from the test matrix.
  • PR review of changes to streaming RPCs (the proto-evolution rules on stream changes are subtle - per buf-cli-lint-breaking-build references/versioning-strategy.md).

Step 1 - Classify each RPC

Walk the .proto file and tabulate:

service Chat {
  rpc Send(Message) returns (Ack);                         // unary
  rpc Subscribe(SubReq) returns (stream Event);            // server streaming
  rpc Upload(stream Chunk) returns (UploadResult);         // client streaming
  rpc Conversation(stream Message) returns (stream Reply); // bidi
}
RPCPatternRequired test categories
Sendunarysuccess, every status code per references/status-codes.md
Subscribeserver-streamsuccess, ordering, server-side close after N messages, server-side mid-stream error, client-side cancel mid-stream, deadline-exceeded mid-stream
Uploadclient-streamsuccess, server completes before client finishes, server-side error mid-upload, client-side cancel before send, empty stream
Conversationbidisuccess, ordering per direction, client closes send while still receiving, server closes send while still receiving, both close, deadline mid-conversation, error mid-conversation

Step 2 - Test categories per pattern

Unary (covered for completeness)

def test_send_returns_ok(stub):
    resp = stub.Send(Message(body="hi"))
    assert resp.ok

def test_send_returns_invalid_argument(stub):
    with pytest.raises(grpc.RpcError) as exc:
        stub.Send(Message(body=""))
    assert exc.value.code() == grpc.StatusCode.INVALID_ARGUMENT

Server-streaming

Ordering preservation - per gRPC docs: "gRPC guarantees message ordering within an individual RPC call."

def test_subscribe_preserves_ordering(stub_with_fake):
    stub_with_fake.fake_response_stream = [
        Event(seq=1), Event(seq=2), Event(seq=3),
    ]
    received = list(stub_with_fake.Subscribe(SubReq()))
    assert [e.seq for e in received] == [1, 2, 3]

Server closes after N messages - completion is the finalisation signal:

def test_subscribe_completes_after_finite_stream(stub_with_fake):
    stub_with_fake.fake_response_stream = [Event(seq=1), Event(seq=2)]
    events = list(stub_with_fake.Subscribe(SubReq()))
    # If list(...) terminates, the server-side close was signalled.
    assert len(events) == 2

Server-side error mid-stream:

def test_subscribe_propagates_error_mid_stream(stub_with_fake):
    stub_with_fake.fake_response_stream = [Event(seq=1)]
    stub_with_fake.fake_post_yield_status = grpc.StatusCode.INTERNAL
    events_iter = stub_with_fake.Subscribe(SubReq())
    # Receive first event OK
    next(events_iter)
    # Subsequent receive fails with INTERNAL per references/status-codes.md
    with pytest.raises(grpc.RpcError) as exc:
        next(events_iter)
    assert exc.value.code() == grpc.StatusCode.INTERNAL

Client cancel mid-stream:

def test_client_cancel_mid_stream(stub_with_fake):
    stub_with_fake.fake_response_stream = [Event(seq=i) for i in range(100)]
    events_iter = stub_with_fake.Subscribe(SubReq())
    next(events_iter)  # receive one
    events_iter.cancel()
    with pytest.raises(grpc.RpcError) as exc:
        next(events_iter)
    assert exc.value.code() == grpc.StatusCode.CANCELLED

Deadline-exceeded mid-stream:

def test_subscribe_deadline_exceeded(stub_with_slow_fake):
    events_iter = stub_with_slow_fake.Subscribe(SubReq(), timeout=0.1)
    with pytest.raises(grpc.RpcError) as exc:
        for _ in events_iter:
            pass
    assert exc.value.code() == grpc.StatusCode.DEADLINE_EXCEEDED

Client-streaming

Categories: success, server completes before client finishes (further Send yields io.EOF), server-side error mid-upload, client-side cancel before send, empty stream. Go bufconn skeletons: references/test-skeletons.md.

Bidirectional

The two streams operate independently, so test each direction plus a concurrent send/recv case. Categories: ordering per direction, client closes send while still receiving (CloseSend), server closes send while still receiving, both close, deadline mid-conversation, error mid-conversation. Go skeletons: references/test-skeletons.md.

Step 3 - Coverage matrix

For each streaming RPC, generate the matrix:

                              Send  Subscribe  Upload  Conversation
                              ----  ---------  ------  ------------
success                        X       X        X         X
ordering preserved             -       X        X         X (both)
N msgs then close              -       X        X         X
mid-stream server error        -       X        X         X
deadline exceeded              X       X        X         X
client cancel                  X       X        X         X
server cancel                  -       X        X         X
empty stream                   -       X        X         X
client half-close              -       -        -         X
server half-close              -       -        -         X

Empty cells in covered patterns = coverage gap. PR must justify or add a test.

Step 4 - Pick the test harness

Per grpc-mock:

LanguageHarness
Gobufconn in-process server + t.Cleanup
Pythonpytest fixture with [::]:0 port + iterator-based stream API
JVMInProcessServerBuilder + StreamObserver
Node@grpc/grpc-js server with bindAsync("127.0.0.1:0") + call.write / call.end

Don't use mockgen / interface-mocks for streaming - they skip the marshalling + ordering guarantees that the streaming contract depends on.

Step 5 - Emit the test directory

tests/grpc-streaming/
  __init__.py
  conftest.py                   # shared fixtures (in-process server)
  test_subscribe.py             # server-streaming
  test_upload.py                # client-streaming
  test_conversation.py          # bidi
  test_send.py                  # unary (sibling)
  README.md                     # the coverage matrix

The README.md should document the matrix from Step 3 so reviewers and new contributors can see at a glance what is and isn't covered.

Streaming evolution - version-safety reminder

Per the versioning-strategy reference in buf-cli-lint-breaking-build, changing an RPC's streaming pattern is always breaking:

service Chat {
-  rpc Subscribe(SubReq) returns (Event);
+  rpc Subscribe(SubReq) returns (stream Event);
}

The wire format differs, so old clients won't parse the new response. Verify breaking-change detection via buf-cli-lint-breaking-build catches this with FILE or PACKAGE category.

Anti-patterns

Anti-patternWhy it failsFix
Single happy-path test per streaming RPCMisses ordering / cancellation / deadline categoriesUse Step 2's per-pattern matrix
Test asserts on the last message onlyMisses ordering bugs in earlier messagesCollect entire stream, assert on the full sequence
time.sleep to wait for server messagesRace-prone; flakes in CIUse channel close / iterator exhaustion as completion signal
Cancellation test sleeps then cancelsRace: server may finish before cancelInject a controllable blocker in the fake server
No deadline-exceeded testProduction deadlines surface in mid-streamAlways include - per references/status-codes.md, DEADLINE_EXCEEDED is its own code
Mock at interface level for streamingSkips marshalling + orderingIn-process server only for streaming
Bidi test where client and server are deterministic-interleavedMisses race conditions inherent in "operate independently"One test per direction + one test with concurrent send/recv
Don't CloseSend() in client-streaming testsServer waits foreverAlways close the send side explicitly

Limitations

  • Wire-level fault injection. Partial-byte cutoffs and middlebox-induced disconnects aren't reachable through bufconn / InProcessServer. For these, use toxiproxy + a real server; live-server patterns in references/wire-level-testing.md.
  • Backpressure semantics differ per stack. Go bufconn buffer size affects when Send blocks; Java StreamObserver is push-based; Python is iterator-pull. Tests are stack-specific.
  • HTTP/2 flow control isn't exercised. In-process transports skip H2 framing; flow-control bugs need real transports.
  • Doesn't test contract compliance. Mocks reflect what this test expects. Real-server contract tests are separate; see protobuf-compat-checking (in the qa-contract-testing plugin).
  • Concurrent-client stress tests not in scope. For that see ghz-load (unary load) or hand-rolled multi-client streaming harnesses.

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 のスキルをすべて見る

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