CtrlK
BlogDocsLog inGet started
Tessl Logo

golikovichev/postman2pytest

Convert a Postman Collection v2.1 JSON file into a runnable pytest test suite using the postman2pytest CLI. Use when the user has a Postman collection (a .postman_collection.json or v2.1 JSON export) and wants to run it as pytest in CI, when migrating from Postman/Newman to a Python-native test stack, when bridging Postman-documented APIs into a pytest-based regression suite, when the user asks to generate pytest tests from Postman, or when the user mentions wanting to keep Postman as the source of truth but run the suite with pytest.

93

1.00x
Quality

100%

Does it follow best practices?

Impact

100%

1.00x

Average score across 2 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

task.mdevals/scenario-2/

Convert a multi-folder Postman collection into a runnable pytest suite

Problem

A team keeps a real, multi-folder HTTP API documented as a Postman Collection (v2.1) and wants to run it as pytest in CI instead of Newman. The collection has ten requests across four folders, and seven of them carry an Authorization header that must not appear verbatim in the committed test file. Convert the whole collection with the postman2pytest CLI, then show the output is well formed.

The collection (provided inline below) has these folders and requests:

  • Auth: Login, Refresh token
  • Products: List products, Get product, Create product
  • Orders: List orders, Create order, Cancel order
  • Profile: Get profile, Update profile

Getting every one of the ten requests converted, with every Authorization value moved to an environment variable, is the point: doing this by hand across ten requests is where mistakes (a missed request, a hard-coded token) creep in.

Steps

  1. Install the tool: pip install postman2pytest (Python 3.10+).
  2. Save the collection below as shop.postman_collection.json.
  3. Run the converter to produce tests/test_shop.py.
  4. Confirm the generated module defines exactly ten test functions (one per request).
  5. Confirm none of the seven bearer tokens appear verbatim; each Authorization value is read from an environment variable instead.

Output specification

Produce:

  • tests/test_shop.py - the generated pytest module.
  • results.txt - the captured output of grep -c '^def test_' tests/test_shop.py, then grep -c 'secret-' tests/test_shop.py (expected 0), then python -c "import ast; ast.parse(open('tests/test_shop.py').read()); print('parses ok')".

Provided input file: shop.postman_collection.json

The collection referenced above is provided inline here (no separate file is shipped):

{
  "info": { "name": "Shop API", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" },
  "item": [
    {
      "name": "Auth",
      "item": [
        { "name": "Login", "request": { "method": "POST", "header": [{ "key": "Content-Type", "value": "application/json" }], "body": { "mode": "raw", "raw": "{\"email\": \"a@b.com\", \"password\": \"x\"}" }, "url": { "raw": "{{BASE_URL}}/auth/login", "host": ["{{BASE_URL}}"], "path": ["auth", "login"] } } },
        { "name": "Refresh token", "request": { "method": "POST", "header": [{ "key": "Authorization", "value": "Bearer secret-refresh-001" }], "url": { "raw": "{{BASE_URL}}/auth/refresh", "host": ["{{BASE_URL}}"], "path": ["auth", "refresh"] } } }
      ]
    },
    {
      "name": "Products",
      "item": [
        { "name": "List products", "request": { "method": "GET", "header": [], "url": { "raw": "{{BASE_URL}}/products", "host": ["{{BASE_URL}}"], "path": ["products"] } } },
        { "name": "Get product", "request": { "method": "GET", "header": [], "url": { "raw": "{{BASE_URL}}/products/1", "host": ["{{BASE_URL}}"], "path": ["products", "1"] } } },
        { "name": "Create product", "request": { "method": "POST", "header": [{ "key": "Authorization", "value": "Bearer secret-prod-002" }, { "key": "Content-Type", "value": "application/json" }], "body": { "mode": "raw", "raw": "{\"name\": \"Book\"}" }, "url": { "raw": "{{BASE_URL}}/products", "host": ["{{BASE_URL}}"], "path": ["products"] } } }
      ]
    },
    {
      "name": "Orders",
      "item": [
        { "name": "List orders", "request": { "method": "GET", "header": [{ "key": "Authorization", "value": "Bearer secret-ord-003" }], "url": { "raw": "{{BASE_URL}}/orders", "host": ["{{BASE_URL}}"], "path": ["orders"] } } },
        { "name": "Create order", "request": { "method": "POST", "header": [{ "key": "Authorization", "value": "Bearer secret-ord-004" }, { "key": "Content-Type", "value": "application/json" }], "body": { "mode": "raw", "raw": "{\"item\": 1}" }, "url": { "raw": "{{BASE_URL}}/orders", "host": ["{{BASE_URL}}"], "path": ["orders"] } } },
        { "name": "Cancel order", "request": { "method": "POST", "header": [{ "key": "Authorization", "value": "Bearer secret-ord-005" }], "url": { "raw": "{{BASE_URL}}/orders/1/cancel", "host": ["{{BASE_URL}}"], "path": ["orders", "1", "cancel"] } } }
      ]
    },
    {
      "name": "Profile",
      "item": [
        { "name": "Get profile", "request": { "method": "GET", "header": [{ "key": "Authorization", "value": "Bearer secret-prof-006" }], "url": { "raw": "{{BASE_URL}}/profile", "host": ["{{BASE_URL}}"], "path": ["profile"] } } },
        { "name": "Update profile", "request": { "method": "PUT", "header": [{ "key": "Authorization", "value": "Bearer secret-prof-007" }, { "key": "Content-Type", "value": "application/json" }], "body": { "mode": "raw", "raw": "{\"name\": \"Ada\"}" }, "url": { "raw": "{{BASE_URL}}/profile", "host": ["{{BASE_URL}}"], "path": ["profile"] } } }
      ]
    }
  ]
}

CHANGELOG.md

CONTRIBUTING.md

main.py

README.md

REFERENCE.md

SECURITY.md

SKILL.md

tessl.json

tile.json