{
    "componentChunkName": "component---src-templates-post-template-js",
    "path": "/en/announcing-strictland-contract-testing/",
    "result": {"data":{"post":{"id":"294eb683-a91d-5d4e-bf69-42a5ee7936f8","html":"<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; height: auto\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/7b5f1c6c933cf4162365268337a15b75/e67e7/2026-06-15-cover.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 58.50000000000001%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC50lEQVQozwHcAiP9AHJOH2ZEHrZ0LYBNJR0tMDU+PENJSDpFSFFAM7KIYt3Yv6Gdi0hJSFBSU0tNTkJGSUtNT19gYHh3c4KBfACDWzBzTSq2cyt/TSQnNDlLTk9UVlhBSEuaXTP93LX5++P/8tB4aVZBSEw+QUU5PkI3PEBWWVuLi4iZmJQAnGpFelA0r20ogU4lPENJVFZYUVRXRklHikch8c2i9vPV/OO8iWFDMzxCOT1CO0BEOj9DOD1BZWdnlJSPAGdSLIVYJsyCL3tKJDI6QD1BRDtCRjwzK2Y0GaaBXcGkg7aMZ6RmQFBTU0RHSTo/Qj1CRURHSXR0cYyLiABILSBeNR+3cSt6SSIgKzA4PT45QEYzLy5/SSmpdFC3j2vGk2iTbFBjZ2deX2BjZGWAf3xnZ2aKiYWGhIAAVCYbVh0TrmgndUghFyYuJS8yOj83OEI1eEUlsGc+rI1w3qdzZkghXVUxaFs2Y2JQd3h2gYN+hYaAZmpmAGQ1HlsiFaVfIWg5GjIvJUhDInFQKVhGMSsiEaNVLbSOar+SZ3BYL2JJF25UHWRWIUM5LzUoKEA0MVJAOQBXKyBfJxiVUCVmOR1DPhl0VSWeYjyZc1VFTDp4Ri1xRTR9UVBjUjddTRxXRR5PQBxWRB2RViCoYSOjXyMATzAkXyogazIpTTAiHygPclw72Kp/xpdyuZ9/TzAveEVEkGZjfWhQWkkZVEYePzcZSEAbbVwmzZQ87KdBAEUrIUoYEEwaEDwjFDEwFmhROdGddY9iRVc9GH1qR/blw///4r2tjldAFFpLIDQ2GUQ5GUM/G2RSJLl4OAA4ExRYIRJeIhJFLhRLSCd7VkJfIxpbRydNRhZ5Yzbp17f589jWxqlcRxtLRR4xMhkXJhY0NRhANxtfLycAOBQUWSESTCUTMzAWHSYUnGE6dFQ/NDkeSUIcW0oi0ryc/ffb39G0XkUfUUEbS0EfJy4aMjUdVEQcpFETL3L6edMR/oAAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"cover\"\n        title=\"cover\"\n        src=\"/static/7b5f1c6c933cf4162365268337a15b75/a331c/2026-06-15-cover.png\"\n        srcset=\"/static/7b5f1c6c933cf4162365268337a15b75/36ca5/2026-06-15-cover.png 200w,\n/static/7b5f1c6c933cf4162365268337a15b75/a3397/2026-06-15-cover.png 400w,\n/static/7b5f1c6c933cf4162365268337a15b75/a331c/2026-06-15-cover.png 800w,\n/static/7b5f1c6c933cf4162365268337a15b75/8537d/2026-06-15-cover.png 1200w,\n/static/7b5f1c6c933cf4162365268337a15b75/e67e7/2026-06-15-cover.png 1338w\"\n        sizes=\"(max-width: 800px) 100vw, 800px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p><strong>I just released something. It’s called Strictland.</strong> And it’s a contract testing library. Why did I do it?</p>\n<p>Before I go further, if you can’t wait, you can check it on:</p>\n<ul>\n<li>GitHub - <a href=\"https://github.com/event-driven-io/strictland\">https://github.com/event-driven-io/strictland</a></li>\n<li>Maven Central - <a href=\"https://central.sonatype.com/artifact/io.event-driven/strictland\">https://github.com/event-driven-io/strictland</a></li>\n</ul>\n<p><strong>So now you already know that it’s a JVM (Java, Scala, Kotlin, etc.) Open Source library.</strong></p>\n<p>Let me first show you a sneak peek. Stop for a moment and have a look on this:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Test</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">ensureOrderPlacedCompatibilityWithNewerVersion</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// Strictland specification</span>\n    <span class=\"token class-name\">MessageContract</span><span class=\"token punctuation\">.</span><span class=\"token function\">specification</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Json<span class=\"token punctuation\">.</span>Jackson</span><span class=\"token punctuation\">.</span><span class=\"token function\">of</span><span class=\"token punctuation\">(</span>yourObjectMapper<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">given</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">OrderPlaced</span><span class=\"token punctuation\">(</span>orderId<span class=\"token punctuation\">,</span> <span class=\"token string\">\"Alice\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">whenDeserializedAs</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">OrderPlacedWithCoupon</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">thenBackwardCompatible</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>What would you say if you saw such a test? Think about it, we’ll get back to it.</p>\n<h2 id=\"whats-strictland\" style=\"position:relative;\"><a href=\"#whats-strictland\" aria-label=\"whats strictland permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What’s Strictland?</h2>\n<p>But again, why did I do it if there are mature solutions like <a href=\"https://pact.io/\">Pact</a>, <a href=\"https://spring.io/projects/spring-cloud-contract\">Spring Cloud Contracts</a>, or <a href=\"https://github.com/confluentinc/schema-registry\">Confluent Schema Registry</a>?</p>\n<p>If you’ve used consumer-driven contract testing, the usual approach is to run both the provider and the consumer, record the consumer’s expectations against a mock, verify the provider against those expectations, and share those contracts through a broker.</p>\n<p>In Strictland, I took a smaller, simpler approach. It serialises the message in a standard unit test and saves the output as a snapshot file that you commit alongside your code.</p>\n<p>The test fails when the serialised shape changes, or when it contains a breaking change - up to you to specify expectations. A check confirms that an older and a newer version of the message can still read each other’s data (or the other way round).</p>\n<p><strong>Because it’s only serialisation and a file, the setup stays small:</strong></p>\n<ul>\n<li>The checks are ordinary unit tests in your existing suite, so there’s no broker, schema registry, or mock service to run, and nothing to start in Docker.</li>\n<li>The contract is the serialised JSON committed alongside the test, so any format change appears in a normal diff and is reviewed like any other code.</li>\n<li>You write the check beside the message it covers and get the answer in the same fast feedback loop as the rest of your tests. The check uses your application’s own serializer, so the snapshot is the exact bytes you ship.</li>\n<li>Strictland checks the serialised shape of a message and whether its versions stay compatible. It doesn’t exercise a live exchange between running services, so it complements that kind of tooling rather than replacing it.</li>\n</ul>\n<p><strong>Strictland checks the serialised shape of a message and whether its versions stay compatible.</strong> It doesn’t exercise a live exchange between running services, so it complements that kind of tooling rather than replacing it.</p>\n<p>It’s not as powerful as popular tooling, but it’s also much simpler to start catching our mistakes. Traditional solutions allow you to mock protocols, put a man in the middle, and even generate client code. All of that is great if you need it and have experience with it.</p>\n<p>Most of the <a href=\"https://event-driven.io/en/training/\">customers I’m helping through consultancy and training</a> aren’t there yet. Setting up those tools is a lot of heavy lifting for them and adds additional complexity. And well, maybe they don’t need to be, as this approach served me well in my past projects. I always handcrafted such a tool in my projects, but finally decided to make it properly.</p>\n<h2 id=\"why-such-a-name\" style=\"position:relative;\"><a href=\"#why-such-a-name\" aria-label=\"why such a name permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Why such a name?</h2>\n<p>I’m putting (too?) much effort into my projects’ names. It’s a word game. Contract testing rewards a strict approach to your message shapes, and <a href=\"https://backtothefuture.fandom.com/wiki/Stanford_S._Strickland\">Mr. Strickland</a> was strict enforcer in <em>Back to the Future</em>. That puts it in good company next to its sibling <a href=\"https://github.com/event-driven-io/emmett\">Emmett</a>, named after Doc Emmett Brown. I also didn’t want to collide with the older <a href=\"https://github.com/jeffhandley/strickland\">JS validation package</a>.</p>\n<h2 id=\"how-to-use-it\" style=\"position:relative;\"><a href=\"#how-to-use-it\" aria-label=\"how to use it permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to use it?</h2>\n<p>Getting back to the essence… How to use it?</p>\n<p><strong>You write a small unit test that locks down a message’s format.</strong> Later, you rename a field, change a type, or adjust how a value serialises; the code still compiles and your other tests pass, but that one fails and points at what changed. You fix it in your build before a consumer or a stored event has hit the old format in production.</p>\n<p>When a message changes by accident, a snapshot check shows you exactly what moved. When you evolve a message on purpose, a compatibility check confirms an old and a new version can still read each other’s data.</p>\n<p>You can start by installing it from Maven Central, by adding dependency.</p>\n<div class=\"gatsby-highlight\" data-language=\"xml\"><pre class=\"language-xml\"><code class=\"language-xml\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>dependency</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>groupId</span><span class=\"token punctuation\">></span></span>io.event-driven<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>groupId</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>artifactId</span><span class=\"token punctuation\">></span></span>strictland<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>artifactId</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>version</span><span class=\"token punctuation\">></span></span>0.3.0<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>version</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>scope</span><span class=\"token punctuation\">></span></span>test<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>scope</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>dependency</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>Then adding such test:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token class-name\">MessageContract</span><span class=\"token punctuation\">.</span><span class=\"token function\">specification</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Json<span class=\"token punctuation\">.</span>Jackson</span><span class=\"token punctuation\">.</span><span class=\"token function\">defaults</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">given</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">OrderPlaced</span><span class=\"token punctuation\">(</span>orderId<span class=\"token punctuation\">,</span> <span class=\"token string\">\"Alice\"</span><span class=\"token punctuation\">,</span> placedAt<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">whenSerialized</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">thenContractIsUnchanged</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The first run serializes the message and writes the result to an approved file named after the class, <code class=\"language-text\">OrderPlaced.approved.txt</code>, saved next to the test:</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token punctuation\">{</span><span class=\"token property\">\"orderId\"</span><span class=\"token operator\">:</span><span class=\"token string\">\"00000000-0000-0000-0000-000000000001\"</span><span class=\"token punctuation\">,</span><span class=\"token property\">\"customer\"</span><span class=\"token operator\">:</span><span class=\"token string\">\"Alice\"</span><span class=\"token punctuation\">,</span><span class=\"token property\">\"placedAt\"</span><span class=\"token operator\">:</span><span class=\"token string\">\"2024-01-01T12:00:00Z\"</span><span class=\"token punctuation\">}</span></code></pre></div>\n<p>You review that file and commit it. From then on the check compares against it and fails if the format drifts, so a later change to the format shows up in the same pull request as the code that caused it.</p>\n<p>A message under contract goes through one of two checks.</p>\n<p>A <strong>snapshot check</strong> confirms the message still serializes exactly as it did when you last approved it, so nothing reading it downstream breaks. A failure means the format changed: a field renamed, a date format switched, a value newly dropped or added.</p>\n<p>A <strong>compatibility check</strong> is for the version you evolve on purpose, so changing a message doesn’t leave the ones already in your store or on the wire stranded. Use <code class=\"language-text\">thenBackwardCompatible()</code> to confirm the newer version still reads a message the older one wrote, the events you stored last year, or a request already sent. Use <code class=\"language-text\">thenForwardCompatible()</code> to confirm a reader that hasn’t upgraded yet still reads a message the newer version writes, so you can ship the new shape before everyone reading it has caught up. Both compare the fields the two versions share and fail if a required one is missing or a shared value has changed.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Test</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">ensureOrderPlacedCompatibilityWithNewerVersion</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// Strictland specification</span>\n    <span class=\"token class-name\">MessageContract</span><span class=\"token punctuation\">.</span><span class=\"token function\">specification</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Json<span class=\"token punctuation\">.</span>Jackson</span><span class=\"token punctuation\">.</span><span class=\"token function\">of</span><span class=\"token punctuation\">(</span>yourObjectMapper<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">given</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">OrderPlaced</span><span class=\"token punctuation\">(</span>orderId<span class=\"token punctuation\">,</span> “<span class=\"token class-name\">Alice</span>”<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">whenDeserializedAs</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">OrderPlacedWithCoupon</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">thenBackwardCompatible</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>You review that file and commit it. From then on the check compares against it and fails if the format drifts, so a later change to the format shows up in the same pull request as the code that caused it.</p>\n<p>As you see, in the specification, you pass your serializer.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">var</span> spec <span class=\"token operator\">=</span> <span class=\"token class-name\">MessageContract</span><span class=\"token punctuation\">.</span><span class=\"token function\">specification</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Json<span class=\"token punctuation\">.</span>Jackson</span><span class=\"token punctuation\">.</span><span class=\"token function\">of</span><span class=\"token punctuation\">(</span>yourObjectMapper<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>I encourage you to use your application’s object mapper and pass the same <code class=\"language-text\">ObjectMapper</code> it uses, so the test checks the exact bytes you ship. That’ll help you avoid nasty surprises, where tests are using a different format than your framework or tooling.</p>\n<p>Strictland provides an implementation of a sensible Jackson setup: ISO-8601 dates, nulls kept, unknown properties ignored on read. You can use it with <code class=\"language-text\">Json.Jackson.defaults()</code>. But it’s more of an accessible thing to get you started quickly.</p>\n<p>You can also define your own serializer if you’re using an unsupported (yet?) format or serializer type. See basic examples in:</p>\n<ul>\n<li><a href=\"https://github.com/event-driven-io/strictland/blob/main/src/jvm/src/test/java/io/eventdriven/strictland/CsvMessageSerializer.java\">CsvMessageSerializer</a> and its <a href=\"https://github.com/event-driven-io/strictland/blob/main/src/jvm/src/test/java/io/eventdriven/strictland/CsvMessageSerializerTests.java\">tests</a> or,</li>\n<li><a href=\"https://github.com/event-driven-io/strictland/blob/main/src/jvm/src/test/java/io/eventdriven/strictland/SimpleBinaryMessageSerializer.java\">SimpleBinaryMessageSerializer</a> and its <a href=\"https://github.com/event-driven-io/strictland/blob/main/src/jvm/src/test/java/io/eventdriven/strictland/SimpleBinaryMessageSerializerTests.java\">tests</a>.</li>\n</ul>\n<h2 id=\"should-you-use-it\" style=\"position:relative;\"><a href=\"#should-you-use-it\" aria-label=\"should you use it permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Should you use it?</h2>\n<p><img src=\"/0a5d1001eec464f7501bcf275c1b73d5/2026-06-15-yes-you-do.gif\" alt=\"Yes, you do!\"></p>\n<p>Strictland is young and pre-1.0, so the API can still move between versions. The checks themselves are small and well covered, and the snapshots they produce are just files in your repository, so trying it out costs little and commits you to nothing.</p>\n<p>I’d genuinely like your feedback. If something is missing or awkward, tell me through comments, on <a href=\"https://discord.gg/fTpqUTMmVa\">Discord</a> or open an <a href=\"https://github.com/event-driven-io/strictland/issues/new\">issue</a>.</p>\n<p>Currently, I’m working on making snapshot location more organised and configurable, not to end up with a bloated snapshots tests folder.</p>\n<p>I also need to rethink the <em>given</em> name; it’s from Behaviour-Driven Design, but it appears to be a <a href=\"https://docs.scala-lang.org/scala3/reference/contextual/givens.html\">reserved word in Scala 3</a>. Cross-language and cross-stack libs are much fun!</p>\n<p>For now, for JVM, as the Java-based customers I’m helping also needed that, but soon want to add .NET and TypeScript/Javascript (and maybe more).</p>\n<p>Tell me your honest thoughts, give it a try and a star if you liked it. Play with it, and pass me your feedback. It’ll motivate me to continue working on it!</p>\n<p><strong>Would you like to learn more about consumer-driven tests and how Strictland can be used for them?</strong></p>\n<p><strong>And read in the event versioning series:</strong></p>\n<ul>\n<li><a href=\"/en/simple_events_versioning_patterns/\">Simple patterns for events schema versioning</a></li>\n<li><a href=\"/en/explicit_events_serialisation_in_event_sourcing/\">Explicit events serialisation in Event Sourcing</a></li>\n<li><a href=\"/en/fun_with_json_serialisation/\">Fun with serial JSON</a></li>\n<li><a href=\"/en/how_to_map_event_type_by_convention/\">Mapping event type by convention</a></li>\n<li><a href=\"/en/event_versioning_with_marten/\">Event Versioning with Marten</a></li>\n<li><a href=\"/en/lets_take_care_of_ourselves_thoughts_about_comptibility/\">Let’s take care of ourselves! Thoughts on compatibility</a></li>\n<li><a href=\"/en/internal_external_events/\">Internal and external events, or how to design event-driven API</a></li>\n</ul>\n<p>Cheers!</p>\n<p>Oskar</p>\n<p>p.s. <strong>Ukraine is still under brutal Russian invasion. A lot of Ukrainian people are hurt, without shelter and need help.</strong> You can help in various ways, for instance, directly helping refugees, spreading awareness, putting pressure on your local government or companies. You can also support Ukraine by donating e.g. to <a href=\"https://www.icrc.org/en/donate/ukraine\">Red Cross</a>, <a href=\"https://savelife.in.ua/en/donate/\">Ukraine humanitarian organisation</a> or <a href=\"https://www.gofundme.com/f/help-to-save-the-lives-of-civilians-in-a-war-zone\">donate Ambulances for Ukraine</a>.</p>","excerpt":"I just released something. It’s called Strictland. And it’s a contract testing library. Why did I do it? Before I go further, if you can’t…","fields":{"slug":"/announcing-strictland-contract-testing/","prefix":"2026-06-15","langKey":"en"},"frontmatter":{"title":"Announcing Strictland - new contract testing library for message compatibility","author":"oskar dudycz","category":"Testing","disqusId":null,"useDefaultLangCanonical":null,"cover":{"childImageSharp":{"resize":{"src":"/static/7b5f1c6c933cf4162365268337a15b75/2a4de/2026-06-15-cover.png"}}}}},"authornote":{"id":"f1fb8a26-256d-5b24-9b06-ad19a0c2961b","html":"<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; height: auto\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/f748655e118b2b9d5ce6b7dd6f9f4f85/d2429/2021-10-13-cover.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 55.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAA6cAAAOnAEHlFPdAAAChUlEQVQozyXOTU/acBwA4J+FFmgp/5RCX2AlFVgUgxTCYZNA6KZMooPSiAoaZ8bLjTmEbALRePAygyaLBEl0lyWePGji1YsnT8YDBxMTE+9+iiXu+QQPPDw8nJ2dtVqtZrNZr9cbjUYul8tkMvl8vt1un5yc3Nzc3N7eDofDu7u74+Pj+/v7x8fH6+vr8/NzGA6HOzs73W53f3+/0+mUSqVisbi3t3d0dNTv9w8PDy8uLnq93sHBQblcrtfrp6enl5eXrVarUqnA8/OzruvLy8uDwUDTtJmZmWw22+12Nzc3q9VqKpUqFovT09OFQsHr9SaTyZWVlVgspmlaoVCAl5cXRVE4jotGowghiqJIkpybm/N4PAsLCwghRVF0Xff5fHa7HQDi8Xg6nQaASCQCT09PwWAQXrEsa7VaZVlOp9NjY2Nut1uWZYIgWJYVRZEkSYZhLBaL0WgkCCIUCkGv1xMEAcMwo9EIABRFEQQhSVI0GhUEwWAw0DQ9OjqK4zhFUQzD2O12HMc5jhMEAa6urmRZRgglEgmHwzEyMuJyuXZ3d2u12tTUFAAQBOF0Onmep2mae2V6heM4bG1tIYR4nk8kEqIoAkAgEOh0OvF4XJIkADCZTDzPu1wuk8lks9kQQhiGmc1mkiTB65U5zun3+xFCPp+P5znaRquqGg6HcdyIYRiO4+VyeWlp6f+CpmmDwWAxm0VRAFX9kM3mVlfXJidDPv/bN24pHI4kkyrDMCRJjo8HJMnz6dNsq9W2WmmzhWRZB2W1BSaCmqbDxrfK9naj/r2az2fWvxTfvY98La2pakxRJuY/zy4u5jLZtPox/uPnxvp6YTalLurz7WZt8PvX3z/9f7APp/oT02NdAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"cover\"\n        title=\"cover\"\n        src=\"/static/f748655e118b2b9d5ce6b7dd6f9f4f85/a331c/2021-10-13-cover.png\"\n        srcset=\"/static/f748655e118b2b9d5ce6b7dd6f9f4f85/36ca5/2021-10-13-cover.png 200w,\n/static/f748655e118b2b9d5ce6b7dd6f9f4f85/a3397/2021-10-13-cover.png 400w,\n/static/f748655e118b2b9d5ce6b7dd6f9f4f85/a331c/2021-10-13-cover.png 800w,\n/static/f748655e118b2b9d5ce6b7dd6f9f4f85/d2429/2021-10-13-cover.png 805w\"\n        sizes=\"(max-width: 800px) 100vw, 800px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>Through my window, I see the result of good plans but poor execution. Opposite my flat, there is a partially completed construction place. Buildings were supposed to be eye-catching Mediterranean style apartments.  Delivery date? Two years ago. Actual? More and more unknown.</p>\n<p>Some time ago, I heard that using Event Sourcing makes creating Event-Driven Architecture easier. The arguments were correct, that if we’re already publishing events to trigger business workflows, then at some point, we may want to also store events to not lose information. Agreed. However, I also heard that keeping the state as events will simplify things. We’ll have a source of truth with a record of the system behaviour. This will allow, e.g. to confront the results of the operations with the recorded state. I’d agree with that, with one distinction. It’s easier as long as you already know Event Sourcing.</p>\n<p>Many people in the DDD community claim that the essential is to properly break down the system into autonomous parts called bounded contexts. Once we have it, the rest is secondary and will sort itself out. For sure.</p>\n<p>Many seasoned programmers speak similarly about new technologies. They claim that they can translate past experience into new technologies. That’s true that by analogy, they can catch the big picture quicker. But isn’t it a bold assumption to say that Win.Forms specialist will learn Angular quickly?</p>\n<p>The end result may differ a lot from the initial ideas. I saw the plan of those buildings next to me. Now I can see the effects of the execution. Or actually, the lack.</p>\n<p>I believe that we should carefully acknowledge not only the point of view of our authorities but also their seating point. If we want to find out how to form a wall, do we ask an architect or a foreman? An architect may know the theory, but the practice is what we’re looking for. On the other hand, if you want to know where to put the wall, you prefer the architect to do measurements. At least if you don’t want to have the roof falling to your head.</p>\n<p>After I had torn a ligament in my knee, I went to two qualified orthopedists. One said I should have surgery and do a reconstruction. The second stated that there is no need for that; rehabilitation should be enough. Guess which one had a specialization in surgery and which in rehabilitation?</p>\n<p>People usually give us advice from the point where they’re currently standing. They are entitled to a biased view. An architect who rarely does programming will tend to downplay the value of implementation and tactical patterns. Midlevel developers will focus on technicalities instead of the global system impact. The team manager or consultant will emphasize the importance of soft skills (or esoteric techniques known only to them).</p>\n<p>The truth is that we need all of them. The excellent plan will fall on the bad execution. The best execution for the wrong case will be just a waste of time. We should carefully evaluate the advice considering what we need and what an expert can give us.</p>\n<p>Therefore, when we’re reading an article, watching a talk, let’s also pay attention to the place where the person is standing. The perspective from there may be much different from where we are right now. That can be good, as it may push us in the right direction. But it may also be misleading, as we accidentally take biases of this person without understanding the tradeoffs. Personally, I prefer to follow not only people from pedestal but also those that are closer to my position. A bit further in the journey, but not too far. That helps me to calibrate my view as those people are more relative to my daily struggles.</p>\n<p>Polish historical leader <a href=\"https://en.wikipedia.org/wiki/J%C3%B3zef_Pi%C5%82sudski\">Józef Piłsudzki</a> reportedly used to say: <em>“Right is like an ass, everyone has its own”</em>.</p>\n<p>Cheers!</p>\n<p>Oskar</p>"},"site":{"siteMetadata":{"facebook":{"appId":""}}}},"pageContext":{"slug":"/announcing-strictland-contract-testing/","lang":"en","langKey":"en","prev":{"id":"4c1b5e1d-76dc-5ae5-b1ee-4f1081f10063","fields":{"slug":"/you-can-fork-a-package-but-can-you-own-it/","prefix":"2026-06-08","source":"posts","langKey":"en"},"frontmatter":{"title":"You can fork a package, but can you own it?","category":"Software Architecture"}},"source":"posts"}},
    "staticQueryHashes": ["2742854296"]}