[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M69B7BHV2RTK64BZ8NQGFPNE":3,"skill-same:01M69B7BHV2RTK64BZ8NQGFPNE":84},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":34,"publishedAt":55,"linkOnly":56,"markdownContent":57,"markdownBody":58,"frontMatter":59,"refName":60,"commitSha":61,"skillDirectory":62,"forksCount":63,"repositoryHtmlUrl":64,"repositoryHomepageUrl":65,"ownerHtmlUrl":66,"ownerBlogUrl":67,"ownerDescription":68,"updatedAt":69,"install":70,"resources":83},"01M69B7BHV2RTK64BZ8NQGFPNE","writing-python-sdk-spector-mock-api-tests",null,"Writes TypeSpec http-client-python generator mock API tests (azure\u002Funbranded\u002Fshared) from a Spector case. Use when given a Spector case link or a PR link that modifies Spector cases under http-specs\u002Fazure-http-specs.","microsoft\u002Ftypespec","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M69B6S8HEDME7WWCNE7RGPJF",5948,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftypespec\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpython-sdk-spector-mock-api-tests\u002FSKILL.md",[18,23,26,31],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":27,"categoryName":28,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",{"categoryNo":32,"categoryName":33,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000036","内容创作者",[35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54],"python","sdk","writing","mock api","mock","writing python sdk spector mock api tests","api","python sdk","writing python","tests","when","generator","case","link","shared","use","typespec","pr","http","azure","2026-11-10 10:12:30",false,"---\nname: writing-python-sdk-spector-mock-api-tests\ndescription: Writes TypeSpec http-client-python generator mock API tests (azure\u002Funbranded\u002Fshared) from a Spector case. Use when given a Spector case link or a PR link that modifies Spector cases under http-specs\u002Fazure-http-specs.\n---\n\n# Writing python SDK tests from a Spector case\n\n## Inputs\n\nYou may receive either:\n\n- **Spector case link** (preferred): link to a specific scenario\u002Fcase under:\n  - `https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftypespec\u002Ftree\u002Fmain\u002Fpackages\u002Fhttp-specs\u002Fspecs\u002F...`\n  - `https:\u002F\u002Fgithub.com\u002FAzure\u002Ftypespec-azure\u002Ftree\u002Fmain\u002Fpackages\u002Fazure-http-specs\u002Fspecs\u002F...`\n- **PR link**: a GitHub PR that changes one or more Spector cases.\n\nSpector cases define the **expected request + response**. The goal is to add\u002Fextend python tests that validate the generated SDK behaves accordingly.\n\n## Output\n\nA python pytest test (sync) added to one of:\n\n- `packages\u002Fhttp-client-python\u002Ftests\u002Fmock_api\u002Fazure`\n- `packages\u002Fhttp-client-python\u002Ftests\u002Fmock_api\u002Funbranded`\n- `packages\u002Fhttp-client-python\u002Ftests\u002Fmock_api\u002Fshared`\n\nAnd a corresponding async pytest test added under the matching `asynctests\u002F` folder:\n\n- `packages\u002Fhttp-client-python\u002Ftests\u002Fmock_api\u002Fazure\u002Fasynctests`\n- `packages\u002Fhttp-client-python\u002Ftests\u002Fmock_api\u002Funbranded\u002Fasynctests`\n- `packages\u002Fhttp-client-python\u002Ftests\u002Fmock_api\u002Fshared\u002Fasynctests`\n\n## Workflow (copy as checklist)\n\nTest-writing progress:\n\n- [ ] Ensure prerequisites are met (pnpm install, package build)\n- [ ] Identify the Spector case link (directly, or extracted from PR)\n- [ ] Update spec dependency version if the case is from an unreleased PR\n- [ ] Decide the destination folder(s): azure vs unbranded vs shared\n- [ ] Regenerate the specific generated client (do NOT run full regeneration)\n- [ ] Find existing test file to extend (or create a new one)\n- [ ] Implement sync + async test(s) that match the case’s request\u002Fresponse expectations\n- [ ] Update test requirements only if a new dependency is introduced\n- [ ] Format changed python files with Black (`python -m black \u003Cpaths> --config .\u002Feng\u002Fscripts\u002Fci\u002Fconfig\u002Fpyproject.toml`)\n- [ ] Validate test locally (start Spector mock server + run pytest)\n- [ ] Add a changelog entry under `.chronus\u002Fchanges`\n\n## Prerequisites — Environment setup\n\nBefore starting, ensure the build environment is ready:\n\n1. **Install dependencies** (from repo root):\n   ```bash\n   pnpm install\n   ```\n2. **Build the http-client-python package** (required before any `tsp compile`):\n   ```bash\n   cd packages\u002Fhttp-client-python\n   npm install\n   npm run build\n   ```\n\n> ⚠️ Do NOT run `pnpm build` at the repo root — it builds the entire monorepo (including the website) and takes 7+ minutes. Only the http-client-python package build is needed.\n\n## Step 1 — Identify the Spector case link\n\n### If input is a Spector case link\n\nUse it directly.\n\n### If input is a PR link\n\n1. List changed files.\n2. From changed files, pick the ones under:\n   - `packages\u002Fhttp-specs\u002Fspecs\u002F` (microsoft\u002Ftypespec)\n   - `packages\u002Fazure-http-specs\u002Fspecs\u002F` (Azure\u002Ftypespec-azure)\n3. Extract the specific case\u002Fscenario path(s) to target.\n\n## Step 2 — Update spec dependency (if needed)\n\nIf the Spector case comes from a PR that hasn't been released yet, you must bump the spec dependency in `packages\u002Fhttp-client-python\u002Fpackage.json`:\n\n- For `Azure\u002Ftypespec-azure` cases: update `@azure-tools\u002Fazure-http-specs`\n- For `microsoft\u002Ftypespec` cases: update `@typespec\u002Fhttp-specs`\n\nTo find the latest dev version, check npm:\n\n```bash\nnpm view @azure-tools\u002Fazure-http-specs versions --json | tail -5\nnpm view @typespec\u002Fhttp-specs versions --json | tail -5\n```\n\nPick the newest version that includes the Spector case you need. Prefer a stable version (e.g., `0.1.0-alpha.38`) if one exists; only fall back to a `-dev.X` version (e.g., `0.1.0-alpha.38-dev.2`) when no stable version contains the change yet.\n\n**Example 1 — a newer stable version is available:**\n\n```jsonc\n\u002F\u002F Before\n\"@azure-tools\u002Fazure-http-specs\": \"0.1.0-alpha.37\",\n\n\u002F\u002F After (stable 0.1.0-alpha.38 exists and includes the case)\n\"@azure-tools\u002Fazure-http-specs\": \"0.1.0-alpha.38\",\n```\n\n**Example 2 — no new stable, only a dev version:**\n\n```jsonc\n\u002F\u002F Before\n\"@azure-tools\u002Fazure-http-specs\": \"0.1.0-alpha.37\",\n\n\u002F\u002F After (0.1.0-alpha.38 does not exist yet, use dev)\n\"@azure-tools\u002Fazure-http-specs\": \"0.1.0-alpha.38-dev.2\",\n```\n\nSame pattern applies to `@typespec\u002Fhttp-specs`.\n\nAfter bumping, run `npm run install` under `packages\u002Fhttp-client-python` to update the lock file.\n\n## Step 3 — Choose where to put the test\n\n### Rule A: Spector in Azure\u002Ftypespec-azure\n\nWrite the python test in:\n\n- `packages\u002Fhttp-client-python\u002Ftests\u002Fmock_api\u002Fazure`\n\n### Rule B: Spector in microsoft\u002Ftypespec\n\nYou may need either:\n\n- **Option (a) shared only**: `...\u002Fmock_api\u002Fshared`\n- **Option (b) both flavors**: `...\u002Fmock_api\u002Fazure` AND `...\u002Fmock_api\u002Funbranded`\n\nDecide with this concrete check:\n\n1. Locate the generated python package\u002Fmodule for the scenario in BOTH:\n   - `packages\u002Fhttp-client-python\u002Ftests\u002Fgenerated\u002Fazure`\n   - `packages\u002Fhttp-client-python\u002Ftests\u002Fgenerated\u002Funbranded`\n2. If the import root and client\u002Fmodel API surface you need are the same (same module path + same client entrypoint), write ONE shared test in `mock_api\u002Fshared`.\n3. If import paths differ (or one flavor lacks the needed client), write separate tests under both `mock_api\u002Fazure` and `mock_api\u002Funbranded`.\n\nWhy: both azure and unbranded tox runs include `mock_api\u002Fshared`, so shared tests are preferred when they can import the same generated package.\n\n## Step 4 — Regenerate the specific generated client\n\nGenerated code is gitignored (`packages\u002Fhttp-client-python\u002Ftests\u002Fgenerated\u002F`). You must regenerate the specific spec before writing tests.\n\n**Compile only the single spec you need** (example for azure-core-page):\n\n```bash\ncd packages\u002Fhttp-client-python\nnpx tsx .\u002Feng\u002Fscripts\u002Fci\u002Fregenerate.ts --flavor azure --name azure\u002Fcore\u002Fpage\n```\n\nThe `--flavor` flag selects `azure` or `unbranded`. The `--name` flag is a case-insensitive substring match on the package name.\n\n> ⚠️ Do NOT run `npx tsx .\u002Feng\u002Fscripts\u002Fci\u002Fregenerate.ts` without `--name` — it compiles ALL specs and takes 40+ minutes. Only regenerate the specific spec you need.\n> ⚠️ Do NOT use `npm run regenerate -- --flavor ...` — npm may strip the flags. Use `npx tsx` directly.\n\n**Verify** the generated client has the expected method:\n\n```bash\ngrep -r \"method_name\" tests\u002Fgenerated\u002Fazure\u002F \u003C package-name > \u002F\n```\n\n## Step 5 — Find existing test file (or create one)\n\n1. Search in the chosen folder for an existing test covering the same feature area.\n   - Prefer extending an existing `test_*.py` when it already imports the same generated module.\n2. In parallel, find the matching async test in `asynctests\u002F`.\n\n- If you extend `mock_api\u002Fazure\u002Ftest_\u003Carea>.py`, also extend `mock_api\u002Fazure\u002Fasynctests\u002Ftest_\u003Carea>_async.py` (or create it if missing).\n- If you extend `mock_api\u002Fshared\u002Ftest_\u003Carea>.py`, also extend `mock_api\u002Fshared\u002Fasynctests\u002Ftest_\u003Carea>_async.py`.\n- If you extend `mock_api\u002Funbranded\u002Ftest_\u003Carea>.py`, also extend `mock_api\u002Funbranded\u002Fasynctests\u002Ftest_\u003Carea>_async.py`.\n\n3. If no sync test exists, create a new `test_\u003Carea>.py` and also create the async counterpart under `asynctests\u002F`.\n\nConventions to match:\n\n- Use `pytest`.\n- Use a `client()` fixture that constructs the generated client and yields it via context manager.\n- For async tests: use `async def client()` fixture + `async with ...` and mark tests with `@pytest.mark.asyncio`.\n- Follow existing assertion style (direct equality for models; `list(...)` for paged results).\n\n## Step 6 — Implement the test from the Spector expectations\n\n1. Read the Spector case to identify:\n   - operation name \u002F route\n   - HTTP method\n   - parameter locations (path\u002Fquery\u002Fheader\u002Fbody)\n   - request body shape + media type\n   - response status code + headers + body\n2. Translate into SDK calls:\n   - construct the client\n   - call the method with the specified inputs\n   - assert the returned value matches the expected response\n   - if the scenario requires sending data, call the corresponding PUT\u002FPOST\u002FPATCH and assert no unexpected error\n\nPractical guidance:\n\n- Prefer comparing with generated model instances (e.g., `models.Foo(...)`) when the SDK returns models.\n- If the response is a stream or iterator, materialize it (`list(...)`) before asserting.\n- Async iterator pattern (seen in existing tests): `result = [item async for item in client.list(...)]`.\n- If the scenario is about serialization (e.g., XML), assert round-trip via GET\u002FPUT (pattern: `assert client.foo.get() == model; client.foo.put(model)`).\n\nAsync client import patterns (match the folder you’re writing to):\n\n- Azure: import `aio` submodule alongside models, e.g. `from specs.\u003C...> import models, aio`, then `async with aio.\u003CClient>()` and `await client.\u003Cop>(...)`.\n- Shared\u002Funbranded generated clients often expose `.aio` modules, e.g. `from \u003Cpkg>.aio import \u003CClient>`.\n\n## Step 7 — Dependencies (only when needed)\n\nDefault: do NOT add new dependencies.\n\nOnly if your new\u002Fextended test imports a package not already available:\n\n- Add it to the appropriate requirements file under `packages\u002Fhttp-client-python\u002Ftests\u002Frequirements\u002F`:\n  - `base.txt` — shared dependencies (pytest, pytest-asyncio, etc.)\n  - `azure.txt` — Azure-specific dependencies (azure-core, azure-mgmt-core)\n  - `unbranded.txt` — unbranded-specific dependencies (corehttp)\n\nAvoid adding dependencies unless strictly required by the test.\n\n## Step 8 — Format changed files\n\nFormat any python files you changed using Black with the project's shared config:\n\n```bash\ncd packages\u002Fhttp-client-python\npython -m black .\u002Feng\u002Fscripts\u002Fci\u002Fconfig\u002Fpyproject.toml \u003C paths > --config\n```\n\nReplace `\u003Cpaths>` with the specific files and\u002For folders you modified (relative to the `http-client-python` root).\n\nAlternatively, you can format all test files via the npm script:\n\n```bash\nnpm run format -- --generator\n```\n\n## Step 9 — Validate your test locally\n\nBefore opening a PR, run your new or updated test. You will need two terminals: one to run the Spector mock API server, and another to run pytest.\n\n1. **Determine the test flavor.** Pick the flavor that matches the test you changed:\n   - Azure tests → `azure`\n   - Unbranded tests → `unbranded`\n\n2. **Regenerate and install packages** (if not already done):\n\n   ```bash\n   cd packages\u002Fhttp-client-python\n   npx tsx .\u002Feng\u002Fscripts\u002Fci\u002Fregenerate.ts --flavor \u003Cazure|unbranded> --name \u003Cspec-name>\n   ```\n\n3. **Create and activate a virtual environment** (if one does not already exist):\n\n   ```bash\n   cd packages\u002Fhttp-client-python\u002Ftests\n   python -m venv .venv\n   # Windows:\n   .venv\\Scripts\\activate\n   # Linux\u002FMac:\n   source .venv\u002Fbin\u002Factivate\n   ```\n\n4. **Install dependencies and the generated SDK:**\n\n   ```bash\n   pip install -r requirements\u002Fbase.txt\n   pip install -r requirements\u002F\u003Cazure|unbranded>.txt\n\n   # install only a single generated SDK:\n   pip install --no-deps -e generated\u002F\u003Cflavor>\u002F\u003Csdk-folder-name>\n   ```\n\n5. **Start the Spector mock API server** in a separate terminal:\n\n   ```bash\n   cd packages\u002Fhttp-client-python\n   npx tsp-spector serve node_modules\u002F@azure-tools\u002Fazure-http-specs\u002Fspecs\u002F node_modules\u002F@typespec\u002Fhttp-specs\u002Fspecs\u002F\n   ```\n\n   Wait until you see the server listening message before running tests.\n\n6. **Run the test** in the original terminal (with venv activated):\n\n   ```bash\n   cd packages\u002Fhttp-client-python\u002Ftests\n   pytest mock_api\u002F \u003C azure | unbranded | shared > \u002F \u003C test_file > .py -v\n   ```\n\n   Verify that all tests pass before proceeding.\n\n   > **Important:** If you only added or changed test files, confirming the changed test passes is sufficient. However, if you modified emitter source code (under `generator\u002F` or `emitter\u002F`), you **must** run the full test suite for the affected flavor(s) to catch regressions before proceeding.\n\n## Step 10 — Add a changelog entry\n\nCreate a changelog file under `.chronus\u002Fchanges\u002F` to document the change. The file should be a Markdown file with YAML frontmatter specifying the change kind and affected package(s).\n\n**File naming convention:** `\u003Cshort-description>-\u003CYYYY>-\u003CM>-\u003CDD>-\u003CH>-\u003Cm>-\u003Cs>.md`\n\n**Template:**\n\n```markdown\n---\nchangeKind: internal\npackages:\n  - \"@typespec\u002Fhttp-client-python\"\n---\n\n\u003CBrief description of what was added or changed.>\n```\n\n**Available `changeKind` values:**\n\n| Kind           | When to use                                      |\n| -------------- | ------------------------------------------------ |\n| `internal`     | Internal changes not user-facing (most test PRs) |\n| `fix`          | Bug fixes to existing features                   |\n| `feature`      | New user-facing features                         |\n| `deprecation`  | Deprecating an existing feature                  |\n| `breaking`     | Breaking changes                                 |\n| `dependencies` | Dependency bumps                                 |\n\nFor test additions, use `changeKind: internal` and list `@typespec\u002Fhttp-client-python` as the package.\n\n## Notes\n\n- Keep the skill concise: prefer adding a single focused test per scenario.\n- Don’t duplicate existing coverage: extend an existing file when reasonable.\n- Use forward-slash paths only.\n- Generated code is gitignored — do NOT attempt to commit it. Only commit: test files, and `package.json`\u002F`package-lock.json` (if dependency versions were updated).\n- You should still validate your test locally (Step 9) before pushing. CI runs the full regeneration and the complete test matrix, but catching failures early locally is faster.\n- Do NOT run `npm run regenerate` without `--name` for verification — CI will handle full regeneration.\n","# Writing python SDK tests from a Spector case\n\n## Inputs\n\nYou may receive either:\n\n- **Spector case link** (preferred): link to a specific scenario\u002Fcase under:\n  - `https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftypespec\u002Ftree\u002Fmain\u002Fpackages\u002Fhttp-specs\u002Fspecs\u002F...`\n  - `https:\u002F\u002Fgithub.com\u002FAzure\u002Ftypespec-azure\u002Ftree\u002Fmain\u002Fpackages\u002Fazure-http-specs\u002Fspecs\u002F...`\n- **PR link**: a GitHub PR that changes one or more Spector cases.\n\nSpector cases define the **expected request + response**. The goal is to add\u002Fextend python tests that validate the generated SDK behaves accordingly.\n\n## Output\n\nA python pytest test (sync) added to one of:\n\n- `packages\u002Fhttp-client-python\u002Ftests\u002Fmock_api\u002Fazure`\n- `packages\u002Fhttp-client-python\u002Ftests\u002Fmock_api\u002Funbranded`\n- `packages\u002Fhttp-client-python\u002Ftests\u002Fmock_api\u002Fshared`\n\nAnd a corresponding async pytest test added under the matching `asynctests\u002F` folder:\n\n- `packages\u002Fhttp-client-python\u002Ftests\u002Fmock_api\u002Fazure\u002Fasynctests`\n- `packages\u002Fhttp-client-python\u002Ftests\u002Fmock_api\u002Funbranded\u002Fasynctests`\n- `packages\u002Fhttp-client-python\u002Ftests\u002Fmock_api\u002Fshared\u002Fasynctests`\n\n## Workflow (copy as checklist)\n\nTest-writing progress:\n\n- [ ] Ensure prerequisites are met (pnpm install, package build)\n- [ ] Identify the Spector case link (directly, or extracted from PR)\n- [ ] Update spec dependency version if the case is from an unreleased PR\n- [ ] Decide the destination folder(s): azure vs unbranded vs shared\n- [ ] Regenerate the specific generated client (do NOT run full regeneration)\n- [ ] Find existing test file to extend (or create a new one)\n- [ ] Implement sync + async test(s) that match the case’s request\u002Fresponse expectations\n- [ ] Update test requirements only if a new dependency is introduced\n- [ ] Format changed python files with Black (`python -m black \u003Cpaths> --config .\u002Feng\u002Fscripts\u002Fci\u002Fconfig\u002Fpyproject.toml`)\n- [ ] Validate test locally (start Spector mock server + run pytest)\n- [ ] Add a changelog entry under `.chronus\u002Fchanges`\n\n## Prerequisites — Environment setup\n\nBefore starting, ensure the build environment is ready:\n\n1. **Install dependencies** (from repo root):\n   ```bash\n   pnpm install\n   ```\n2. **Build the http-client-python package** (required before any `tsp compile`):\n   ```bash\n   cd packages\u002Fhttp-client-python\n   npm install\n   npm run build\n   ```\n\n> ⚠️ Do NOT run `pnpm build` at the repo root — it builds the entire monorepo (including the website) and takes 7+ minutes. Only the http-client-python package build is needed.\n\n## Step 1 — Identify the Spector case link\n\n### If input is a Spector case link\n\nUse it directly.\n\n### If input is a PR link\n\n1. List changed files.\n2. From changed files, pick the ones under:\n   - `packages\u002Fhttp-specs\u002Fspecs\u002F` (microsoft\u002Ftypespec)\n   - `packages\u002Fazure-http-specs\u002Fspecs\u002F` (Azure\u002Ftypespec-azure)\n3. Extract the specific case\u002Fscenario path(s) to target.\n\n## Step 2 — Update spec dependency (if needed)\n\nIf the Spector case comes from a PR that hasn't been released yet, you must bump the spec dependency in `packages\u002Fhttp-client-python\u002Fpackage.json`:\n\n- For `Azure\u002Ftypespec-azure` cases: update `@azure-tools\u002Fazure-http-specs`\n- For `microsoft\u002Ftypespec` cases: update `@typespec\u002Fhttp-specs`\n\nTo find the latest dev version, check npm:\n\n```bash\nnpm view @azure-tools\u002Fazure-http-specs versions --json | tail -5\nnpm view @typespec\u002Fhttp-specs versions --json | tail -5\n```\n\nPick the newest version that includes the Spector case you need. Prefer a stable version (e.g., `0.1.0-alpha.38`) if one exists; only fall back to a `-dev.X` version (e.g., `0.1.0-alpha.38-dev.2`) when no stable version contains the change yet.\n\n**Example 1 — a newer stable version is available:**\n\n```jsonc\n\u002F\u002F Before\n\"@azure-tools\u002Fazure-http-specs\": \"0.1.0-alpha.37\",\n\n\u002F\u002F After (stable 0.1.0-alpha.38 exists and includes the case)\n\"@azure-tools\u002Fazure-http-specs\": \"0.1.0-alpha.38\",\n```\n\n**Example 2 — no new stable, only a dev version:**\n\n```jsonc\n\u002F\u002F Before\n\"@azure-tools\u002Fazure-http-specs\": \"0.1.0-alpha.37\",\n\n\u002F\u002F After (0.1.0-alpha.38 does not exist yet, use dev)\n\"@azure-tools\u002Fazure-http-specs\": \"0.1.0-alpha.38-dev.2\",\n```\n\nSame pattern applies to `@typespec\u002Fhttp-specs`.\n\nAfter bumping, run `npm run install` under `packages\u002Fhttp-client-python` to update the lock file.\n\n## Step 3 — Choose where to put the test\n\n### Rule A: Spector in Azure\u002Ftypespec-azure\n\nWrite the python test in:\n\n- `packages\u002Fhttp-client-python\u002Ftests\u002Fmock_api\u002Fazure`\n\n### Rule B: Spector in microsoft\u002Ftypespec\n\nYou may need either:\n\n- **Option (a) shared only**: `...\u002Fmock_api\u002Fshared`\n- **Option (b) both flavors**: `...\u002Fmock_api\u002Fazure` AND `...\u002Fmock_api\u002Funbranded`\n\nDecide with this concrete check:\n\n1. Locate the generated python package\u002Fmodule for the scenario in BOTH:\n   - `packages\u002Fhttp-client-python\u002Ftests\u002Fgenerated\u002Fazure`\n   - `packages\u002Fhttp-client-python\u002Ftests\u002Fgenerated\u002Funbranded`\n2. If the import root and client\u002Fmodel API surface you need are the same (same module path + same client entrypoint), write ONE shared test in `mock_api\u002Fshared`.\n3. If import paths differ (or one flavor lacks the needed client), write separate tests under both `mock_api\u002Fazure` and `mock_api\u002Funbranded`.\n\nWhy: both azure and unbranded tox runs include `mock_api\u002Fshared`, so shared tests are preferred when they can import the same generated package.\n\n## Step 4 — Regenerate the specific generated client\n\nGenerated code is gitignored (`packages\u002Fhttp-client-python\u002Ftests\u002Fgenerated\u002F`). You must regenerate the specific spec before writing tests.\n\n**Compile only the single spec you need** (example for azure-core-page):\n\n```bash\ncd packages\u002Fhttp-client-python\nnpx tsx .\u002Feng\u002Fscripts\u002Fci\u002Fregenerate.ts --flavor azure --name azure\u002Fcore\u002Fpage\n```\n\nThe `--flavor` flag selects `azure` or `unbranded`. The `--name` flag is a case-insensitive substring match on the package name.\n\n> ⚠️ Do NOT run `npx tsx .\u002Feng\u002Fscripts\u002Fci\u002Fregenerate.ts` without `--name` — it compiles ALL specs and takes 40+ minutes. Only regenerate the specific spec you need.\n> ⚠️ Do NOT use `npm run regenerate -- --flavor ...` — npm may strip the flags. Use `npx tsx` directly.\n\n**Verify** the generated client has the expected method:\n\n```bash\ngrep -r \"method_name\" tests\u002Fgenerated\u002Fazure\u002F \u003C package-name > \u002F\n```\n\n## Step 5 — Find existing test file (or create one)\n\n1. Search in the chosen folder for an existing test covering the same feature area.\n   - Prefer extending an existing `test_*.py` when it already imports the same generated module.\n2. In parallel, find the matching async test in `asynctests\u002F`.\n\n- If you extend `mock_api\u002Fazure\u002Ftest_\u003Carea>.py`, also extend `mock_api\u002Fazure\u002Fasynctests\u002Ftest_\u003Carea>_async.py` (or create it if missing).\n- If you extend `mock_api\u002Fshared\u002Ftest_\u003Carea>.py`, also extend `mock_api\u002Fshared\u002Fasynctests\u002Ftest_\u003Carea>_async.py`.\n- If you extend `mock_api\u002Funbranded\u002Ftest_\u003Carea>.py`, also extend `mock_api\u002Funbranded\u002Fasynctests\u002Ftest_\u003Carea>_async.py`.\n\n3. If no sync test exists, create a new `test_\u003Carea>.py` and also create the async counterpart under `asynctests\u002F`.\n\nConventions to match:\n\n- Use `pytest`.\n- Use a `client()` fixture that constructs the generated client and yields it via context manager.\n- For async tests: use `async def client()` fixture + `async with ...` and mark tests with `@pytest.mark.asyncio`.\n- Follow existing assertion style (direct equality for models; `list(...)` for paged results).\n\n## Step 6 — Implement the test from the Spector expectations\n\n1. Read the Spector case to identify:\n   - operation name \u002F route\n   - HTTP method\n   - parameter locations (path\u002Fquery\u002Fheader\u002Fbody)\n   - request body shape + media type\n   - response status code + headers + body\n2. Translate into SDK calls:\n   - construct the client\n   - call the method with the specified inputs\n   - assert the returned value matches the expected response\n   - if the scenario requires sending data, call the corresponding PUT\u002FPOST\u002FPATCH and assert no unexpected error\n\nPractical guidance:\n\n- Prefer comparing with generated model instances (e.g., `models.Foo(...)`) when the SDK returns models.\n- If the response is a stream or iterator, materialize it (`list(...)`) before asserting.\n- Async iterator pattern (seen in existing tests): `result = [item async for item in client.list(...)]`.\n- If the scenario is about serialization (e.g., XML), assert round-trip via GET\u002FPUT (pattern: `assert client.foo.get() == model; client.foo.put(model)`).\n\nAsync client import patterns (match the folder you’re writing to):\n\n- Azure: import `aio` submodule alongside models, e.g. `from specs.\u003C...> import models, aio`, then `async with aio.\u003CClient>()` and `await client.\u003Cop>(...)`.\n- Shared\u002Funbranded generated clients often expose `.aio` modules, e.g. `from \u003Cpkg>.aio import \u003CClient>`.\n\n## Step 7 — Dependencies (only when needed)\n\nDefault: do NOT add new dependencies.\n\nOnly if your new\u002Fextended test imports a package not already available:\n\n- Add it to the appropriate requirements file under `packages\u002Fhttp-client-python\u002Ftests\u002Frequirements\u002F`:\n  - `base.txt` — shared dependencies (pytest, pytest-asyncio, etc.)\n  - `azure.txt` — Azure-specific dependencies (azure-core, azure-mgmt-core)\n  - `unbranded.txt` — unbranded-specific dependencies (corehttp)\n\nAvoid adding dependencies unless strictly required by the test.\n\n## Step 8 — Format changed files\n\nFormat any python files you changed using Black with the project's shared config:\n\n```bash\ncd packages\u002Fhttp-client-python\npython -m black .\u002Feng\u002Fscripts\u002Fci\u002Fconfig\u002Fpyproject.toml \u003C paths > --config\n```\n\nReplace `\u003Cpaths>` with the specific files and\u002For folders you modified (relative to the `http-client-python` root).\n\nAlternatively, you can format all test files via the npm script:\n\n```bash\nnpm run format -- --generator\n```\n\n## Step 9 — Validate your test locally\n\nBefore opening a PR, run your new or updated test. You will need two terminals: one to run the Spector mock API server, and another to run pytest.\n\n1. **Determine the test flavor.** Pick the flavor that matches the test you changed:\n   - Azure tests → `azure`\n   - Unbranded tests → `unbranded`\n\n2. **Regenerate and install packages** (if not already done):\n\n   ```bash\n   cd packages\u002Fhttp-client-python\n   npx tsx .\u002Feng\u002Fscripts\u002Fci\u002Fregenerate.ts --flavor \u003Cazure|unbranded> --name \u003Cspec-name>\n   ```\n\n3. **Create and activate a virtual environment** (if one does not already exist):\n\n   ```bash\n   cd packages\u002Fhttp-client-python\u002Ftests\n   python -m venv .venv\n   # Windows:\n   .venv\\Scripts\\activate\n   # Linux\u002FMac:\n   source .venv\u002Fbin\u002Factivate\n   ```\n\n4. **Install dependencies and the generated SDK:**\n\n   ```bash\n   pip install -r requirements\u002Fbase.txt\n   pip install -r requirements\u002F\u003Cazure|unbranded>.txt\n\n   # install only a single generated SDK:\n   pip install --no-deps -e generated\u002F\u003Cflavor>\u002F\u003Csdk-folder-name>\n   ```\n\n5. **Start the Spector mock API server** in a separate terminal:\n\n   ```bash\n   cd packages\u002Fhttp-client-python\n   npx tsp-spector serve node_modules\u002F@azure-tools\u002Fazure-http-specs\u002Fspecs\u002F node_modules\u002F@typespec\u002Fhttp-specs\u002Fspecs\u002F\n   ```\n\n   Wait until you see the server listening message before running tests.\n\n6. **Run the test** in the original terminal (with venv activated):\n\n   ```bash\n   cd packages\u002Fhttp-client-python\u002Ftests\n   pytest mock_api\u002F \u003C azure | unbranded | shared > \u002F \u003C test_file > .py -v\n   ```\n\n   Verify that all tests pass before proceeding.\n\n   > **Important:** If you only added or changed test files, confirming the changed test passes is sufficient. However, if you modified emitter source code (under `generator\u002F` or `emitter\u002F`), you **must** run the full test suite for the affected flavor(s) to catch regressions before proceeding.\n\n## Step 10 — Add a changelog entry\n\nCreate a changelog file under `.chronus\u002Fchanges\u002F` to document the change. The file should be a Markdown file with YAML frontmatter specifying the change kind and affected package(s).\n\n**File naming convention:** `\u003Cshort-description>-\u003CYYYY>-\u003CM>-\u003CDD>-\u003CH>-\u003Cm>-\u003Cs>.md`\n\n**Template:**\n\n```markdown\n---\nchangeKind: internal\npackages:\n  - \"@typespec\u002Fhttp-client-python\"\n---\n\n\u003CBrief description of what was added or changed.>\n```\n\n**Available `changeKind` values:**\n\n| Kind           | When to use                                      |\n| -------------- | ------------------------------------------------ |\n| `internal`     | Internal changes not user-facing (most test PRs) |\n| `fix`          | Bug fixes to existing features                   |\n| `feature`      | New user-facing features                         |\n| `deprecation`  | Deprecating an existing feature                  |\n| `breaking`     | Breaking changes                                 |\n| `dependencies` | Dependency bumps                                 |\n\nFor test additions, use `changeKind: internal` and list `@typespec\u002Fhttp-client-python` as the package.\n\n## Notes\n\n- Keep the skill concise: prefer adding a single focused test per scenario.\n- Don’t duplicate existing coverage: extend an existing file when reasonable.\n- Use forward-slash paths only.\n- Generated code is gitignored — do NOT attempt to commit it. Only commit: test files, and `package.json`\u002F`package-lock.json` (if dependency versions were updated).\n- You should still validate your test locally (Step 9) before pushing. CI runs the full regeneration and the complete test matrix, but catching failures early locally is faster.\n- Do NOT run `npm run regenerate` without `--name` for verification — CI will handle full regeneration.\n",{"name":5,"description":7},"main","05b9bad7c57b9b58e8fb5390f9bab081a1a9ac31",".github\u002Fskills\u002Fpython-sdk-spector-mock-api-tests",423,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftypespec","https:\u002F\u002Ftypespec.io\u002F","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-11-14 06:59:49",{"source":8,"skillName":5,"commands":71,"prompt":81,"zipAvailable":82},[72,75,78],{"tool":73,"command":74},"npx","npx skills add microsoft\u002Ftypespec --skill writing-python-sdk-spector-mock-api-tests",{"tool":76,"command":77},"bunx","bunx skills add microsoft\u002Ftypespec --skill writing-python-sdk-spector-mock-api-tests",{"tool":79,"command":80},"pnpm","pnpm dlx skills add microsoft\u002Ftypespec --skill writing-python-sdk-spector-mock-api-tests","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftypespec\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpython-sdk-spector-mock-api-tests\u002FSKILL.md",true,[],[85,114,135,156,169,188],{"skillNo":86,"name":87,"nameZh":6,"description":88,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":89,"categories":90,"keywords":97,"publishedAt":55},"01M69B7KKBZE845SFNJQ5H992V","test-unbranded-emitter","Build and test the @typespec\u002Fhttp-client-python emitter. Use this skill whenever the user wants to test their local changes to the emitter, run the generator test suite, check if their http-client-python changes are passing, or validate a fix. Triggers on phrases like \"test the emitter\", \"run tests\", \"check if my changes pass\", \"run test:generator\", \"run CI\", or any mention of testing\u002Fvalidating changes in the emitter package.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftypespec\u002Fblob\u002Fmain\u002Fpackages\u002Fhttp-client-python\u002F.github\u002Fskills\u002Ftest-unbranded-emitter\u002FSKILL.md",[91,94],{"categoryNo":92,"categoryName":93,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":95,"categoryName":96,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[98,99,100,35,101,102,103,53,51,104,105,106,107,108,50,109,110,111,44,112,46,113],"test","test unbranded emitter","testing","build and test","validate","run tests","run","package","ci","check","fix","test suite","build","local","triggers","changes",{"skillNo":115,"name":116,"nameZh":6,"description":117,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":118,"categories":119,"keywords":121,"publishedAt":55},"01M69B7H23BJ7ART6SA67EFJ5W","generate-from-typespec","Generate Python SDK code from a TypeSpec specification using the local emitter. Use this skill when the user wants to generate\u002Fregenerate a Python client from a TypeSpec spec, provides a GitHub URL or local path to a TypeSpec project, or says things like \"generate from this spec\", \"emit Python from this tsp\", \"regenerate the SDK\", or \"compile this TypeSpec for Python\".","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftypespec\u002Fblob\u002Fmain\u002Fpackages\u002Fhttp-client-python\u002F.github\u002Fskills\u002Fgenerate-from-typespec\u002FSKILL.md",[120],{"categoryNo":95,"categoryName":96,"taxonomyType":21,"taxonomyTypeDesc":22},[51,122,123,124,35,125,36,126,127,42,128,50,129,111,130,131,132,133,134,45],"generate from typespec","generate","spec","github","code","compile","user","specification","project","client","URL","for","things",{"skillNo":136,"name":137,"nameZh":6,"description":138,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":139,"categories":140,"keywords":142,"publishedAt":55},"01M69B7EJ0F9HGY2Y8RMX9C4E6","diff-upstream","Regenerate the local emitter and diff the generated code against the upstream baseline checked into autorest.python. Use this skill when the user wants to see how their emitter changes affect generated code compared to what's currently in production, says things like \"diff upstream\", \"compare to baseline\", \"what changed vs production\", \"show me the diff\", \"how does this affect generated code\", or wants to validate their changes produce the expected output differences.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftypespec\u002Fblob\u002Fmain\u002Fpackages\u002Fhttp-client-python\u002F.github\u002Fskills\u002Fdiff-upstream\u002FSKILL.md",[141],{"categoryNo":95,"categoryName":96,"taxonomyType":21,"taxonomyTypeDesc":22},[143,144,145,35,102,126,146,147,148,149,150,50,151,152,111,153,154,134,113,155,45],"diff upstream","diff","upstream","produce","baseline","show me","how","generated","show","me","compare","output","expected",{"skillNo":157,"name":158,"nameZh":6,"description":159,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":160,"categories":161,"keywords":162,"publishedAt":55},"01M69B79NV57JMNA7RS13MAE5P","pnpm-format","Format the codebase with pnpm and recover from common formatting failures.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftypespec\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpnpm-format\u002FSKILL.md",[],[163,164,79,165,166,167,168],"pnpm format","format","common","formatting","with","codebase",{"skillNo":170,"name":171,"nameZh":6,"description":172,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":173,"categories":174,"keywords":175,"publishedAt":55},"01M69B784PEAQ45ZKNZAX9NCA9","minimal-repro","Help create a minimal reproduction for a TypeSpec compiler or emitter bug. Use when a user provides TypeSpec source (pasted code or a GitHub URL) and describes an issue. Reproduces locally and reduces to a single-file repro.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftypespec\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fminimal-repro\u002FSKILL.md",[],[176,177,178,125,51,179,126,180,181,182,128,50,183,184,185,132,133,186,187,45],"minimal repro","repro","minimal","create","help","compiler","file","single-file","bug","issue","source","single",{"skillNo":189,"name":190,"nameZh":6,"description":191,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":192,"categories":193,"keywords":194,"publishedAt":55},"01M69B76464N72EBS07HC4NMWJ","http-client-python-bump-and-release","Create a PR to bump TypeSpec\u002FAzure Tools dependencies, update peer dependencies, or release a new version of the http-client-python package.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftypespec\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fhttp-client-python-bump-and-release\u002FSKILL.md",[],[35,53,195,196,197,131,198,54,52,51,179,199,105,200,201,202,203,204],"http client python bump and release","release","bump","http client","update","Tools","version","peer","dependencies","new"]