<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ITFabers</title>
    <description>The latest articles on DEV Community by ITFabers (@itfabers).</description>
    <link>https://dev.to/itfabers</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4060282%2F33e51341-4f1a-40ff-a06e-54b9a9fa882b.png</url>
      <title>DEV Community: ITFabers</title>
      <link>https://dev.to/itfabers</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/itfabers"/>
    <language>en</language>
    <item>
      <title>Schemathesis vs Postman for generated API tests</title>
      <dc:creator>ITFabers</dc:creator>
      <pubDate>Mon, 09 Nov 2026 19:44:12 +0000</pubDate>
      <link>https://dev.to/itfabers/schemathesis-vs-postman-for-generated-api-tests-4e9o</link>
      <guid>https://dev.to/itfabers/schemathesis-vs-postman-for-generated-api-tests-4e9o</guid>
      <description>&lt;p&gt;I get asked which one to use, and I think the question hides a false choice. Schemathesis and Postman are not two versions of the same tool. One generates requests from your schema while the test runs. The other stores requests you can send, and what you assert on them is up to you. Pick the wrong one for the job and you spend a week building the thing you did not need.&lt;/p&gt;

&lt;p&gt;Full disclosure: I build apitestgen, which generates test files from a spec. I have read the docs for both tools below and linked them so you can check me.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Schemathesis actually does
&lt;/h2&gt;

&lt;p&gt;Schemathesis reads an OpenAPI or GraphQL schema, or a gRPC service descriptor, and generates requests from it at run time. You do not write one test per endpoint. You point it at the schema, and it produces cases, including malformed ones, then checks the responses against what the schema promises.&lt;/p&gt;

&lt;p&gt;The docs put it this way: it "automatically generates property-based tests from OpenAPI and GraphQL schemas or gRPC service descriptors, chains operations into realistic workflows, and exercises the edge cases that break your API" (&lt;a href="https://schemathesis.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;Schemathesis docs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;In pytest the entry point is &lt;code&gt;@schema.parametrize()&lt;/code&gt;, which turns one test function into one test per operation, and &lt;code&gt;case.call_and_validate()&lt;/code&gt; sends each generated request and runs the built-in checks. Stateful tests are a separate class built with &lt;code&gt;schema.as_state_machine()&lt;/code&gt; (&lt;a href="https://schemathesis.readthedocs.io/en/stable/tutorials/pytest/" rel="noopener noreferrer"&gt;pytest tutorial&lt;/a&gt;). The CLI runs the full set, stateful testing included, in one command.&lt;/p&gt;

&lt;p&gt;The output is failures, not a suite you commit. When something breaks you get a minimal curl or grpcurl command that reproduces it. That is the point. It is a bug finder that runs against a live server.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Postman actually does
&lt;/h2&gt;

&lt;p&gt;Postman starts from requests. If you import an OpenAPI file, Postman generates "a collection with folders, requests, and response examples based on the specification." Spec Hub supports OpenAPI 2.0, 3.0, and 3.1, and you can import a spec as a collection or as a spec together with a collection (&lt;a href="https://learning.postman.com/docs/design-apis/specifications/import-a-specification" rel="noopener noreferrer"&gt;Postman import docs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The generated collection is scaffolding. The assertions are post-response scripts you add to a request, a folder, or the whole collection. Postman runs them in the Postman Sandbox and gives you &lt;code&gt;pm.test&lt;/code&gt; and Chai assertions, so a status check looks like this (&lt;a href="https://learning.postman.com/docs/tests-and-scripts/write-scripts/test-scripts/" rel="noopener noreferrer"&gt;Postman test scripts&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Status test&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Collection and folder scripts run after every request in that scope, which is how people reuse auth and response checks. You can run the collection in the Collection Runner or from the Postman CLI in CI.&lt;/p&gt;

&lt;p&gt;So the artefact is a collection that lives in Postman, or exports as JSON, plus the scripts you wrote. The schema import saves typing. It does not decide what a correct response looks like for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side by side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Where tests come from&lt;/th&gt;
&lt;th&gt;What you get&lt;/th&gt;
&lt;th&gt;What fails the run&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Schemathesis&lt;/td&gt;
&lt;td&gt;The schema, generated at run time&lt;/td&gt;
&lt;td&gt;Requests plus built-in schema checks&lt;/td&gt;
&lt;td&gt;Server errors, undocumented status codes, schema violations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Postman&lt;/td&gt;
&lt;td&gt;An imported spec plus your scripts&lt;/td&gt;
&lt;td&gt;A collection of requests with assertion scripts&lt;/td&gt;
&lt;td&gt;Whatever your &lt;code&gt;pm.test&lt;/code&gt; assertions check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;apitestgen&lt;/td&gt;
&lt;td&gt;A spec file you paste&lt;/td&gt;
&lt;td&gt;pytest, Jest, or Postman test files&lt;/td&gt;
&lt;td&gt;Generated checks for the happy path, auth failures, missing params, bad types, response schema&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Where each one wins
&lt;/h2&gt;

&lt;p&gt;Schemathesis is the right pick when you want to find bugs you did not think of, when the API is already running somewhere reachable, when your tests live in pytest, and when multi-step workflows matter. It can carry real identifiers from one operation to the next, so "create a booking, then fetch it" is one flow rather than two disconnected requests.&lt;/p&gt;

&lt;p&gt;Postman is the right pick when the team already lives in Postman, when you want a shared collection for manual exploration with assertions attached, when you need to hand a collection to someone who does not run Python, or when you want collection runs in CI through the Postman CLI.&lt;/p&gt;

&lt;p&gt;Neither answers a different question: "give me test files I can read, edit, and commit, that cover the boring cases." That is the gap I built into &lt;a href="https://apitestgen.dev/?utm_source=blog&amp;amp;utm_medium=organic&amp;amp;utm_campaign=schemathesis-vs-postman" rel="noopener noreferrer"&gt;apitestgen&lt;/a&gt;. Paste an OpenAPI, Swagger, or Postman file and you get pytest, Jest, or Postman tests covering the happy path, auth failures, missing parameters, wrong types, and response-schema checks. The files are yours to edit and run wherever your CI already runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would do on a new API
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Run Schemathesis against staging first. Server errors and undocumented status codes are the cheapest bugs to find, and they do not need a test suite.&lt;/li&gt;
&lt;li&gt;Generate a file-based suite for the checks you want to keep and review. Read the assertions before you commit them. A generated test you do not understand is a liability.&lt;/li&gt;
&lt;li&gt;Reach for Postman when a human needs to click through the same requests, or when the team already shares collections there.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you already have a Postman collection and no tests in the repo, the reverse order works too. Import the collection somewhere that writes code, then keep the parts that still match your API.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest summary
&lt;/h2&gt;

&lt;p&gt;Schemathesis is a schema-aware fuzzer. Postman is a request workspace with a scripting layer. Both are good at what they do, and neither is a substitute for the other. Only one of them gives you a test file on disk. If that is the thing you actually need, say so when you are choosing tools, because neither tool will admit the gap for you.&lt;/p&gt;

&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://schemathesis.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;https://schemathesis.readthedocs.io/en/stable/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://schemathesis.readthedocs.io/en/stable/tutorials/pytest/" rel="noopener noreferrer"&gt;https://schemathesis.readthedocs.io/en/stable/tutorials/pytest/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learning.postman.com/docs/design-apis/specifications/import-a-specification" rel="noopener noreferrer"&gt;https://learning.postman.com/docs/design-apis/specifications/import-a-specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learning.postman.com/docs/tests-and-scripts/write-scripts/test-scripts/" rel="noopener noreferrer"&gt;https://learning.postman.com/docs/tests-and-scripts/write-scripts/test-scripts/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  If you want this done for you
&lt;/h2&gt;

&lt;p&gt;If you have an OpenAPI 3.x spec and want a runnable contract-test suite in 48 hours, that is $149. You send the spec, YAML or JSON, public URL or shared file. Within 48 hours of purchase you get runnable pytest, Jest or Newman test files, a README with run instructions, and the list of spec gaps I found while generating them. If I miss the 48 hours, you get a refund.&lt;/p&gt;

&lt;p&gt;Checkout: &lt;a href="https://itfabers.lemonsqueezy.com/checkout/buy/d1cbe20e-1358-466b-8af2-7cbfbff88636" rel="noopener noreferrer"&gt;https://itfabers.lemonsqueezy.com/checkout/buy/d1cbe20e-1358-466b-8af2-7cbfbff88636&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>testing</category>
      <category>schemathesis</category>
      <category>postman</category>
    </item>
    <item>
      <title>A status-200 check is not a contract test</title>
      <dc:creator>ITFabers</dc:creator>
      <pubDate>Mon, 09 Nov 2026 19:43:02 +0000</pubDate>
      <link>https://dev.to/itfabers/a-status-200-check-is-not-a-contract-test-3i9k</link>
      <guid>https://dev.to/itfabers/a-status-200-check-is-not-a-contract-test-3i9k</guid>
      <description>&lt;p&gt;A test that checks for HTTP 200 and stops there is not testing your API. It is testing that the server is awake.&lt;/p&gt;

&lt;p&gt;I have been building a small tool that turns OpenAPI specs into runnable test suites. The hard part was never generating the code. It was deciding what a generated test is allowed to assert.&lt;/p&gt;

&lt;p&gt;Here is the trap I keep running into in real public specs: every response is described as &lt;code&gt;type: object&lt;/code&gt;, with no properties and no required fields. A generator can write a test against that, watch it return 200, and call it a pass. The suite is green and the contract is untested.&lt;/p&gt;

&lt;p&gt;Two fixes, both in the spec:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Give response schemas real properties and required fields. If the body can be anything, nothing can fail.&lt;/li&gt;
&lt;li&gt;Document the error responses. When 400, 401 and 404 have no shapes, the negative tests have nothing to check.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A generated suite is a mirror of the spec. A vague spec produces vague tests. So before writing a single test, I read the spec for the holes. That step is boring and it is most of the value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a status code assertion is not enough
&lt;/h2&gt;

&lt;p&gt;A status code assertion passes on an empty body too. Adding a schema check on the response turns a lot of those green tests red, which is the point. If &lt;code&gt;required&lt;/code&gt; is missing, the generator has no reason to send the field, and the test proves less than it looks like it does.&lt;/p&gt;

&lt;p&gt;Two more things I check before generating anything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;401 versus 403. A missing token should be 401. A valid token without permission should be 403. APIs that return 401 for both hide authorization bugs until production.&lt;/li&gt;
&lt;li&gt;Pagination edges: last page, empty page, an expired cursor, a limit larger than the server allows. Cheap to test, expensive to find in production.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is novel. It is the work a fast generator will skip if you let it.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you want a suite built
&lt;/h2&gt;

&lt;p&gt;If you have an OpenAPI spec and want a runnable contract-test suite in 48 hours, that is what I do for $149. You send an OpenAPI 3.x file, YAML or JSON, public URL or shared file. You get runnable test files (pytest, Jest or Newman), a README with run instructions, and a short list of the spec gaps I found along the way. If I miss the 48 hours, you get a refund.&lt;/p&gt;

&lt;p&gt;Details and checkout: &lt;a href="https://itfabers.lemonsqueezy.com/checkout/buy/d1cbe20e-1358-466b-8af2-7cbfbff88636" rel="noopener noreferrer"&gt;https://itfabers.lemonsqueezy.com/checkout/buy/d1cbe20e-1358-466b-8af2-7cbfbff88636&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to check fit first, send the spec link in a comment.&lt;/p&gt;

&lt;p&gt;I am an independent developer in Yerevan. I am not going to pretend I have a wall of logos. This is the offer, and the spec-gap audit is the part I think is worth paying for.&lt;/p&gt;

</description>
      <category>api</category>
      <category>testing</category>
      <category>openapi</category>
    </item>
    <item>
      <title>Your API test suite is green and your contract is still untested</title>
      <dc:creator>ITFabers</dc:creator>
      <pubDate>Mon, 09 Nov 2026 19:17:35 +0000</pubDate>
      <link>https://dev.to/itfabers/your-api-test-suite-is-green-and-your-contract-is-still-untested-4317</link>
      <guid>https://dev.to/itfabers/your-api-test-suite-is-green-and-your-contract-is-still-untested-4317</guid>
      <description>&lt;p&gt;A test that checks for HTTP 200 and stops there is not testing your API. It is testing that the server is awake.&lt;/p&gt;

&lt;p&gt;I have been building a small tool that turns OpenAPI specs into runnable test suites. The hard part was never generating the code. It was deciding what a generated test is allowed to assert.&lt;/p&gt;

&lt;p&gt;Here is the trap I keep running into in real public specs: every response is described as &lt;code&gt;type: object&lt;/code&gt;, with no properties and no required fields. A generator can write a test against that, watch it return 200, and call it a pass. The suite is green and the contract is untested.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two fixes, both in the spec
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Give response schemas real properties and required fields. If the body can be anything, nothing can fail.&lt;/li&gt;
&lt;li&gt;Document the error responses. When 400, 401 and 404 have no shapes, the negative tests have nothing to check.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A generated suite is a mirror of the spec. A vague spec produces vague tests. So before writing a single test, I read the spec for the holes. That step is boring and it is most of the value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a status code assertion is not enough
&lt;/h2&gt;

&lt;p&gt;A status code assertion passes on an empty body too. Adding a schema check on the response turns a lot of those green tests red, which is the point. If &lt;code&gt;required&lt;/code&gt; is missing, the generator has no reason to send the field, and the test proves less than it looks like it does.&lt;/p&gt;

&lt;p&gt;Two more things I check before generating anything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;401 versus 403. A missing token should be 401. A valid token without permission should be 403. APIs that return 401 for both hide authorization bugs until production.&lt;/li&gt;
&lt;li&gt;Pagination edges: last page, empty page, an expired cursor, a limit larger than the server allows. Cheap to test, expensive to find in production.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is novel. It is the work a fast generator will skip if you let it.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you want a suite built
&lt;/h2&gt;

&lt;p&gt;If you have an OpenAPI spec and want a runnable contract-test suite in 48 hours, that is what I do for $149. You send an OpenAPI 3.x file, YAML or JSON, public URL or shared file. You get runnable test files (pytest, Jest or Newman), a README with run instructions, and a short list of the spec gaps I found along the way. If I miss the 48 hours, you get a refund.&lt;/p&gt;

&lt;p&gt;Details and checkout: &lt;a href="https://itfabers.lemonsqueezy.com/checkout/buy/d1cbe20e-1358-466b-8af2-7cbfbff88636" rel="noopener noreferrer"&gt;https://itfabers.lemonsqueezy.com/checkout/buy/d1cbe20e-1358-466b-8af2-7cbfbff88636&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to check fit first, send the spec link in a comment.&lt;/p&gt;




&lt;p&gt;I am an independent developer in Yerevan. I am not going to pretend I have a wall of logos. This is the offer, and the spec-gap audit is the part I think is worth paying for.&lt;/p&gt;

</description>
      <category>api</category>
      <category>testing</category>
      <category>openapi</category>
      <category>qa</category>
    </item>
  </channel>
</rss>
