<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Invariants on Ocarina — manual</title>
    <link>https://mojo-molotov.github.io/from-ocarina-to-igor/tags/invariants/</link>
    <description>Recent content in Invariants on Ocarina — manual</description>
    <generator>Hugo</generator>
    <language>en-US</language>
    <lastBuildDate>Thu, 28 May 2026 21:02:53 +0200</lastBuildDate>
    <atom:link href="https://mojo-molotov.github.io/from-ocarina-to-igor/tags/invariants/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Chapter 02.04 — Invariants</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/</guid>
      <description>&lt;h1 id=&#34;chapter-0204invariants&#34;&gt;Chapter 02.04 — Invariants&lt;a class=&#34;anchor&#34; href=&#34;#chapter-0204invariants&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;Ocarina&amp;rsquo;s sub-DSL for typed, composable invariants. Used everywhere: CLI, POMs, the &lt;code&gt;custom_invariants/testing/&lt;/code&gt; that check suite consistency before any test runs.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;plan&#34;&gt;Plan&lt;a class=&#34;anchor&#34; href=&#34;#plan&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th style=&#34;text-align: center&#34;&gt;#&lt;/th&gt;&#xA;          &lt;th&gt;File&lt;/th&gt;&#xA;          &lt;th&gt;Subject&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;01&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/01-validate-flow/&#34;&gt;&lt;code&gt;01-validate-flow.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;The full flow &lt;code&gt;validate(value) → assert_that → execute → raise_if_invalid&lt;/code&gt; + the &lt;code&gt;_ValidationChain&lt;/code&gt; class.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;02&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/02-assertions/&#34;&gt;&lt;code&gt;02-assertions.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Catalog of builtin assertions (&lt;code&gt;is_str&lt;/code&gt;, &lt;code&gt;is_email&lt;/code&gt;, &lt;code&gt;is_positive&lt;/code&gt;, &lt;code&gt;is_in&lt;/code&gt;, &lt;code&gt;has_unique_elements&lt;/code&gt;, &lt;code&gt;each&lt;/code&gt;, &lt;code&gt;is_valid_filename&lt;/code&gt;, …).&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;03&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/03-otherwise-any-of/&#34;&gt;&lt;code&gt;03-otherwise-any-of.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;.otherwise(...)&lt;/code&gt; and the OR combination via &lt;code&gt;_any_of&lt;/code&gt;.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;04&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/04-then-chain-of-validations/&#34;&gt;&lt;code&gt;04-then-chain-of-validations.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;.then(new_value)&lt;/code&gt; and &lt;code&gt;chain_validations(...)&lt;/code&gt; for composition.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;05&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/05-business-vs-framework-validator/&#34;&gt;&lt;code&gt;05-business-vs-framework-validator.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;BusinessInvariantValidator&lt;/code&gt; vs &lt;code&gt;FrameworkInvariantValidator&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;06&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/06-invariant-errors/&#34;&gt;&lt;code&gt;06-invariant-errors.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;InvariantViolationError&lt;/code&gt;, &lt;code&gt;DuplicatesError&lt;/code&gt;, &lt;code&gt;AggregateInvariantViolationError&lt;/code&gt;.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;why-the-invariants-dsl&#34;&gt;Why the invariants DSL&lt;a class=&#34;anchor&#34; href=&#34;#why-the-invariants-dsl&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;Pre-execution guard.&lt;/strong&gt; &lt;code&gt;TestSuite.__init__&lt;/code&gt; checks — &lt;em&gt;before&lt;/em&gt; launching anything — that test names / IDs are unique, &lt;code&gt;max_workers &amp;gt;= 1&lt;/code&gt;, etc.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;CLI validation.&lt;/strong&gt; Every flag carries its &lt;code&gt;validate=lambda chain: chain.assert_that(...)&lt;/code&gt; inside the &lt;code&gt;CliStore&lt;/code&gt;. Errors aggregate into one message.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;POM-side validation.&lt;/strong&gt; POM actions validate their parameters (&amp;quot;&lt;code&gt;retries&lt;/code&gt; must be positive&amp;quot;) via &lt;code&gt;validate(retries, name=&amp;quot;retries&amp;quot;).assert_that(is_positive).execute().raise_if_invalid()&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;The Holy Book sums it up:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Chapter 02.05 — Orchestration</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/05-orchestration/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/05-orchestration/</guid>
      <description>&lt;h1 id=&#34;chapter-0205orchestration&#34;&gt;Chapter 02.05 — Orchestration&lt;a class=&#34;anchor&#34; href=&#34;#chapter-0205orchestration&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;&lt;code&gt;Test → TestSuite → TestCampaign → TestCycle&lt;/code&gt;: how each level slots into the next, who owns parallelization, who owns retries, who decides skipping, and where the pre-execution invariants live.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;plan&#34;&gt;Plan&lt;a class=&#34;anchor&#34; href=&#34;#plan&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th style=&#34;text-align: center&#34;&gt;#&lt;/th&gt;&#xA;          &lt;th&gt;File&lt;/th&gt;&#xA;          &lt;th&gt;Subject&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;01&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/05-orchestration/01-test/&#34;&gt;&lt;code&gt;01-test.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;The &lt;code&gt;Test[Driver]&lt;/code&gt; class — &lt;code&gt;spawn&lt;/code&gt;, pre/post fragments, skip.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;02&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/05-orchestration/02-test-executor/&#34;&gt;&lt;code&gt;02-test-executor.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;TestExecutor&lt;/code&gt; — execution of &lt;strong&gt;one&lt;/strong&gt; attempt, order: setup → watchers.start → chain → watchers.stop → teardown.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;03&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/05-orchestration/03-test-flow-retries/&#34;&gt;&lt;code&gt;03-test-flow-retries.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;TestFlow&lt;/code&gt; — retry loop (1 + max_retries), linear backoff, setup-failure handling.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;04&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/05-orchestration/04-test-suite/&#34;&gt;&lt;code&gt;04-test-suite.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;TestSuite&lt;/code&gt; — parallelization with &lt;code&gt;ThreadPoolExecutor&lt;/code&gt;, ID filtering, guardrails.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;05&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/05-orchestration/05-saturation/&#34;&gt;&lt;code&gt;05-saturation.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Worker saturation: random cloning &lt;code&gt;[COPY N]&lt;/code&gt;. Why and how.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;06&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/05-orchestration/06-test-campaign/&#34;&gt;&lt;code&gt;06-test-campaign.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;TestCampaign&lt;/code&gt; — sequence of suites, &lt;code&gt;campaign_has_failed&lt;/code&gt;.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;07&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/05-orchestration/07-test-cycle-modes/&#34;&gt;&lt;code&gt;07-test-cycle-modes.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;TestCycle&lt;/code&gt; — smoke + main, &lt;code&gt;fail-fast&lt;/code&gt; vs &lt;code&gt;wait-for-all&lt;/code&gt; modes, &lt;code&gt;has_test_cycle_failed&lt;/code&gt;.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;08&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/05-orchestration/08-filter-tests-by-ids/&#34;&gt;&lt;code&gt;08-filter-tests-by-ids.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;filter_tests_by_ids&lt;/code&gt; — &lt;code&gt;--only&lt;/code&gt;/&lt;code&gt;--exclude&lt;/code&gt;, mutex, ignores unknown IDs.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;diagram&#34;&gt;Diagram&lt;a class=&#34;anchor&#34; href=&#34;#diagram&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;            ┌────────────────────────────────────────────────┐&#xA;            │                  TestCycle                     │&#xA;            │                                                │&#xA;            │  ┌──────────────────────────────────────────┐  │&#xA;            │  │ smoke_tests_campaigns                    │  │ ◄── first, gate&#xA;            │  │  └─ TestCampaign                         │  │     mode: fail-fast |&#xA;            │  │      └─ TestSuite                        │  │           wait-for-all&#xA;            │  │          └─ Test                         │  │&#xA;            │  └──────────────────────────────────────────┘  │&#xA;            │                                                │&#xA;            │  ┌──────────────────────────────────────────┐  │&#xA;            │  │ campaigns (main)                         │  │ ◄── skipped if a&#xA;            │  │  └─ TestCampaign                         │  │     smoke fails&#xA;            │  │      └─ TestSuite                        │  │&#xA;            │  │          └─ Test                         │  │&#xA;            │  └──────────────────────────────────────────┘  │&#xA;            └────────────────────────────────────────────────┘&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;who-does-what&#34;&gt;Who does what?&lt;a class=&#34;anchor&#34; href=&#34;#who-does-what&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Level&lt;/th&gt;&#xA;          &lt;th&gt;Single responsibility&lt;/th&gt;&#xA;          &lt;th&gt;Concurrency&lt;/th&gt;&#xA;          &lt;th&gt;Out of scope&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Test&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Metadata + &lt;code&gt;spawn(driver, logger)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;none&lt;/td&gt;&#xA;          &lt;td&gt;execution&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;TestExecutor&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;One &lt;strong&gt;attempt&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;none&lt;/td&gt;&#xA;          &lt;td&gt;retries, driver acquisition&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;TestFlow&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Retry&lt;/strong&gt; loop&lt;/td&gt;&#xA;          &lt;td&gt;none&lt;/td&gt;&#xA;          &lt;td&gt;parallelization, aggregation&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;TestSuite&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Parallelization + saturation + ID filtering&lt;/td&gt;&#xA;          &lt;td&gt;&lt;strong&gt;N threads&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;inter-suite sequence&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;TestCampaign&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Sequence of suites&lt;/td&gt;&#xA;          &lt;td&gt;suite-level&lt;/td&gt;&#xA;          &lt;td&gt;smoke vs main&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;TestCycle&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Smoke + main + mode&lt;/td&gt;&#xA;          &lt;td&gt;campaign-level&lt;/td&gt;&#xA;          &lt;td&gt;bootstrap / post-exec plugins&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;The strict separation is &lt;strong&gt;deliberate&lt;/strong&gt;. &lt;code&gt;TestExecutor&lt;/code&gt; knows nothing about retries. &lt;code&gt;TestFlow&lt;/code&gt; knows nothing about concurrency. &lt;code&gt;TestSuite&lt;/code&gt; knows nothing about campaign-level aggregation. One axis of responsibility per class.&lt;/p&gt;</description>
    </item>
    <item>
      <title>04.06 — Property-based testing (hypothesis)</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/04-internal-tests/06-hypothesis-properties/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/04-internal-tests/06-hypothesis-properties/</guid>
      <description>&lt;h1 id=&#34;0406property-based-testing-hypothesis&#34;&gt;04.06 — Property-based testing (&lt;code&gt;hypothesis&lt;/code&gt;)&lt;a class=&#34;anchor&#34; href=&#34;#0406property-based-testing-hypothesis&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;A single file (&lt;code&gt;test_invariants_properties.py&lt;/code&gt;), but the pattern is interesting: we &lt;strong&gt;generate&lt;/strong&gt; inputs and verify &lt;strong&gt;universal properties&lt;/strong&gt; of the invariant predicates.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;the-concept&#34;&gt;The concept&lt;a class=&#34;anchor&#34; href=&#34;#the-concept&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;hypothesis&lt;/code&gt; auto-generates &lt;em&gt;test cases&lt;/em&gt; that satisfy given constraints, then checks a property holds for every generated case. On failure, &lt;em&gt;hypothesis&lt;/em&gt; does &lt;strong&gt;shrinking&lt;/strong&gt; to find the &lt;strong&gt;smallest counter-example&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;from&lt;/span&gt; hypothesis &lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; given, strategies &lt;span style=&#34;color:#ff79c6&#34;&gt;as&lt;/span&gt; st&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@given(st&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;integers())&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;test_is_positive_passes_on_positive&lt;/span&gt;(value):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; value &lt;span style=&#34;color:#ff79c6&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        is_positive(value)             &lt;span style=&#34;color:#6272a4&#34;&gt;# must not raise&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ff79c6&#34;&gt;with&lt;/span&gt; pytest&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;raises(InvariantViolationError):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            is_positive(value)         &lt;span style=&#34;color:#6272a4&#34;&gt;# must raise&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;→ &lt;code&gt;hypothesis&lt;/code&gt; generates integers (typically 100 by default), checks the property on each. &lt;em&gt;Unexpected&lt;/em&gt; exception → fail. The shrinker finds the smallest failing case (&lt;code&gt;0&lt;/code&gt;? &lt;code&gt;-1&lt;/code&gt;? &lt;code&gt;MIN_INT&lt;/code&gt;?).&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
