<?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: Mesut Yakut</title>
    <description>The latest articles on DEV Community by Mesut Yakut (@mstykt).</description>
    <link>https://dev.to/mstykt</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3658787%2F22b7ac18-e094-439a-adb3-616290e23126.jpeg</url>
      <title>DEV Community: Mesut Yakut</title>
      <link>https://dev.to/mstykt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mstykt"/>
    <language>en</language>
    <item>
      <title>Atrahasis CLI</title>
      <dc:creator>Mesut Yakut</dc:creator>
      <pubDate>Wed, 20 May 2026 23:19:05 +0000</pubDate>
      <link>https://dev.to/mstykt/atrahasis-cli-3k2e</link>
      <guid>https://dev.to/mstykt/atrahasis-cli-3k2e</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjffk57nkv3uv1bjlqt5x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjffk57nkv3uv1bjlqt5x.png" alt=" " width="799" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Atrahasis CLI - atra&lt;/strong&gt;&lt;br&gt;
atra is the official command-line interface of Atrahasis a modern API workspace that covers everything from a single HTTP request to multi-step flow tests and full load benchmarks. The desktop app gives you the full visual experience; atra is what you reach for when your hands are already on the keyboard.&lt;br&gt;
It's built in Rust and shipped as a single static binary. No runtime, no dependencies, no setup ceremony - install once, run anywhere.&lt;/p&gt;
&lt;h2&gt;
  
  
  The problems atra is built to solve
&lt;/h2&gt;

&lt;p&gt;Working with APIs from the terminal has always felt like assembling a toolkit by hand. You need one thing for ad-hoc requests, another to chain them, another to put them under load, and a fourth to make any of it run in CI. Each piece comes with its own config format, its own scripting model, and its own gaps.&lt;/p&gt;

&lt;p&gt;Atrahasis CLI was built to flatten all of that into a single, coherent tool:&lt;br&gt;
&lt;strong&gt;Opaque latency:&lt;/strong&gt; "It was slow" tells you nothing. atra breaks every request into DNS, TCP, TLS, server response, and download phases so you see exactly where the time went.&lt;br&gt;
Assertions as an afterthought: Most CLIs hand you a body and a status code and leave the verification to you. atra has assertions built in for status, headers, body, JSON path, and response time with proper exit codes so they drop straight into CI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-step API testing:&lt;/strong&gt; Real workflows are "log in → create → verify → clean up." atra runs them as flows with shared state, variable extraction, and a live terminal dashboard that shows you each iteration as it happens.&lt;br&gt;
Load testing in a separate world: Stress and spike testing usually means learning yet another tool. atra runs the same step definitions as load tests, with full percentile metrics in your terminal - no second toolchain to maintain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modern protocols:&lt;/strong&gt; HTTP/3 is the present, not the future. atra speaks HTTP/1.1, HTTP/2, and HTTP/3 (QUIC) natively, with automatic protocol negotiation.&lt;/p&gt;

&lt;p&gt;One-Line Install&lt;br&gt;
Pick your channel, Atrahasis CLI ships natively for macOS, Linux, and Windows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Homebrew (macOS)
brew install atrahasisdev/tap/atra

# npm
npm install -g @atrahasis/cli

# curl (macOS/Linux)
curl -sSL https://cli.atrahasis.dev | sh

# wget
wget -qO- https://cli.atrahasis.dev | sh

# PowerShell (Windows)
irm https://cli.atrahasis.dev | iex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No Node, no Python, no Docker required at runtime. Every install method drops a native binary on your &lt;code&gt;PATH&lt;/code&gt;. &lt;code&gt;atra - version&lt;/code&gt; and you're done.&lt;br&gt;
There's also a built-in self-updater:&lt;br&gt;
&lt;code&gt;atra update&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Familiar Syntax, curl-Compatible Flags
&lt;/h2&gt;

&lt;p&gt;If you know curl, you already know most of atra. Headers, methods, body data, basic auth, follow redirects, cookies the flags map straight across:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;atra https://api.example.com/users \
  -H "Authorization: Bearer my-token" \
  -d '{"name": "Alice"}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But atra also adds triple-mode syntax, so the same request can be expressed as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Shorthand - auto-detects JSON, sets Content-Type
atra POST https://api.example.com/users name:Alice age:30

# Or fully explicit
atra POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name": "Alice", "age": 30}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Where Did the Time Go? Request Tracing
&lt;/h2&gt;

&lt;p&gt;Most HTTP clients tell you the response time. atra tells you where it was spent.&lt;br&gt;
Add &lt;code&gt;-t&lt;/code&gt; (or &lt;code&gt;--trace&lt;/code&gt;) to any request, and you get a connection waterfall directly in the terminal:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjffk57nkv3uv1bjlqt5x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjffk57nkv3uv1bjlqt5x.png" alt=" " width="799" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You see DNS, TCP, TLS, request send, server response, and download phases broken out individually. That 600ms latency you've been hunting? It's right, there was it the TLS handshake, the upstream's slow first byte, or the download itself?&lt;br&gt;
No flame graphs, no packet capture, no extra tooling. One flag, full visibility.&lt;/p&gt;
&lt;h2&gt;
  
  
  Assertions That Speak CI/CD
&lt;/h2&gt;

&lt;p&gt;Atrahasis CLI has first-class assertion support built-in, with no extra parser or wrapper script. Each assertion exits with code 1 on failure, which means atra slides into any CI pipeline as easily as curl did, but actually tells you whether your API is healthy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;atra GET https://api.example.com/users \
  -a "status eq 200" \
  -a "$.age eq 30" \
  -a "body contains Alice" \
  -a "header content-type contains xml" \
  -a "response_time lt 10"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa8yomwkd798ysu1h9qou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa8yomwkd798ysu1h9qou.png" alt=" " width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You assert against:&lt;br&gt;
Status codes&lt;br&gt;
JSONPath values as (&lt;code&gt;$.age equals 30&lt;/code&gt;)&lt;br&gt;
Body contents&lt;br&gt;
Headers&lt;br&gt;
Response time thresholds&lt;/p&gt;

&lt;p&gt;In a GitHub Actions step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Smoke test
  run: |
    curl -sSL https://cli.atrahasis.dev | sh
    atra GET https://api.example.com/health \
      -a "status eq 200" \
      -a "response_time lt 500"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or skip the install entirely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Smoke test
  run: npx --yes @atrahasis/cli GET https://api.example.com/health -a "status eq 200"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Flow Runner - Multi-Step API Tests with Live Dashboards
&lt;/h2&gt;

&lt;p&gt;Real-world API testing isn't a single request. It's "log in, then create an order, then fetch it back, then verify the state changed."&lt;br&gt;
That's what the &lt;strong&gt;flow runner&lt;/strong&gt; is for. You describe a multi-step flow in JSON, atra runs it with shared state, pre/post scripts, variable extraction between steps, and real-time terminal UI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;atra run api-tests -f bulk-create-orders -i 4

OR

atra run api-tests -f bulk-create-orders -p 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Furlvr36wap3fmlz8vxnc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Furlvr36wap3fmlz8vxnc.png" alt=" " width="800" height="802"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you get in the terminal:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live response-time chart&lt;/strong&gt; per step, per iteration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Throughput&lt;/strong&gt; and &lt;strong&gt;success rate&lt;/strong&gt; summaries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anomaly detection&lt;/strong&gt; atra highlights when a particular iteration is significantly slower or faster than the average for that step&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step-by-step results&lt;/strong&gt; with HTTP status, latency, and asserted outcomes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Flow variables ({{flow.userId}}), environment variables ({{base_url}}), and random generators ({{random.email}}), ({{random.uuid}}) are first-class. Chain a login response into the next request without writing a single line of glue code.&lt;/p&gt;

&lt;p&gt;And because exit codes propagate, the same flow can run as a smoke test in CI, as a release gate, or as a local sanity check. One artifact, three jobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Load Testing in the Terminal
&lt;/h2&gt;

&lt;p&gt;The same step definitions that drive your flow tests can drive a load test. No second toolchain, no second scripting language, no second mental model just run the same spec with a load profile:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;atra run spec-group -s create-order -t stress&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjiwow49nm7ko64mpv687.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjiwow49nm7ko64mpv687.png" alt=" " width="800" height="804"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Profiles included out of the box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| Type   | Virtual Users | Ramp  | Duration |
|--------|---------------|-------|----------|
| load   | 50            | 30s   | 60s      |
| stress | 200           | 10s   | 60s      |
| spike  | 300           | 2s    | 30s      |
| soak   | 30            | 30s   | 5min     |
| custom | yours         | yours | yours    |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Live terminal dashboard shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Avg, p50, p90, p95, p99&lt;/strong&gt; response times, updated every second&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Throughput&lt;/strong&gt; (requests/second) over time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error rate&lt;/strong&gt; chart&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active virtual users&lt;/strong&gt; ramp&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-step breakdown&lt;/strong&gt; with full percentile distribution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reports can be exported to &lt;strong&gt;HTML&lt;/strong&gt;, &lt;strong&gt;PDF&lt;/strong&gt;, or &lt;strong&gt;OpenTelemetry JSON&lt;/strong&gt; for handoff to dashboards downstream.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP/3, Natively
&lt;/h2&gt;

&lt;p&gt;Most CLIs added HTTP/3 as an afterthought, requiring custom builds or feature flags. atra ships with HTTP/3 (QUIC) support compiled in. Force any protocol or let atra negotiate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;atra GET https://api.example.com --http3
atra GET https://api.example.com --http2
atra GET https://api.example.com --http1.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Connection pooling and protocol negotiation happen automatically, so when you don't force a protocol, atra picks the best available and reuses connections across redirects and flow steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Real-World Walkthrough
&lt;/h2&gt;

&lt;p&gt;Imagine you've just shipped a new endpoint and want to validate it end-to-end before flipping the feature flag. With atra, that's three commands you can put in a single script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 1. Smoke test the new endpoint
atra GET https://api.example.com/v2/orders \
  -B my-token \
  -a "status eq 200" \
  -a "$.data is_type array"

# 2. Run the integration flow (login → create → fetch → cancel)
atra run flows -f order-lifecycle -e staging

# 3. Apply 30 seconds of load to see if it holds under traffic
atra run specs -s order-create -t spike -e staging
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If any step fails - assertion mismatch, flow step error, threshold breach the exit code propagates, your CI fails, and you have a colorful terminal report explaining exactly what went wrong. No tab-switching, no copy-paste from different tools, no "wait, what was the curl command again?"&lt;/p&gt;

&lt;p&gt;That same script works on your laptop, in GitHub Actions, in GitLab CI, in a Kubernetes Job, or on a Raspberry Pi running Linux. Single binary. Zero runtime. Same output everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Bother?
&lt;/h2&gt;

&lt;p&gt;Because tooling fragmentation is a tax we've been paying for too long. Every new tool means a new config format, a new install dance, a new way to ask the same three questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Did the request succeed?&lt;/li&gt;
&lt;li&gt;Did it return the right thing?&lt;/li&gt;
&lt;li&gt;Did it return in time?
atra makes those three questions one command, with rich output, on every OS, in every CI.
Ad-hoc requests, multi-step flows, load tests - same binary, same syntax, same dashboards. That's the whole pitch.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g @atrahasis/cli
atra https://api.example.com -a "status eq 200" -t
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;curl:&lt;/strong&gt; &lt;code&gt;curl -sSL https://cli.atrahasis.dev | sh &lt;/code&gt;&lt;br&gt;
&lt;strong&gt;wget:&lt;/strong&gt; &lt;code&gt;wget -qO- https://cli.atrahasis.dev | sh&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;code&gt;npm install -g @atrahasis/cli&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;homebrew:&lt;/strong&gt; &lt;code&gt;brew install atrahasisdev/tap/atra&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;powershell:&lt;/strong&gt; &lt;code&gt;irm https://cli.atrahasis.dev | iex&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Platform: &lt;a href="https://atrahasis.dev" rel="noopener noreferrer"&gt;Atrahasis&lt;/a&gt;&lt;br&gt;
Desktop App: &lt;a href="https://atrahasis.dev" rel="noopener noreferrer"&gt;Api Client&lt;/a&gt;&lt;br&gt;
CLI Documentation: &lt;a href="https://atrahasis.dev/cli" rel="noopener noreferrer"&gt;Atra CLI&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cli</category>
      <category>apiclient</category>
      <category>testing</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What are Webhooks and How to Test Them</title>
      <dc:creator>Mesut Yakut</dc:creator>
      <pubDate>Fri, 23 Jan 2026 15:47:24 +0000</pubDate>
      <link>https://dev.to/mstykt/what-are-webhooks-and-how-to-test-them-58o8</link>
      <guid>https://dev.to/mstykt/what-are-webhooks-and-how-to-test-them-58o8</guid>
      <description>&lt;p&gt;You're building an e-commerce app. A customer completes a payment, and you need to update their order status, send a confirmation email, and notify the warehouse. How does your payment provider tell your app that the payment succeeded?&lt;/p&gt;

&lt;p&gt;This is exactly where webhooks come in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Webhook?
&lt;/h2&gt;

&lt;p&gt;A webhook is an automated HTTP request that one system sends to another when a specific event occurs. Think of it as a "reverse API" - instead of your app asking "Did anything happen?", the other system proactively tells you "Hey, something just happened!"&lt;/p&gt;

&lt;p&gt;Traditional API polling works like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your App: "Any new payments?" → Payment API: "No"&lt;br&gt;
Your App: "Any new payments?" → Payment API: "No"&lt;br&gt;
Your App: "Any new payments?" → Payment API: "Yes! Here's the data"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Webhooks flip this around:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Payment API: "A payment just completed!" → Your App: "Got it, thanks!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is more efficient, real-time, and reduces unnecessary API calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Webhook Examples
&lt;/h2&gt;

&lt;p&gt;Webhooks are everywhere in modern software:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stripe/PayPal&lt;/strong&gt; sends a webhook when a payment succeeds or fails&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt; notifies your CI/CD pipeline when code is pushed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slack&lt;/strong&gt; triggers workflows when messages are posted&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shopify&lt;/strong&gt; alerts your inventory system when an order is placed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Twilio&lt;/strong&gt; informs your app when an SMS is delivered&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every major platform uses webhooks to enable real-time integrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Webhook Testing Challenge
&lt;/h2&gt;

&lt;p&gt;Here's the problem: webhooks are notoriously difficult to test during development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 1: You don't control when they fire&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When testing a Stripe integration, you can't just "trigger" a real payment webhook whenever you want. You'd need to make actual payments, wait for processing, and hope the webhook arrives.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 2: Your local server isn't accessible&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Webhooks need a public URL to send requests to. Your &lt;code&gt;localhost:3000&lt;/code&gt; isn't reachable from Stripe's servers. Developers often resort to tunneling tools, which add complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 3: Inconsistent payloads&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Real webhook payloads can vary. A payment webhook might include different fields depending on the payment method, currency, or account settings. Testing all variations is tedious.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 4: Timing and sequence issues&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What happens if a webhook arrives before your database transaction commits? Or if webhooks arrive out of order? These race conditions are hard to reproduce with real services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 5: Error handling is blind&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When your webhook handler fails in production, you often don't know why. The external service just sees a 500 error. Debugging requires extensive logging and often can't be reproduced locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Mock Servers Solve Webhook Testing
&lt;/h2&gt;

&lt;p&gt;A mock server lets you simulate webhook behavior without depending on external services. Instead of waiting for Stripe to send a webhook, you configure your mock server to send it exactly when and how you need.&lt;/p&gt;

&lt;p&gt;This approach gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Full control&lt;/strong&gt; over when webhooks fire&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Predictable payloads&lt;/strong&gt; that match your test scenarios&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local development&lt;/strong&gt; without public URLs or tunnels&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge case testing&lt;/strong&gt; for timeouts, failures, and retries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reproducible tests&lt;/strong&gt; that run the same way every time&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Webhooks in Mocklantis
&lt;/h2&gt;

&lt;p&gt;Mocklantis provides a complete webhook simulation system. Here's how it works:&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Webhook
&lt;/h3&gt;

&lt;p&gt;In Mocklantis, webhooks are standalone entities that you configure once and bind to multiple endpoints. When any bound endpoint is called, the webhook fires automatically.&lt;/p&gt;

&lt;p&gt;You configure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Target URL&lt;/strong&gt;: Where to send the webhook (your app's webhook handler)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP Method&lt;/strong&gt;: Usually POST, but supports all methods&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headers&lt;/strong&gt;: Custom headers like &lt;code&gt;Content-Type&lt;/code&gt; or authentication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Body&lt;/strong&gt;: The payload to send, with dynamic template support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Template Variables
&lt;/h3&gt;

&lt;p&gt;The real power comes from template variables. Your webhook payload can include data from the original request:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "event": "payment.completed",&lt;br&gt;
  "orderId": "{{request.body.orderId}}",&lt;br&gt;
  "amount": {{request.body.amount}},&lt;br&gt;
  "customerId": "{{request.body.customerId}}",&lt;br&gt;
  "processedAt": "{{request.timestamp}}",&lt;br&gt;
  "transactionId": "{{random.uuid}}"&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When a request hits your mock endpoint, Mocklantis extracts values from the request and injects them into the webhook payload. This creates realistic, dynamic webhooks that mirror real-world behavior.&lt;/p&gt;

&lt;p&gt;Available template variables include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;{{request.path.id}}&lt;/code&gt; - URL path parameters&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;{{request.query.page}}&lt;/code&gt; - Query string parameters&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;{{request.body.field}}&lt;/code&gt; - JSON body fields (supports nested paths)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;{{request.header.X-Custom}}&lt;/code&gt; - Request headers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;{{request.timestamp}}&lt;/code&gt; - ISO timestamp&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;{{random.uuid}}&lt;/code&gt; - Generate unique IDs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Webhook Flow
&lt;/h3&gt;

&lt;p&gt;Here's the sequence when a request arrives:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Client sends request to mock endpoint&lt;/li&gt;
&lt;li&gt;Mocklantis returns the mock response immediately&lt;/li&gt;
&lt;li&gt;Webhook fires asynchronously (doesn't block the response)&lt;/li&gt;
&lt;li&gt;Your webhook handler receives the notification&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This "fire-and-forget" approach mirrors how real webhook systems work. The webhook execution never affects your endpoint's response time or success.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advanced Configuration
&lt;/h3&gt;

&lt;p&gt;For realistic testing, Mocklantis supports:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Delay&lt;/strong&gt;: Add latency before the webhook fires. Real payment processors don't send webhooks instantly - there's usually a 1-5 second delay. Simulate this to test your app's behavior during that window.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retry Logic&lt;/strong&gt;: Configure automatic retries if your handler returns an error. Set retry count (up to 10) and delay between attempts. Test how your app handles webhook redelivery.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authentication&lt;/strong&gt;: Support for Basic Auth, Bearer tokens, and API keys. Test that your webhook handler properly validates incoming requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Timeout Control&lt;/strong&gt;: Set how long to wait for your handler's response. Test timeout scenarios without waiting forever.&lt;/p&gt;

&lt;h3&gt;
  
  
  Binding Webhooks to Endpoints
&lt;/h3&gt;

&lt;p&gt;A single webhook can be bound to multiple endpoints. For example, an "Order Notification" webhook might fire when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;POST /api/orders&lt;/code&gt; (new order created)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PUT /api/orders/:id/status&lt;/code&gt; (status change)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DELETE /api/orders/:id&lt;/code&gt; (order cancellation)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This models real-world scenarios where the same external system needs to know about multiple types of events.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Testing Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Testing Payment Flows
&lt;/h3&gt;

&lt;p&gt;Create a mock &lt;code&gt;POST /api/checkout&lt;/code&gt; endpoint that returns a success response, bound to a webhook that hits your &lt;code&gt;POST /webhooks/payment&lt;/code&gt; handler. Now you can test your entire payment flow locally, including the webhook processing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing Failure Handling
&lt;/h3&gt;

&lt;p&gt;Configure a webhook with a short timeout and point it at a slow endpoint. Verify your app handles webhook timeouts gracefully. Then test retry behavior by returning 500 errors and checking that retries occur.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing Race Conditions
&lt;/h3&gt;

&lt;p&gt;Add a 2-second delay to your webhook. Make a request and immediately query your database. Is the order in a "pending" state? Does your UI handle this correctly? These timing issues are nearly impossible to test with real services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing Idempotency
&lt;/h3&gt;

&lt;p&gt;Webhooks can be delivered multiple times. Configure retries and verify your handler doesn't create duplicate records or send duplicate emails when the same webhook arrives twice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Always verify webhook signatures&lt;/strong&gt; in production. While testing, you can skip this, but your production handler should validate that webhooks come from the expected source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Make handlers idempotent&lt;/strong&gt;. Use unique identifiers to detect and ignore duplicate deliveries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Respond quickly&lt;/strong&gt;. Return a 200 response immediately and process asynchronously. Webhook senders often have short timeouts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Log everything&lt;/strong&gt;. Webhook debugging is hard without detailed logs of what was received and how it was processed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test error scenarios&lt;/strong&gt;. Don't just test the happy path. Simulate network failures, invalid payloads, and authentication errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Webhooks are fundamental to modern application architecture, enabling real-time communication between services. But their asynchronous, external nature makes them challenging to test during development.&lt;/p&gt;

&lt;p&gt;By using a mock server with webhook support, you gain full control over the testing process. You can simulate any webhook scenario, test edge cases, and build confidence in your webhook handlers before deploying to production.&lt;/p&gt;

&lt;p&gt;The next time you're integrating with a webhook-based service, consider setting up mock webhooks first. Your future self will thank you when debugging that mysterious production issue.&lt;/p&gt;

&lt;p&gt;For this and more features: &lt;a href="https://mocklantis.com" rel="noopener noreferrer"&gt;mocklantis.com&lt;/a&gt;&lt;br&gt;
Download mocklantis: &lt;a href="https://mocklantis.com" rel="noopener noreferrer"&gt;mock server&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>testing</category>
      <category>webhooks</category>
      <category>mockserver</category>
    </item>
    <item>
      <title>Mocklantis: Modern API Mocking Made Simple</title>
      <dc:creator>Mesut Yakut</dc:creator>
      <pubDate>Fri, 12 Dec 2025 14:48:31 +0000</pubDate>
      <link>https://dev.to/mstykt/mocklantis-modern-api-mocking-made-simple-5do2</link>
      <guid>https://dev.to/mstykt/mocklantis-modern-api-mocking-made-simple-5do2</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1c5s0zszgcgr4apdkmd1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1c5s0zszgcgr4apdkmd1.png" alt=" " width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Hidden Cost of Dependencies: Why Mocking Matters
&lt;/h2&gt;

&lt;p&gt;Working with microservices architecture means living with dependencies. Your service talks to another service, that service talks to three more, and somewhere in this chain, there's a payment gateway, a notification service, and probably a third-party API with aggressive rate limits.&lt;/p&gt;

&lt;p&gt;When everything is up and running, life is good. But here's the question nobody likes to ask: what happens when they're not?&lt;/p&gt;

&lt;p&gt;How do you test a timeout scenario? How do you simulate a 503 from the payment service? How do you know your retry logic actually works before it matters?&lt;/p&gt;

&lt;p&gt;These questions are uncomfortable because the honest answer is often "we don't" or "we hope for the best."&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problems We Don't Talk About Enough
&lt;/h2&gt;

&lt;p&gt;In microservices development, there are friction points that slow everyone down but rarely get addressed properly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependencies block progress.&lt;/strong&gt; Your service is ready, but the one you depend on isn't. Maybe another team is still building it. Maybe it's a third-party API with sandbox limitations. Maybe it's a payment gateway that only behaves correctly in production. Whatever the reason, you're waiting for something outside your control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unit tests create false confidence.&lt;/strong&gt; Tests pass. Green checkmarks everywhere. But passing unit tests means your code works in isolation—with mocked interfaces that behave exactly as you programmed them. Real services don't behave that way. They timeout. They return unexpected responses. They fail at 3 AM on a Sunday.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simulating failure is harder than building features.&lt;/strong&gt; You need to verify what happens when a downstream service returns a 503. You need to test your circuit breaker. You need to confirm your fallback logic works. But actually creating these conditions? That's where teams give up and hope monitoring will catch problems in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Everyone mocks differently.&lt;/strong&gt; One developer hardcodes JSON responses. Another writes a small Express server. Someone else uses a CLI tool with YAML configs. The staging environment is shared by four teams and constantly broken. "Works on my machine" becomes the team motto.&lt;/p&gt;

&lt;p&gt;These aren't rare situations. This is Tuesday for most backend teams.&lt;/p&gt;




&lt;h2&gt;
  
  
  It's Not Just Microservices
&lt;/h2&gt;

&lt;p&gt;Dependency problems aren't exclusive to microservices architecture. They exist wherever two systems need to talk to each other.&lt;/p&gt;

&lt;p&gt;Frontend teams waiting for backend APIs to be ready. Mobile apps blocked because the server endpoint isn't deployed yet. Integration projects stalled because the third-party system has rate limits or sandbox restrictions.&lt;/p&gt;

&lt;p&gt;The pattern is the same: your work is done, but you can't verify it because something else isn't available. You're blocked not by your own code, but by external factors.&lt;/p&gt;

&lt;p&gt;This is where mocking becomes essential. Not as a nice-to-have, but as a fundamental part of how software gets built and tested.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Mocking Has a Bad Reputation
&lt;/h2&gt;

&lt;p&gt;The concept of mocking is simple: create fake services that return predictable responses. Test your code against them. Simulate any scenario you need.&lt;/p&gt;

&lt;p&gt;On paper, it's the perfect solution. In practice, most teams avoid it.&lt;/p&gt;

&lt;p&gt;Traditional mocking means configuration files. YAML or JSON schemas. CLI commands. Learning another tool's syntax. Restarting servers every time you change a response.&lt;/p&gt;

&lt;p&gt;You've already written the feature. You've already written unit tests. Now you need more setup just to simulate a service that someone else should have finished?&lt;/p&gt;

&lt;p&gt;The friction isn't worth it. So teams test against unstable staging environments or skip integration testing entirely. Neither is good, but both feel more practical than fighting mock server configuration.&lt;/p&gt;

&lt;p&gt;This is the real problem: mocking works, but the experience around it doesn't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mocklantis changes this.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mocklantis is a free desktop application for creating mock servers. It runs locally on macOS, Windows, and Linux. It supports HTTP/REST endpoints, WebSocket connections, Server-Sent Events, and webhooks—all in one application.&lt;/p&gt;

&lt;p&gt;But what makes it different is the experience. No configuration files. No CLI commands. No YAML schemas to learn. You open the app, create a server, add endpoints, and start testing. Changes apply instantly—no restarts, no rebuilds. Everything visual, everything immediate.&lt;/p&gt;

&lt;p&gt;The distance between "I want to test this scenario" and "I'm testing this scenario" becomes seconds instead of hours.&lt;/p&gt;




&lt;h2&gt;
  
  
  Mocklantis in Action
&lt;/h2&gt;

&lt;p&gt;The workflow is straightforward. You open the application, create a server on port 8080, add an endpoint—&lt;code&gt;POST /payments/process&lt;/code&gt;, type a JSON response, set the status code. Done. The endpoint is live. Your service can call it immediately.&lt;/p&gt;

&lt;p&gt;Need to test timeout handling? Add a delay. The change applies instantly—no restart, no config file, no terminal command. Need to test error scenarios? Change the status code to 503. Watch how your service responds.&lt;/p&gt;

&lt;p&gt;Need dynamic data? Mocklantis supports template variables—UUIDs that regenerate per request, timestamps, emails, names, values that follow custom patterns. Fourteen different random variable types built in.&lt;/p&gt;

&lt;p&gt;But HTTP/REST is just the beginning. Modern systems aren't just REST anymore.&lt;/p&gt;

&lt;p&gt;WebSockets are everywhere—real-time dashboards, notifications, chat systems, live feeds. Mocklantis supports WebSocket mocking with three modes: conversational for request-response patterns, streaming for continuous data flow, and triggered streaming where a client message triggers a sequence of responses—perfect for AI-style interactions.&lt;/p&gt;

&lt;p&gt;Server-Sent Events power streaming interfaces, especially in AI applications where responses arrive token by token. With Mocklantis, you configure events, set intervals, and define on-connect messages. Exactly what you need for testing streaming consumers.&lt;/p&gt;

&lt;p&gt;Need to trigger external callbacks? Webhooks are built in. When an endpoint is called, Mocklantis can fire HTTP requests to other URLs with configurable auth, retry logic, and delays.&lt;/p&gt;

&lt;p&gt;Everything visual. Everything immediate. No custom server code. No documentation required to get started.&lt;/p&gt;




&lt;h2&gt;
  
  
  Small Features, Big Impact
&lt;/h2&gt;

&lt;p&gt;Some capabilities sound minor until you actually need them. Mocklantis gets these details right.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live updates without restart.&lt;/strong&gt; Change any endpoint while your service is running. Modify responses, add delays, switch status codes—all without restarting anything. Stay in flow. Experiment freely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automatic persistence.&lt;/strong&gt; Every change saves immediately—500ms debounce, no save buttons. Close Mocklantis, come back tomorrow, everything is exactly as you left it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-time request logs.&lt;/strong&gt; See every request hitting your mock server as it happens. Headers, bodies, timing. Debug integration issues in seconds instead of adding logging statements everywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proxy mode.&lt;/strong&gt; Mock some endpoints, forward others to real services. Isolate specific dependencies while keeping the rest of your stack intact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Import from anywhere.&lt;/strong&gt; Paste a cURL command, import an OpenAPI spec, or load a .mock file. Don't start from scratch when you don't have to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local-only operation.&lt;/strong&gt; Everything runs on localhost. No cloud accounts. No data leaving your machine. No concerns about sensitive test data being logged somewhere.&lt;/p&gt;

&lt;p&gt;None of these are revolutionary on their own. Together, they remove the friction that stops teams from testing properly.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Friction Problem
&lt;/h2&gt;

&lt;p&gt;Developer tools follow a pattern: more power means more complexity. Steeper learning curves. Thicker documentation. More Stack Overflow questions about basic setup.&lt;/p&gt;

&lt;p&gt;But complexity isn't a requirement for capability. Usually it means nobody prioritized the user experience.&lt;/p&gt;

&lt;p&gt;The best tools disappear into your workflow. You don't think about them. You don't fight them. They just work.&lt;/p&gt;

&lt;p&gt;Mocklantis is built on this principle. Creating an endpoint shouldn't require reading documentation. Simulating a scenario shouldn't mean editing config files. Testing edge cases shouldn't feel like a separate project.&lt;/p&gt;

&lt;p&gt;When mocking is easy, teams mock more. They test more scenarios. They catch more bugs before production. The tool's simplicity directly impacts code quality.&lt;/p&gt;




&lt;h2&gt;
  
  
  Confidence Compounds
&lt;/h2&gt;

&lt;p&gt;Testing isn't about any single test. It's about the confidence that builds over time.&lt;/p&gt;

&lt;p&gt;When simulating scenarios is easy, you simulate more of them. You verify error handling works. You confirm retry logic behaves correctly. You ship knowing your code handles edge cases—not hoping it does.&lt;/p&gt;

&lt;p&gt;Reliable software comes from teams that can test thoroughly without fighting their tools. When the tooling gets out of the way, testing becomes a habit instead of a chore.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Dependency mocking is the most effective way to test services in isolation. It's how you verify that code handles real-world scenarios—not just happy paths, but failures, timeouts, and edge cases.&lt;/p&gt;

&lt;p&gt;Most teams don't mock enough because the friction is too high. Configuration files, CLI commands, server restarts, learning curves. Rational trade-offs lead to less testing and more production surprises.&lt;/p&gt;

&lt;p&gt;Mocklantis removes that friction. Visual interface. Instant updates. No configuration files. HTTP, WebSocket, and SSE support. Runs locally on macOS, Windows, and Linux.&lt;/p&gt;

&lt;p&gt;It's free. You can start using it in seconds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mocklantis.com" rel="noopener noreferrer"&gt;mocklantis.com&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Get Started
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;📥 &lt;a href="https://mocklantis.com/download" rel="noopener noreferrer"&gt;Download Mocklantis&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📖 &lt;a href="https://mocklantis.com/guide" rel="noopener noreferrer"&gt;Read the Guide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⭐ &lt;a href="https://mocklantis.com/features" rel="noopener noreferrer"&gt;See All Features&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have fun.&lt;/p&gt;

</description>
      <category>api</category>
      <category>testing</category>
      <category>webdev</category>
      <category>mocking</category>
    </item>
  </channel>
</rss>
