<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Software Engineering Made Simple</title><link>https://semsway.com/</link><description>Recent content on Software Engineering Made Simple</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Fri, 08 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://semsway.com/index.xml" rel="self" type="application/rss+xml"/><item><title>About</title><link>https://semsway.com/about/</link><pubDate>Fri, 08 May 2026 00:00:00 +0000</pubDate><guid>https://semsway.com/about/</guid><description>&lt;p>Hi, I&amp;rsquo;m &lt;strong>Mor Dabastany&lt;/strong>.&lt;/p>
&lt;p>A seasoned technologist working at the intersection of &lt;strong>AI-TestOps&lt;/strong> and &lt;strong>AI-Automation&lt;/strong>. Currently at &lt;strong>Palo Alto Networks&lt;/strong>, based out of Israel.&lt;/p>
&lt;h2 id="what-i-work-on">What I work on&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>AI-driven testing &amp;amp; automation&lt;/strong> - pushing quality engineering past hand-written assertions into agent-based validation.&lt;/li>
&lt;li>&lt;strong>Quality engineering transformation&lt;/strong> - taking teams from brittle manual QA to engineered, scalable test systems.&lt;/li>
&lt;li>&lt;strong>AI agent skills &amp;amp; validation&lt;/strong> - how do you test something that doesn&amp;rsquo;t behave deterministically? That&amp;rsquo;s the question.&lt;/li>
&lt;li>&lt;strong>Internal knowledge hubs&lt;/strong> - putting company knowledge in front of AI so engineers actually find what they need.&lt;/li>
&lt;li>&lt;strong>Prompt engineering &amp;amp; agentic workflows&lt;/strong> - practical, not theatrical.&lt;/li>
&lt;/ul>
&lt;h2 id="why-this-site">Why this site&lt;/h2>
&lt;p>I&amp;rsquo;ve been writing on LinkedIn for years. Reach is fine, platform is not - posts vanish into a feed, formatting is rough, code blocks unreadable. So everything moves here: searchable, properly typeset, with an RSS feed for people who still believe in the open web.&lt;/p></description></item><item><title>Nobody Tests Their AI Agent Skills. Here's Why That's a Problem (and How to Fix It)</title><link>https://semsway.com/posts/testing-ai-agent-skills/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/testing-ai-agent-skills/</guid><description>&lt;p>There are &lt;strong>47,000+ AI agent skills across 6,300+ repositories&lt;/strong> (according to a SkillsBench study that queries GitHub and others for the numbers). Almost none of them are tested beyond a &amp;ldquo;vibe check&amp;rdquo; - try it a few times, looks good, ship it.&lt;/p>
&lt;p>I was assigned to come up with a &lt;strong>framework-agnostic testing architecture&lt;/strong> for agent skills, and the research surfaced some things worth sharing.&lt;/p>
&lt;h2 id="the-core-insight-skills-need-4-types-of-testing-not-1">The core insight: skills need 4 types of testing, not 1&lt;/h2>
&lt;p>Most people think &amp;ldquo;testing a skill&amp;rdquo; means running the agent and seeing if it works. That&amp;rsquo;s only one layer. We identified four distinct testing concerns:&lt;/p></description></item><item><title>An Internal Knowledge Hub, Built 100% by AI</title><link>https://semsway.com/posts/internal-knowledge-hub-built-100-ai/</link><pubDate>Sun, 15 Mar 2026 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/internal-knowledge-hub-built-100-ai/</guid><description>&lt;h2 id="the-problem">The Problem&lt;/h2>
&lt;p>Every engineering team accumulates internal tools, frameworks, guides, and resources over time. But discovering and accessing them? That&amp;rsquo;s a different story. Links get buried in Slack threads, wikis grow stale, and onboarding new team members means repeating the same &amp;ldquo;here&amp;rsquo;s where you find X&amp;rdquo; conversations. Needless to say, that many teams are also using Confluence/Jira systems which complicates it even further.&lt;/p>
&lt;p>We needed a single, clean, internal portal, a front door to everything our team builds and maintains. But we didn&amp;rsquo;t want to spin up a backend, manage a database, or wrestle with a CMS.&lt;/p></description></item><item><title>Claude Sauce - Spicey, Yet Nicey</title><link>https://semsway.com/posts/claude-sauce-spicey-yet-nicey/</link><pubDate>Tue, 13 Jan 2026 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/claude-sauce-spicey-yet-nicey/</guid><description>&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>We built an internal framework - &lt;strong>Claude Sauce&lt;/strong> - that lets teams package domain knowledge, workflows, and automation into reusable modules for Claude. Think of it as creating &amp;ldquo;expert modes&amp;rdquo; that anyone can use, share, and improve.&lt;/p>
&lt;h2 id="the-problem-we-set-out-to-solve">The Problem We Set Out to Solve&lt;/h2>
&lt;p>Claude is extremely capable out of the box - but every organization has its own:&lt;/p>
&lt;ul>
&lt;li>Deep domain knowledge no general model can fully capture&lt;/li>
&lt;li>Established workflows that require specific sequences and checks&lt;/li>
&lt;li>Tooling and integrations unique to its tech stack&lt;/li>
&lt;li>Business logic that changes how tasks should be executed&lt;/li>
&lt;/ul>
&lt;p>As a result, every specialized use case meant the same friction: people re-explained context, re-wrote instructions, and hoped they didn&amp;rsquo;t forget critical nuances. Knowledge stayed trapped in individuals instead of becoming reusable.&lt;/p></description></item><item><title>Don't Waste Time to Style Your Code. Black It.</title><link>https://semsway.com/posts/dont-waste-time-style-your-code-black-it/</link><pubDate>Tue, 30 Sep 2025 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/dont-waste-time-style-your-code-black-it/</guid><description>&lt;p>As developers, we&amp;rsquo;ve all been there: spending precious minutes debating whether to use single or double quotes, arguing over line breaks in code reviews, or reformatting entire files to match team standards.&lt;/p>
&lt;p>What if I told you there&amp;rsquo;s a tool that eliminates these discussions entirely and gives you back hours each week? And the bonus part - it&amp;rsquo;s free and easy to use.&lt;/p>
&lt;h2 id="the-time-saving-reality">The Time-Saving Reality&lt;/h2>
&lt;p>Let me break down where &lt;a href="https://github.com/psf/black">Black&lt;/a> saves you real time:&lt;/p></description></item><item><title>How to Deploy a pytest Testing Project Using Cookiecutter</title><link>https://semsway.com/posts/deploy-pytest-cookiecutter/</link><pubDate>Mon, 08 Sep 2025 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/deploy-pytest-cookiecutter/</guid><description>&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>Cookiecutter is a powerful command-line utility that creates projects from templates, making it an excellent tool for standardizing and deploying pytest-based automation projects. Whether you&amp;rsquo;re setting up test automation for web applications, APIs, or mobile apps, Cookiecutter can help you bootstrap projects quickly while maintaining consistency across your organization.&lt;/p>
&lt;p>In this article, we&amp;rsquo;ll explore how to create and deploy a comprehensive pytest automation project template using Cookiecutter, covering everything from basic setup to advanced deployment strategies.&lt;/p></description></item><item><title>MCP Made Simple (Even for Testing!) Using FastMCP</title><link>https://semsway.com/posts/mcp-made-simple-fastmcp/</link><pubDate>Sun, 24 Aug 2025 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/mcp-made-simple-fastmcp/</guid><description>&lt;p>I&amp;rsquo;m not going to explain what MCP is - most of you are already onboarded to the hype. Instead I&amp;rsquo;m going to talk about &lt;strong>FastMCP&lt;/strong>, a framework that makes building Model Context Protocol (MCP) servers easy and fast.&lt;/p>
&lt;h2 id="what-is-mcp-quick-recap">What is MCP (quick recap)?&lt;/h2>
&lt;p>The Model Context Protocol lets AI models connect to external tools and data. Instead of building complex integrations from scratch, you create an MCP server that exposes your functionality in a standard way.&lt;/p></description></item><item><title>Kickstarting AI-Enhanced Automation Infrastructure: A Practical Guide Using Claude Code</title><link>https://semsway.com/posts/kickstarting-ai-enhanced-automation-infrastructure/</link><pubDate>Wed, 30 Jul 2025 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/kickstarting-ai-enhanced-automation-infrastructure/</guid><description>&lt;p>Imagine you&amp;rsquo;re a software developer - or better yet, an &lt;strong>automation infrastructure engineer&lt;/strong> - tasked with building a test framework from scratch. Sounds exciting, right? Well… that depends on how well you execute it.&lt;/p>
&lt;p>There are countless considerations when designing a resilient automation infrastructure. But the real secret? &lt;strong>Making it extensible with minimal effort.&lt;/strong>&lt;/p>
&lt;p>In this short guide, I&amp;rsquo;ll walk you through a method I&amp;rsquo;ve designed to streamline the design and implementation process using AI as a development partner.&lt;/p></description></item><item><title>Soft Asserting With pytest Made Fun</title><link>https://semsway.com/posts/asserting-pytest-made-fun/</link><pubDate>Thu, 10 Jul 2025 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/asserting-pytest-made-fun/</guid><description>&lt;p>As Python developers or automation engineers, we&amp;rsquo;ve all been there. You&amp;rsquo;re running a comprehensive test suite (unit, component, or end-to-end), and one assertion fails early in a test function. The test stops executing, and you&amp;rsquo;re left wondering about the other potential failures that might exist further down in the same test. You fix that one assertion, re-run the test, and discover another failure. &lt;em>Fix-run-test-fail-repeat&lt;/em>, isn&amp;rsquo;t it?&lt;/p>
&lt;h2 id="meet-pytest-check">Meet pytest-check&lt;/h2>
&lt;p>Unlike traditional pytest assertions that halt execution at the first failure, &lt;strong>pytest-check&lt;/strong> allows you to continue executing tests even after assertions fail. This means you can collect multiple failures in a single test run, dramatically improving your debugging efficiency and ability to explore multiple failure areas.&lt;/p></description></item><item><title>The Open Source Coding Companion: Harnessing OLLaMA 3 With PyCharm and Continue</title><link>https://semsway.com/posts/ollama-3-coding-companion/</link><pubDate>Sun, 12 May 2024 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/ollama-3-coding-companion/</guid><description>&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>In the ever-evolving landscape of artificial intelligence and natural language processing, open-source models have emerged as powerful tools for developers and researchers alike. Among these, the &lt;strong>OLLaMA 3&lt;/strong> model stands out for its impressive capabilities and accessibility.&lt;/p>
&lt;p>In this article, we&amp;rsquo;ll explore how to leverage OLLaMA 3 as an offline model and seamlessly integrate it with PyCharm using the &lt;strong>Continue&lt;/strong> plugin, unlocking a world of possibilities for enhanced coding productivity.&lt;/p></description></item><item><title>Reusing Core Functions for Locust and pytest: A Path to Efficient Testing</title><link>https://semsway.com/posts/reusing-core-functions-locust-pytest/</link><pubDate>Thu, 02 May 2024 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/reusing-core-functions-locust-pytest/</guid><description>&lt;p>In the world of software development, testing plays a crucial role in ensuring the quality and reliability of applications. Two widely used testing frameworks, &lt;strong>Locust&lt;/strong> and &lt;strong>pytest&lt;/strong>, have gained popularity due to their versatility and ease of use. However, as projects grow in complexity, it becomes essential to adopt practices that promote code reusability and maintainability.&lt;/p>
&lt;p>This article explores how to leverage the power of reusable functions across Locust and pytest, streamlining the testing process and improving overall efficiency.&lt;/p></description></item><item><title>Effective Unit Testing With Hypothesis and pytest</title><link>https://semsway.com/posts/effective-unit-testing-hypothesis-pytest/</link><pubDate>Mon, 15 Apr 2024 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/effective-unit-testing-hypothesis-pytest/</guid><description>&lt;p>Unit testing is a crucial aspect of software development, ensuring that individual components of a system work as expected. While traditional unit testing involves manually crafting test cases, tools like &lt;strong>Hypothesis&lt;/strong> and &lt;strong>pytest&lt;/strong> can significantly streamline and enhance the testing process.&lt;/p>
&lt;h2 id="introduction-to-hypothesis">Introduction to Hypothesis&lt;/h2>
&lt;p>Hypothesis is a powerful library for &lt;strong>property-based testing&lt;/strong> in Python. Unlike traditional unit testing, where you explicitly define test cases, Hypothesis lets you specify the &lt;strong>properties or invariants&lt;/strong> your code should satisfy. It then automatically generates a diverse set of test cases to validate those properties.&lt;/p></description></item><item><title>Sweet Debugging With IceCream for Python</title><link>https://semsway.com/posts/sweet-debugging-icecream-python/</link><pubDate>Sat, 06 Apr 2024 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/sweet-debugging-icecream-python/</guid><description>&lt;p>We&amp;rsquo;ve all been there - staring at lines of Python code, trying to figure out why our script isn&amp;rsquo;t behaving as expected. Debugging is a crucial skill for any programmer, but printing variables (e.g. &lt;code>print()&lt;/code>) all over the place can quickly become messy and cumbersome.&lt;/p>
&lt;p>Enter &lt;strong>IceCream&lt;/strong> - a sweet little debugging library that makes logging variables and expressions a piece of cake.&lt;/p>
&lt;p>IceCream is inspired by the popular debugging approach in JavaScript where you can sprinkle &lt;code>console.log()&lt;/code> statements throughout your code. Similarly, with IceCream you simply import the library and use the &lt;code>ic()&lt;/code> function to log variables, data structures, and even complex objects with a single line.&lt;/p></description></item><item><title>Elevate Your GitHub Profile to Stand Out</title><link>https://semsway.com/posts/elevate-your-github-profile/</link><pubDate>Tue, 02 Apr 2024 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/elevate-your-github-profile/</guid><description>&lt;p>Your GitHub profile is your virtual resume, showcasing your coding skills, projects, and contributions to the open-source community. By optimizing your profile, you can attract potential employers, collaborators, and peers, ultimately advancing your career in the tech industry.&lt;/p>
&lt;p>Here&amp;rsquo;s how you can enhance your GitHub profile to leave a lasting impression.&lt;/p>
&lt;h2 id="complete-your-profile-information">Complete your profile information&lt;/h2>
&lt;p>Provide a comprehensive overview of your skills, experiences, and interests. A well-written bio and a professional profile picture make a significant difference in how others perceive you. Add your location, website, and social media links to increase visibility and connectivity.&lt;/p></description></item><item><title>Extending pytest With Hooks and Plugins</title><link>https://semsway.com/posts/extending-pytest-hooks-plugins/</link><pubDate>Wed, 27 Mar 2024 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/extending-pytest-hooks-plugins/</guid><description>&lt;p>It&amp;rsquo;s no secret that I believe pytest is one of the most powerful Python-based test frameworks. One of its great features is the ability to be extended through &lt;strong>hooks&lt;/strong> and &lt;strong>plugins&lt;/strong>. Hooks let you tap into specific points during the testing process, while plugins provide a way to bundle hooks and other pytest extensions into a single distributable package.&lt;/p>
&lt;h2 id="utilizing-hooks">Utilizing hooks&lt;/h2>
&lt;p>Hooks are a way to extend or modify pytest&amp;rsquo;s behavior without modifying the core pytest code. pytest provides numerous hooks that you can define and implement in your tests. Here&amp;rsquo;s an example of using the &lt;code>pytest_runtest_setup&lt;/code> hook to perform an action before each test runs:&lt;/p></description></item><item><title>Streamlining Asynchronous System Testing With Flask and pytest</title><link>https://semsway.com/posts/async-testing-flask-pytest/</link><pubDate>Sun, 24 Mar 2024 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/async-testing-flask-pytest/</guid><description>&lt;p>For developers and QE engineers dealing with asynchronous systems, testing can be a significant challenge. These systems often respond with only a request ID, making it difficult to verify the actual response data. However, by leveraging the power of Flask and pytest, we can create a robust testing framework that simplifies the process.&lt;/p>
&lt;h2 id="the-asynchronous-system-challenge">The asynchronous system challenge&lt;/h2>
&lt;p>In an asynchronous system, when a request is sent, the system typically responds with a request ID rather than the actual data. This ID is then used to query the system for the result at a later time. This behavior can make testing difficult, as the traditional request-response cycle is disrupted.&lt;/p></description></item><item><title>pytest Parametrization: Injecting Data Into Tests</title><link>https://semsway.com/posts/pytest-parametrization-injecting-data/</link><pubDate>Wed, 20 Mar 2024 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/pytest-parametrization-injecting-data/</guid><description>&lt;p>As already mentioned in a previous article, pytest is a powerful testing framework for Python that offers a wide range of features, including &lt;strong>parametrization&lt;/strong>. Parametrization allows you to run the same test with different sets of input data, making it easier to test multiple scenarios without duplicating code.&lt;/p>
&lt;h2 id="parameterizing-tests">Parameterizing tests&lt;/h2>
&lt;p>pytest provides the &lt;code>@pytest.mark.parametrize&lt;/code> decorator to parameterize tests. This decorator takes two arguments: the name of the parameter(s) and a list of input data. Here&amp;rsquo;s a simple example:&lt;/p></description></item><item><title>Simplifying API Testing With pytest and Requests</title><link>https://semsway.com/posts/simplifying-api-testing-pytest-requests/</link><pubDate>Tue, 19 Mar 2024 00:00:00 +0000</pubDate><guid>https://semsway.com/posts/simplifying-api-testing-pytest-requests/</guid><description>&lt;p>As software developers, we often work with APIs, whether consuming third-party services or building our own. Ensuring our API interactions are functioning correctly is crucial, which is where testing comes into play. In this article, we&amp;rsquo;ll explore how to leverage &lt;strong>pytest&lt;/strong>, a powerful Python testing framework, along with the &lt;strong>requests&lt;/strong> library, to streamline API testing.&lt;/p>
&lt;h2 id="what-is-pytest">What is pytest?&lt;/h2>
&lt;p>pytest is a robust, feature-rich testing framework for Python that simplifies writing, organizing, and running tests. It offers a simple and intuitive syntax, making it easy to get started. Additionally, pytest supports a wide range of plugins that extend its functionality, enabling developers to tailor the testing experience to their specific needs.&lt;/p></description></item><item><title>Open Source Projects</title><link>https://semsway.com/projects/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://semsway.com/projects/</guid><description>&lt;p>A live list of my public GitHub repositories, sorted by most recently updated.&lt;/p>
&lt;ul id="projects-list" class="projects-list">
 &lt;li>Loading projects&amp;hellip;&lt;/li>
&lt;/ul>
&lt;style>
.projects-list { list-style: none; padding: 0; min-height: 800px; }
.projects-list li { margin: 0 0 1rem 0; padding: 1rem; border: 1px solid var(--border-color, #2a2a2a); border-radius: 8px; }
.projects-list li a { font-weight: 600; font-size: 1.1rem; }
.projects-list .repo-meta { display: block; margin-top: 0.25rem; opacity: 0.8; font-size: 0.9rem; }
.projects-list .repo-stars { float: right; }
&lt;/style>
&lt;script>
(function () {
 const username = "Formartha";
 const list = document.getElementById("projects-list");

 fetch(`https://api.github.com/users/${username}/repos?sort=updated&amp;per_page=100`)
 .then((r) => {
 if (!r.ok) throw new Error("GitHub API " + r.status);
 return r.json();
 })
 .then((repos) => {
 const visible = repos.filter(
 (r) => !r.fork &amp;&amp; r.name.toLowerCase() !== "formartha.github.io"
 );
 if (!visible.length) {
 list.innerHTML = "&lt;li>No public projects found.&lt;/li>";
 return;
 }
 list.innerHTML = "";
 for (const repo of visible) {
 const li = document.createElement("li");
 const desc = repo.description ? `&lt;span class="repo-meta">${repo.description}&lt;/span>` : "";
 const lang = repo.language ? `&lt;span class="repo-meta">${repo.language}&lt;/span>` : "";
 li.innerHTML = `
 &lt;a href="${repo.html_url}" target="_blank" rel="noopener">${repo.name}&lt;/a>
 &lt;span class="repo-stars">&amp;#9733; ${repo.stargazers_count}&lt;/span>
 ${desc}
 ${lang}
 `;
 list.appendChild(li);
 }
 })
 .catch((err) => {
 list.innerHTML = `&lt;li>Failed to load projects: ${err.message}&lt;/li>`;
 });
})();
&lt;/script></description></item><item><title>Privacy Policy</title><link>https://semsway.com/privacy/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://semsway.com/privacy/</guid><description>&lt;p>&lt;strong>Last updated:&lt;/strong> May 8, 2026
&lt;strong>Applies to:&lt;/strong> the semsway.com website.
&lt;strong>Contact:&lt;/strong> &lt;a href="mailto:morpci@gmail.com">morpci@gmail.com&lt;/a>&lt;/p>
&lt;hr>
&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>What we collect:&lt;/strong> anonymous, aggregated visit data via Cloudflare Web Analytics. No accounts. No forms.&lt;/li>
&lt;li>&lt;strong>What we use it for:&lt;/strong> understanding which posts get read so we can write better ones.&lt;/li>
&lt;li>&lt;strong>What we do not do:&lt;/strong> we do not sell, rent, or share personal data. We do not run ads. We do not use third-party trackers, marketing pixels, or identity-graph services.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="information-we-collect">Information We Collect&lt;/h2>
&lt;p>semsway.com is a static blog. There is no backend, no user accounts, no comments system, no contact form, no newsletter signup. &lt;strong>Nothing on this site asks you for personal information.&lt;/strong>&lt;/p></description></item></channel></rss>