<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Helper Code</title>
	<atom:link href="https://helpercode.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://helpercode.com</link>
	<description>On software development and anything else I find interesting...</description>
	<lastBuildDate>Mon, 30 Mar 2026 12:13:48 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://i0.wp.com/helpercode.com/wp-content/uploads/2017/03/cropped-dscn06732.jpg?fit=32%2C32&#038;ssl=1</url>
	<title>Helper Code</title>
	<link>https://helpercode.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">124941425</site>	<item>
		<title>Using Kiro Subagents to Improve Test Coverage</title>
		<link>https://helpercode.com/2026/03/30/using-kiro-sub-agents-to-improve-test-coverage/</link>
					<comments>https://helpercode.com/2026/03/30/using-kiro-sub-agents-to-improve-test-coverage/#comments</comments>
		
		<dc:creator><![CDATA[Dror Helper]]></dc:creator>
		<pubDate>Mon, 30 Mar 2026 12:07:47 +0000</pubDate>
				<category><![CDATA[Agentic Coding]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Kiro]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Unit Testing Tips]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Mock objects]]></category>
		<category><![CDATA[Unit tests]]></category>
		<category><![CDATA[XUnit]]></category>
		<guid isPermaLink="false">https://helpercode.com/?p=6838</guid>

					<description><![CDATA[Every developer knows the sinking feeling. A &#8220;simple&#8221; change breaks production. You realize there were no tests catching the edge case. Poor test coverage means longer debugging sessions, more production incidents, and that nagging anxiety every time you deploy. But here&#8217;s the catch-22: going back to add tests to existing code feels like an overwhelming &#8230; <a href="https://helpercode.com/2026/03/30/using-kiro-sub-agents-to-improve-test-coverage/" class="more-link">Continue reading <span class="screen-reader-text">Using Kiro Subagents to Improve Test Coverage</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Every developer knows the sinking feeling. A &#8220;simple&#8221; change breaks production. You realize there were no tests catching the edge case. Poor test coverage means longer debugging sessions, more production incidents, and that nagging anxiety every time you deploy. But here&#8217;s the catch-22: going back to add tests to existing code feels like an overwhelming task. Where do you even start?</p>



<p class="wp-block-paragraph"><strong>That&#8217;s where Coding AI changes the game.</strong> You don&#8217;t need to spend days writing tests for legacy code. Coding AI tools like <a href="https://kiro.dev">Kiro</a> can analyze your existing codebase. They understand the logic and generate comprehensive unit tests in minutes. You get the safety net of high test coverage without the manual grind. This frees you to focus on building new features. You don&#8217;t have to play archaeological detective with old code.</p>



<p class="wp-block-paragraph">In this blog post you&#8217;ll learn how to leverage <a href="https://kiro.dev">Kiro</a>, <a href="https://kiro.dev/docs/steering/">Steering files</a> and <a href="https://kiro.dev/docs/cli/chat/subagents/">Subagents</a> to dramatically improve your test coverage. This enhancement applies to existing projects. It turns that technical debt into a competitive advantage.</p>



<h2 class="wp-block-heading">T<strong>he Demo Application: Bob&#8217;s Used Bookstore</strong></h2>


<div class="wp-block-image">
<figure class="alignright size-large is-resized"><img data-recalc-dims="1" fetchpriority="high" decoding="async" width="1100" height="1321" data-attachment-id="6856" data-permalink="https://helpercode.com/2026/03/30/using-kiro-sub-agents-to-improve-test-coverage/bob-sticker/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/bob-sticker.jpeg?fit=1426%2C1712&amp;ssl=1" data-orig-size="1426,1712" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;,&quot;alt&quot;:&quot;&quot;}" data-image-title="Bob-sticker" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/bob-sticker.jpeg?fit=853%2C1024&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/bob-sticker.jpeg?resize=1100%2C1321&#038;ssl=1" alt="Illustration of a cheerful man giving a thumbs up in front of a used bookstore labeled 'Bob's Used Bookstore', featuring signs for various books including '.NET', 'NUG s'Nú', 'Extremely Cloudy', and 'ASP NET GOSSIP'." class="wp-image-6856" style="aspect-ratio:0.8330093476901232;width:164px;height:auto"/></figure>
</div>


<p class="wp-block-paragraph">For this blog post, I&#8217;m using <strong><a href="https://github.com/aws-samples/bobs-used-bookstore-sample">Bob&#8217;s Used Bookstore</a></strong>—an open-source .NET sample application from AWS that demonstrates real-world eCommerce functionality. Originally built as a monolithic ASP.NET Core MVC application, Bob&#8217;s Used Bookstore is a fictional second-hand book marketplace with both customer and admin portals. </p>



<p class="wp-block-paragraph">What makes Bob&#8217;s Used Bookstore ideal for demonstrating unit test coverage improvements is its realistic complexity without overwhelming scope. It includes actual business logic, like order processing, inventory management, and shopping carts. It also features service integrations and a well-structured codebase. The repository is available at <a href="https://github.com/aws-samples/bobs-used-bookstore-sample">GitHub</a>.</p>



<h2 class="wp-block-heading">T<strong>he Complete Workflow</strong></h2>



<p class="wp-block-paragraph">There are plenty of ways to improve test coverage with AI. Your mileage may vary depending on your codebase, team conventions, and testing philosophy, here&#8217;s the workflow I used to go from minimal coverage to 96 comprehensive unit tests:</p>



<ol class="wp-block-list">
<li><strong>Create</strong> <strong>steering files</strong> &#8211; Put together steering files to capture our testing standards</li>



<li><strong>Let Kiro help refine them</strong> &#8211; Use Kiro&#8217;s chat to polish both files based on what&#8217;s worked for us in the past</li>



<li><strong>Set them to auto-include</strong> &#8211; Add YAML headers with <code>inclusion: auto</code> so these rules kick in automatically whenever we&#8217;re creating or tweaking tests</li>



<li><strong>Built the test-gap-analyzer subagent</strong> &#8211; Create a custom agent that systematically scans the codebase to find all the missing unit tests and organizes them into units of work</li>



<li><strong>Built the unit-test-writer subagent</strong> &#8211; Create another agent that takes those gaps and generates comprehensive test files following our conventions</li>



<li><strong>Create an orchestration hook</strong> &#8211; Set up a manually-triggered hook that runs the gap analyzer first, then spins up multiple unit-test-writer agents in parallel to knock out all the missing tests</li>



<li><strong>Ran the workflow</strong> &#8211; Hit play on the hook and watch Kiro analyze the codebase, partition the work, and generate 96 new unit tests in just a few minutes</li>
</ol>



<h2 class="wp-block-heading">Teaching Kiro Unit Testing Best Practices</h2>



<p class="wp-block-paragraph">One of Kiro&#8217;s most powerful features is <strong>steering</strong>. This is the ability to guide its code generation with custom instructions. These instructions encode your team&#8217;s best practices. You can save time by using steering to &#8220;teach&#8221; Kiro your unit testing standards upfront. This way, there&#8217;s no need to manually review and correct every AI-generated test. For example, you can specify naming conventions, like <code>MethodName_Scenario_ExpectedBehavior</code>. You can enforce patterns like Arrange-Act-Assert, require specific assertion libraries, or mandate edge case coverage.</p>



<p class="wp-block-paragraph">And so the first thing to do is to &#8220;First you&#8217;ll need&#8221;teach&#8221; Kiro how an ideal unit test should look like &#8211; using steering files.</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="826" height="220" data-attachment-id="6844" data-permalink="https://helpercode.com/2026/03/30/using-kiro-sub-agents-to-improve-test-coverage/image-12/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-5.png?fit=826%2C220&amp;ssl=1" data-orig-size="826,220" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;,&quot;alt&quot;:&quot;&quot;}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-5.png?fit=826%2C220&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-5.png?resize=826%2C220&#038;ssl=1" alt="" class="wp-image-6844"/></figure>



<p class="wp-block-paragraph">I have created two files <a href="https://gist.github.com/dhelper/251b38a0e9f417f854c6f48f21db694c">unit-tests.naming-conventions.md</a> and <a href="https://gist.github.com/dhelper/fdcfb940d8b6bfe43222a9df7a77e2b7">unit-tests.xunit-assertion-rules.md</a> and used Kiro&#8217;s agentic chat to edit both files based on my preferences and experience. </p>



<p class="wp-block-paragraph">Steering files support several <a href="https://kiro.dev/docs/steering/">inclusion modes</a>. These modes define when the steering file is used as part of the chat context. Both files are only valid when writing unit tests. You should add the next header to your steering files. This ensures your unit testing standards are consistently enforced whenever you create or change tests without manual activation. </p>


<div style="--line-number-gutter-width: 1ch;" class="show-line-numbers wp-block-code">
	<div class="a8c/code__header"><div class="a8c/code__header-right"><button class="wp-element-button element-button a8c/code__btn-copy" type="button" data-copy-text="---
inclusion: auto
name: unit tests assertion rules
description: assertion rules for unit tests. Use when creating or modifying unit tests.
---" hidden>Copy</button></div></div>
	<div class="cm-editor">
		<div class="cm-scroller">
			
<pre><code class="language-markdown"><div class="cm-line">---</div><div class="cm-line"><span class="tok-heading">inclusion: auto</span></div><div class="cm-line"><span class="tok-heading">name: unit tests assertion rules</span></div><div class="cm-line"><span class="tok-heading">description: assertion rules for unit tests. Use when creating or modifying unit tests.</span></div><div class="cm-line"><span class="tok-heading tok-meta">---</span></div></code></pre>
		</div>
	</div>
</div>


<p class="wp-block-paragraph">Once the unit testing rules are defined in steering files, you can start working on unit tests. These include best practices and preferences.</p>



<h2 class="wp-block-heading">Creating the Test Gap Analyzer Subagent</h2>



<p class="wp-block-paragraph">Instead of writing a simple prompt I&#8217;ve decided to use an agent. Kiro&#8217;s <a href="https://kiro.dev/docs/chat/subagents/">subagents</a> transform code analysis by running specialized tasks in parallel, each with its own dedicated context window. Instead of overwhelming a single conversation with your entire codebase, you can analyze test coverage gaps. You can also evaluate dependencies. Additionally, you can assess code quality. Each task is handled by subagents focused on specific missions. This parallel architecture means faster insights and more precise recommendations. Each analysis maintains clean, isolated context. This prevents the pollution that degrades results when mixing multiple concerns in one thread.</p>



<p class="wp-block-paragraph">You can define your own custom agent by creating a markdown (.md) file in <code>~/.kiro/agents</code> (global) or <code>&lt;workspace>/.kiro/agents</code> (workspace scope). Enter the prompt for the custom agent in the body of the markdown file. Define extra attributes as YAML front matter. After I had the first agent in place I&#8217;ve asked Kiro to review and improve it and got the next agent definition:</p>


<div style="--line-number-gutter-width: 2ch;" class="show-line-numbers wp-block-code">
	<div class="a8c/code__header"><div class="a8c/code__header-right"><button class="wp-element-button element-button a8c/code__btn-copy" type="button" data-copy-text="---
name: test-gap-analyzer
description: Analyzes the codebase to identify missing unit tests by examining business logic classes and methods, mapping external dependencies, and producing a structured report of test gaps organized by units of work.
tools: [&quot;read&quot;]
---

You are a test gap analyzer. Your job is to analyze a codebase and identify missing unit tests.
Use the workspace steering files (in `.kiro/steering/`) to understand the project structure, tech stack, testing frameworks, and conventions before starting analysis. Do NOT assume any specific project layout — discover it from steering files and by exploring the codebase.

## Analysis Process

Follow these steps strictly:

### Step 1: Understand the Project
- Read all steering files in `.kiro/steering/` to learn the project structure, dependency flow, tech stack, test frameworks, and conventions.
- Identify the source directories, test directories, and how the project is organized.

### Step 2: Discover All Business Logic
Scan the solution to identify:
- All classes and methods that contain business logic (primary candidates for unit tests)
- All logic that interacts with external dependencies such as databases, HTTP clients, file systems, or message queues (candidates for integration tests)

### Step 3: Discover Existing Tests
Scan all test projects to catalog what is already tested. Map each existing test to the class/method it covers.

### Step 4: Identify Test Gaps
Compare Step 2 and Step 3 to find untested business logic. Focus on:
- Service classes with business rules
- Entity methods and computed properties
- Validation logic
- Controller/handler action methods with business logic
- Helper/utility methods with logic

### Step 5: Organize into Units of Work
Group the identified gaps into discrete units of work. Each unit of work should represent a logical grouping of related functionality. For each unit of work, determine:

1. **Target class and methods** — what specifically needs tests
2. **Test type** — unit test or integration test
3. **Dependencies to mock** — which interfaces/services need to be faked
4. **Test project** — which test project the tests belong in
5. **Priority** — High (core business logic, calculations, state changes), Medium (validation, filtering, mapping), Low (simple getters, pass-through methods)

## Output Format

Produce a structured report with:

1. **Summary** — total classes analyzed, total methods analyzed, existing test count, gap count
2. **Existing Test Coverage** — list of what&#039;s already tested
3. **Units of Work** — each unit formatted as:

```
### Unit of Work: [Name]
- **Target**: [Class.Method or Class (multiple methods)]
- **Test Type**: Unit Test | Integration Test
- **Test Project**: [project name]
- **Priority**: High | Medium | Low
- **Dependencies to Mock**: [list of interfaces]
- **What to Test**: [bullet list of specific behaviors/scenarios to verify]
- **Notes**: [any relevant context]
```

## Important Rules

- Tests must target business logic BEHAVIOR, not implementation details. Focus on what the code does, not how it does it internally.
- Do NOT suggest tests for trivial property getters/setters with no logic.
- Do NOT suggest tests for auto-generated code or migrations.
- Do NOT suggest integration tests for simple CRUD methods that just delegate to a data framework.
- DO suggest tests for any method that contains conditional logic, calculations, state transitions, or validation.
- DO suggest tests for data access methods that contain custom query logic beyond simple CRUD.
- When identifying dependencies to mock, list the interface name, not the concrete implementation." hidden>Copy</button></div></div>
	<div class="cm-editor">
		<div class="cm-scroller">
			
<pre><code class="language-markdown"><div class="cm-line">---</div><div class="cm-line"><span class="tok-heading">name: test-gap-analyzer</span></div><div class="cm-line"><span class="tok-heading">description: Analyzes the codebase to identify missing unit tests by examining business logic classes and methods, mapping external dependencies, and producing a structured report of test gaps organized by units of work.</span></div><div class="cm-line"><span class="tok-heading">tools: </span><span class="tok-heading tok-link tok-meta">[</span><span class="tok-heading tok-link">&quot;read&quot;</span><span class="tok-heading tok-link tok-meta">]</span></div><div class="cm-line"><span class="tok-heading tok-meta">---</span></div><div class="cm-line"></div><div class="cm-line">You are a test gap analyzer. Your job is to analyze a codebase and identify missing unit tests.</div><div class="cm-line">Use the workspace steering files (in <span class="tok-meta">`</span>.kiro/steering/<span class="tok-meta">`</span>) to understand the project structure, tech stack, testing frameworks, and conventions before starting analysis. Do NOT assume any specific project layout — discover it from steering files and by exploring the codebase.</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">##</span><span class="tok-heading"> Analysis Process</span></div><div class="cm-line"></div><div class="cm-line">Follow these steps strictly:</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">###</span><span class="tok-heading"> Step 1: Understand the Project</span></div><div class="cm-line"><span class="tok-meta">-</span> Read all steering files in <span class="tok-meta">`</span>.kiro/steering/<span class="tok-meta">`</span> to learn the project structure, dependency flow, tech stack, test frameworks, and conventions.</div><div class="cm-line"><span class="tok-meta">-</span> Identify the source directories, test directories, and how the project is organized.</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">###</span><span class="tok-heading"> Step 2: Discover All Business Logic</span></div><div class="cm-line">Scan the solution to identify:</div><div class="cm-line"><span class="tok-meta">-</span> All classes and methods that contain business logic (primary candidates for unit tests)</div><div class="cm-line"><span class="tok-meta">-</span> All logic that interacts with external dependencies such as databases, HTTP clients, file systems, or message queues (candidates for integration tests)</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">###</span><span class="tok-heading"> Step 3: Discover Existing Tests</span></div><div class="cm-line">Scan all test projects to catalog what is already tested. Map each existing test to the class/method it covers.</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">###</span><span class="tok-heading"> Step 4: Identify Test Gaps</span></div><div class="cm-line">Compare Step 2 and Step 3 to find untested business logic. Focus on:</div><div class="cm-line"><span class="tok-meta">-</span> Service classes with business rules</div><div class="cm-line"><span class="tok-meta">-</span> Entity methods and computed properties</div><div class="cm-line"><span class="tok-meta">-</span> Validation logic</div><div class="cm-line"><span class="tok-meta">-</span> Controller/handler action methods with business logic</div><div class="cm-line"><span class="tok-meta">-</span> Helper/utility methods with logic</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">###</span><span class="tok-heading"> Step 5: Organize into Units of Work</span></div><div class="cm-line">Group the identified gaps into discrete units of work. Each unit of work should represent a logical grouping of related functionality. For each unit of work, determine:</div><div class="cm-line"></div><div class="cm-line"><span class="tok-meta">1.</span> <span class="tok-strong tok-meta">**</span><span class="tok-strong">Target class and methods</span><span class="tok-strong tok-meta">**</span> — what specifically needs tests</div><div class="cm-line"><span class="tok-meta">2.</span> <span class="tok-strong tok-meta">**</span><span class="tok-strong">Test type</span><span class="tok-strong tok-meta">**</span> — unit test or integration test</div><div class="cm-line"><span class="tok-meta">3.</span> <span class="tok-strong tok-meta">**</span><span class="tok-strong">Dependencies to mock</span><span class="tok-strong tok-meta">**</span> — which interfaces/services need to be faked</div><div class="cm-line"><span class="tok-meta">4.</span> <span class="tok-strong tok-meta">**</span><span class="tok-strong">Test project</span><span class="tok-strong tok-meta">**</span> — which test project the tests belong in</div><div class="cm-line"><span class="tok-meta">5.</span> <span class="tok-strong tok-meta">**</span><span class="tok-strong">Priority</span><span class="tok-strong tok-meta">**</span> — High (core business logic, calculations, state changes), Medium (validation, filtering, mapping), Low (simple getters, pass-through methods)</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">##</span><span class="tok-heading"> Output Format</span></div><div class="cm-line"></div><div class="cm-line">Produce a structured report with:</div><div class="cm-line"></div><div class="cm-line"><span class="tok-meta">1.</span> <span class="tok-strong tok-meta">**</span><span class="tok-strong">Summary</span><span class="tok-strong tok-meta">**</span> — total classes analyzed, total methods analyzed, existing test count, gap count</div><div class="cm-line"><span class="tok-meta">2.</span> <span class="tok-strong tok-meta">**</span><span class="tok-strong">Existing Test Coverage</span><span class="tok-strong tok-meta">**</span> — list of what&apos;s already tested</div><div class="cm-line"><span class="tok-meta">3.</span> <span class="tok-strong tok-meta">**</span><span class="tok-strong">Units of Work</span><span class="tok-strong tok-meta">**</span> — each unit formatted as:</div><div class="cm-line"></div><div class="cm-line"><span class="tok-meta">```</span></div><div class="cm-line">### Unit of Work: [Name]</div><div class="cm-line">- **Target**: [Class.Method or Class (multiple methods)]</div><div class="cm-line">- **Test Type**: Unit Test | Integration Test</div><div class="cm-line">- **Test Project**: [project name]</div><div class="cm-line">- **Priority**: High | Medium | Low</div><div class="cm-line">- **Dependencies to Mock**: [list of interfaces]</div><div class="cm-line">- **What to Test**: [bullet list of specific behaviors/scenarios to verify]</div><div class="cm-line">- **Notes**: [any relevant context]</div><div class="cm-line"><span class="tok-meta">```</span></div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">##</span><span class="tok-heading"> Important Rules</span></div><div class="cm-line"></div><div class="cm-line"><span class="tok-meta">-</span> Tests must target business logic BEHAVIOR, not implementation details. Focus on what the code does, not how it does it internally.</div><div class="cm-line"><span class="tok-meta">-</span> Do NOT suggest tests for trivial property getters/setters with no logic.</div><div class="cm-line"><span class="tok-meta">-</span> Do NOT suggest tests for auto-generated code or migrations.</div><div class="cm-line"><span class="tok-meta">-</span> Do NOT suggest integration tests for simple CRUD methods that just delegate to a data framework.</div><div class="cm-line"><span class="tok-meta">-</span> DO suggest tests for any method that contains conditional logic, calculations, state transitions, or validation.</div><div class="cm-line"><span class="tok-meta">-</span> DO suggest tests for data access methods that contain custom query logic beyond simple CRUD.</div><div class="cm-line"><span class="tok-meta">-</span> When identifying dependencies to mock, list the interface name, not the concrete implementation.</div></code></pre>
		</div>
	</div>
</div>


<p class="wp-block-paragraph">This subagent definition creates a <strong>test gap analyzer</strong> that systematically identifies missing unit tests in a codebase. Here&#8217;s the breakdown by high-level structure:</p>



<p class="wp-block-paragraph"><strong>Lines 1-4</strong> &#8211; Header: agent definition, name, description, read-only tool access<br><strong>Lines 6-8</strong> &#8211; Purpose: audits test coverage by identifying missing unit tests<br><strong>Lines 10-41</strong> &#8211; Process: five steps to understand project structure, discover business logic, catalog existing tests, find gaps, and organize into prioritized units of work<br><strong>Lines 43-60</strong> &#8211; Output: structured report with summary, coverage list, and detailed units of work (target, type, project, priority, dependencies, test scenarios)<br><strong>Lines 62-70</strong> &#8211; Rules: focus on behavior over implementation, skip trivial code, emphasize logic with conditionals/calculations/validation, mock interfaces not implementations</p>



<p class="wp-block-paragraph">Running the agent is done by starting a new &#8220;Vibe&#8221; session and using <em>/test-gap-analyzer</em> from Kiro&#8217;s chat:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe class="youtube-player" width="1100" height="619" src="https://www.youtube.com/embed/FHYK4lAvTbs?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-US&#038;autohide=2&#038;wmode=transparent" allowfullscreen="true" style="border:0;" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox"></iframe>
</div></figure>



<h2 class="wp-block-heading">Creating Subagent to Add Missing Unit Tests </h2>



<p class="wp-block-paragraph">Now that you have the test gap analysis it&#8217;s time to add the missing unit tests. I have created another subagent to help add the missing tests and saved it&#8217;s definition in <em>unit-test-writer.md</em> (because naming is hard).<br>The subagent creates a <strong>unit test writer</strong> that systematically generates comprehensive test coverage based on gap analysis, while respecting existing project conventions and minimizing invasive changes to production code:</p>


<div style="--line-number-gutter-width: 2ch;" class="show-line-numbers wp-block-code">
	<div class="a8c/code__header"><div class="a8c/code__header-right"><button class="wp-element-button element-button a8c/code__btn-copy" type="button" data-copy-text="---
name: unit-test-writer
description: Creates unit test files based on test gap analysis output. Reads steering files for project conventions, naming standards, and assertion rules before writing tests.
tools: [&quot;read&quot;, &quot;write&quot;, &quot;shell&quot;]
---

You are a unit test writer. Your job is to create unit test files based on units of work provided to you, typically from a test gap analysis.

## Process

### Step 1: Read Steering Files
- Read all steering files in `.kiro/steering/` to learn the project structure, tech stack, test frameworks, naming conventions, and assertion rules.
- Follow all conventions defined in steering files strictly. Do NOT redefine or override them.

### Step 2: Examine Existing Tests
- Look at existing test files to understand the established patterns: imports, class structure, test method style, how mocks are set up, how test data is created.
- Reuse existing builders, helpers, and shared infrastructure where available.

### Step 3: Read the Source Code
- For each unit of work, read the target class and its dependencies to fully understand the behavior being tested.
- Identify all code paths, edge cases, and boundary conditions.

### Step 4: Write the Tests
- Create test files in the appropriate test project following the discovered conventions.
- Each test file should cover one unit of work (one class or closely related group of methods).
- Write tests that verify behavior, not implementation details.

### Step 5: Validate Per Project
- After finishing all test files for a specific test project, run `dotnet test` on that project to verify tests compile and pass.
- Fix any failures before moving on to the next project.

### Step 6: Final Validation
- After all test files are written across all projects, run `dotnet test` on the entire solution to verify everything works together.
- Fix any failures found.

## Test Writing Rules

- Write UNIT TESTS only. Do not write integration tests.
- All naming conventions and assertion rules are defined in the steering files. Follow them — do not duplicate or redefine them here.
- Mock all external dependencies using the project&#039;s mocking framework.
- Each test method should verify one logical behavior/scenario.
- Use Arrange-Act-Assert pattern.
- Include edge cases: null inputs, empty collections, boundary values, error conditions.
- Do NOT test trivial getters/setters, constructors with no logic, or auto-generated code.
- Do NOT duplicate existing tests — check what already exists before writing.
- Reuse existing test builders and helpers rather than creating new ones when possible.
- Create new builders only when no suitable one exists for the class under test.
- Place test files in the correct test project following the project&#039;s organizational pattern.

## Source Code Modification Policy

- Do NOT modify existing source code files (code under test) except in the following specific cases:
  1. Extracting interfaces from existing classes to enable mocking of existing dependencies.
  2. Updating constructors to enable dependency injection only when needed for injecting mocks for testing.
  3. Updating project files (`.csproj`) to add `InternalsVisibleTo` attributes to allow mocking of internal classes.
- Any other changes to production source code are strictly forbidden. Tests must be written against the existing code as-is." hidden>Copy</button></div></div>
	<div class="cm-editor">
		<div class="cm-scroller">
			
<pre><code class="language-markdown"><div class="cm-line">---</div><div class="cm-line"><span class="tok-heading">name: unit-test-writer</span></div><div class="cm-line"><span class="tok-heading">description: Creates unit test files based on test gap analysis output. Reads steering files for project conventions, naming standards, and assertion rules before writing tests.</span></div><div class="cm-line"><span class="tok-heading">tools: </span><span class="tok-heading tok-link tok-meta">[</span><span class="tok-heading tok-link">&quot;read&quot;, &quot;write&quot;, &quot;shell&quot;</span><span class="tok-heading tok-link tok-meta">]</span></div><div class="cm-line"><span class="tok-heading tok-meta">---</span></div><div class="cm-line"></div><div class="cm-line">You are a unit test writer. Your job is to create unit test files based on units of work provided to you, typically from a test gap analysis.</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">##</span><span class="tok-heading"> Process</span></div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">###</span><span class="tok-heading"> Step 1: Read Steering Files</span></div><div class="cm-line"><span class="tok-meta">-</span> Read all steering files in <span class="tok-meta">`</span>.kiro/steering/<span class="tok-meta">`</span> to learn the project structure, tech stack, test frameworks, naming conventions, and assertion rules.</div><div class="cm-line"><span class="tok-meta">-</span> Follow all conventions defined in steering files strictly. Do NOT redefine or override them.</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">###</span><span class="tok-heading"> Step 2: Examine Existing Tests</span></div><div class="cm-line"><span class="tok-meta">-</span> Look at existing test files to understand the established patterns: imports, class structure, test method style, how mocks are set up, how test data is created.</div><div class="cm-line"><span class="tok-meta">-</span> Reuse existing builders, helpers, and shared infrastructure where available.</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">###</span><span class="tok-heading"> Step 3: Read the Source Code</span></div><div class="cm-line"><span class="tok-meta">-</span> For each unit of work, read the target class and its dependencies to fully understand the behavior being tested.</div><div class="cm-line"><span class="tok-meta">-</span> Identify all code paths, edge cases, and boundary conditions.</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">###</span><span class="tok-heading"> Step 4: Write the Tests</span></div><div class="cm-line"><span class="tok-meta">-</span> Create test files in the appropriate test project following the discovered conventions.</div><div class="cm-line"><span class="tok-meta">-</span> Each test file should cover one unit of work (one class or closely related group of methods).</div><div class="cm-line"><span class="tok-meta">-</span> Write tests that verify behavior, not implementation details.</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">###</span><span class="tok-heading"> Step 5: Validate Per Project</span></div><div class="cm-line"><span class="tok-meta">-</span> After finishing all test files for a specific test project, run <span class="tok-meta">`</span>dotnet test<span class="tok-meta">`</span> on that project to verify tests compile and pass.</div><div class="cm-line"><span class="tok-meta">-</span> Fix any failures before moving on to the next project.</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">###</span><span class="tok-heading"> Step 6: Final Validation</span></div><div class="cm-line"><span class="tok-meta">-</span> After all test files are written across all projects, run <span class="tok-meta">`</span>dotnet test<span class="tok-meta">`</span> on the entire solution to verify everything works together.</div><div class="cm-line"><span class="tok-meta">-</span> Fix any failures found.</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">##</span><span class="tok-heading"> Test Writing Rules</span></div><div class="cm-line"></div><div class="cm-line"><span class="tok-meta">-</span> Write UNIT TESTS only. Do not write integration tests.</div><div class="cm-line"><span class="tok-meta">-</span> All naming conventions and assertion rules are defined in the steering files. Follow them — do not duplicate or redefine them here.</div><div class="cm-line"><span class="tok-meta">-</span> Mock all external dependencies using the project&apos;s mocking framework.</div><div class="cm-line"><span class="tok-meta">-</span> Each test method should verify one logical behavior/scenario.</div><div class="cm-line"><span class="tok-meta">-</span> Use Arrange-Act-Assert pattern.</div><div class="cm-line"><span class="tok-meta">-</span> Include edge cases: null inputs, empty collections, boundary values, error conditions.</div><div class="cm-line"><span class="tok-meta">-</span> Do NOT test trivial getters/setters, constructors with no logic, or auto-generated code.</div><div class="cm-line"><span class="tok-meta">-</span> Do NOT duplicate existing tests — check what already exists before writing.</div><div class="cm-line"><span class="tok-meta">-</span> Reuse existing test builders and helpers rather than creating new ones when possible.</div><div class="cm-line"><span class="tok-meta">-</span> Create new builders only when no suitable one exists for the class under test.</div><div class="cm-line"><span class="tok-meta">-</span> Place test files in the correct test project following the project&apos;s organizational pattern.</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">##</span><span class="tok-heading"> Source Code Modification Policy</span></div><div class="cm-line"></div><div class="cm-line"><span class="tok-meta">-</span> Do NOT modify existing source code files (code under test) except in the following specific cases:</div><div class="cm-line">  <span class="tok-meta">1.</span> Extracting interfaces from existing classes to enable mocking of existing dependencies.</div><div class="cm-line">  <span class="tok-meta">2.</span> Updating constructors to enable dependency injection only when needed for injecting mocks for testing.</div><div class="cm-line">  <span class="tok-meta">3.</span> Updating project files (<span class="tok-meta">`</span>.csproj<span class="tok-meta">`</span>) to add <span class="tok-meta">`</span>InternalsVisibleTo<span class="tok-meta">`</span> attributes to allow mocking of internal classes.</div><div class="cm-line"><span class="tok-meta">-</span> Any other changes to production source code are strictly forbidden. Tests must be written against the existing code as-is.</div></code></pre>
		</div>
	</div>
</div>


<p class="wp-block-paragraph"><strong>Lines 1-4</strong> &#8211; <strong>Header section</strong> &#8211; Agent definition with name, description, and tools (read, write, shell access)<br><strong>Lines 6-7</strong> &#8211; <strong>Core purpose</strong> &#8211; The agent acts as a unit test creator that generates test files from test gap analysis output<br><strong>Lines 9-42</strong> &#8211; <strong>Process workflow</strong> &#8211; Six-step methodology:</p>



<ul class="wp-block-list">
<li><strong>Step 1</strong>: Read steering files to understand project conventions</li>



<li><strong>Step 2</strong>: Examine existing tests to learn established patterns</li>



<li><strong>Step 3</strong>: Read source code to understand behavior being tested</li>



<li><strong>Step 4</strong>: Write tests following discovered conventions</li>



<li><strong>Step 5</strong>: Validate per project using <code>dotnet test</code></li>



<li><strong>Step 6</strong>: Final validation across entire solution</li>
</ul>



<p class="wp-block-paragraph"><strong>Lines 44-56</strong> &#8211; <strong>Test writing rules</strong> &#8211; Enforce unit test best practices. Follow the AAA pattern. Mock dependencies. Cover edge cases. Avoid testing trivial code. Reuse existing test infrastructure. Prevent test duplication.<br><strong>Lines 58-65</strong> &#8211; <strong>Source code modification policy</strong> &#8211; Strictly limit changes to production code. Only allow interface extraction for mocking, constructor updates for dependency injection, and <code>.csproj</code> modifications for <code>InternalsVisibleTo</code> attributes. All other source modifications are forbidden.</p>



<p class="wp-block-paragraph">With the two agents created &#8211; it&#8217;s time to add the final piece in the puzzle &#8211; orchestration.</p>



<h2 class="wp-block-heading">Orchestrating Subagents using Kiro&#8217;s Agent Hooks</h2>



<p class="wp-block-paragraph"><a href="https://kiro.dev/docs/hooks/">Agent hooks </a>are powerful automation tools. They automate your development workflow by executing predefined agent actions. These actions turn on automatically when specific events occur in your IDE. With hooks, you remove the need to manually ask for routine tasks and guarantee consistency across your codebase.</p>



<p class="wp-block-paragraph">But, in this case you do not need to use Kiro&#8217;s Hooks automatic triggering capabilities. Instead, we&#8217;ll use a manually triggered hook. We&#8217;ll use the hook to define and store the workflow to run the first subagent. Then, it will run the second subagent in parallel!</p>



<p class="wp-block-paragraph">Creating a new Hook from the &#8216;+&#8217; in Kiro&#8217;s menu:<br></p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="433" height="133" data-attachment-id="6872" data-permalink="https://helpercode.com/2026/03/30/using-kiro-sub-agents-to-improve-test-coverage/image-14/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-7.png?fit=433%2C133&amp;ssl=1" data-orig-size="433,133" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;,&quot;alt&quot;:&quot;&quot;}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-7.png?fit=433%2C133&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-7.png?resize=433%2C133&#038;ssl=1" alt="" class="wp-image-6872"/></figure>



<p class="wp-block-paragraph">Then choose <em>Manually create a hook</em></p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1055" height="256" data-attachment-id="6874" data-permalink="https://helpercode.com/2026/03/30/using-kiro-sub-agents-to-improve-test-coverage/image-15/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-8.png?fit=1055%2C256&amp;ssl=1" data-orig-size="1055,256" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;,&quot;alt&quot;:&quot;&quot;}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-8.png?fit=1024%2C248&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-8.png?resize=1055%2C256&#038;ssl=1" alt="" class="wp-image-6874"/></figure>



<p class="wp-block-paragraph">Give a title and description. Make sure that the event type is <em>Manual Trigger</em> and in the action paste the next code:</p>


<div style="--line-number-gutter-width: 2ch;" class="show-line-numbers wp-block-code">
	<div class="a8c/code__header"><div class="a8c/code__header-right"><button class="wp-element-button element-button a8c/code__btn-copy" type="button" data-copy-text="Run the test-gap-analyzer sub-agent to analyze the codebase and identify all missing unit tests.

Once the analysis is complete, run &#039;dotnet build&#039; to verify solution build succesfully. Fix any errors before continuing to the next stage.

Then group the high-priority units of work by their target test project. Within each test project, further partition the units of work into non-overlapping batches so that no two batches create or modify the same test file. A good partitioning strategy is:
- Batch by class-under-test category (e.g., entity tests vs. service tests) so each batch writes to different test files.
- Each batch should list the exact unit-of-work names it must handle.

Then invoke multiple unit-test-writer sub-agents IN PARALLEL — one per batch. Each sub-agent prompt must:
1. Specify the exact units of work (by name) it is responsible for.
2. Specify which test files it should create (so there is zero overlap with other batches).
3. Include the full gap analysis context for those units.

IMPORTANT: No two parallel sub-agents may create or modify the same file. Partition so each agent owns distinct test files. After all parallel agents complete, run &#039;dotnet test&#039; once on the full solution to validate everything compiles and passes." hidden>Copy</button></div></div>
	<div class="cm-editor">
		<div class="cm-scroller">
			
<pre><code class="language-markdown"><div class="cm-line">Run the test-gap-analyzer sub-agent to analyze the codebase and identify all missing unit tests.</div><div class="cm-line"></div><div class="cm-line">Once the analysis is complete, run &apos;dotnet build&apos; to verify solution build succesfully. Fix any errors before continuing to the next stage.</div><div class="cm-line"></div><div class="cm-line">Then group the high-priority units of work by their target test project. Within each test project, further partition the units of work into non-overlapping batches so that no two batches create or modify the same test file. A good partitioning strategy is:</div><div class="cm-line"><span class="tok-meta">-</span> Batch by class-under-test category (e.g., entity tests vs. service tests) so each batch writes to different test files.</div><div class="cm-line"><span class="tok-meta">-</span> Each batch should list the exact unit-of-work names it must handle.</div><div class="cm-line"></div><div class="cm-line">Then invoke multiple unit-test-writer sub-agents IN PARALLEL — one per batch. Each sub-agent prompt must:</div><div class="cm-line"><span class="tok-meta">1.</span> Specify the exact units of work (by name) it is responsible for.</div><div class="cm-line"><span class="tok-meta">2.</span> Specify which test files it should create (so there is zero overlap with other batches).</div><div class="cm-line"><span class="tok-meta">3.</span> Include the full gap analysis context for those units.</div><div class="cm-line"></div><div class="cm-line">IMPORTANT: No two parallel sub-agents may create or modify the same file. Partition so each agent owns distinct test files. After all parallel agents complete, run &apos;dotnet test&apos; once on the full solution to validate everything compiles and passes.</div></code></pre>
		</div>
	</div>
</div>


<p class="wp-block-paragraph">After you save the hook you will see the new hook with a &#8220;play&#8221; button added under the <em>Agent Hooks</em> section, along with the steering files we&#8217;ve created:<br></p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="523" height="624" data-attachment-id="6880" data-permalink="https://helpercode.com/2026/03/30/using-kiro-sub-agents-to-improve-test-coverage/image-19/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-12.png?fit=523%2C624&amp;ssl=1" data-orig-size="523,624" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;,&quot;alt&quot;:&quot;&quot;}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-12.png?fit=523%2C624&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-12.png?resize=523%2C624&#038;ssl=1" alt="" class="wp-image-6880"/></figure>



<p class="wp-block-paragraph">With all the pieces in place, you can run the hook. Kiro runs a subagent to conduct a codebase-wide analysis. Then, it spins up multiple subagents to add the missing unit tests.</p>



<p class="wp-block-paragraph">Kiro spins up a subagent to analyze and find the missing unit tests &#8211; then analyze the results and break the work down between multiple subagents that write new unit test tests across my codebase:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="920" height="1050" data-attachment-id="6882" data-permalink="https://helpercode.com/2026/03/30/using-kiro-sub-agents-to-improve-test-coverage/image-20/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-13.png?fit=920%2C1050&amp;ssl=1" data-orig-size="920,1050" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;,&quot;alt&quot;:&quot;&quot;}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-13.png?fit=897%2C1024&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-13.png?resize=920%2C1050&#038;ssl=1" alt="" class="wp-image-6882"/></figure>



<p class="wp-block-paragraph">And finally, after a few minutes, Kiro has created <strong>96 new unit tests</strong>. These tests will help catch bugs early. They allow confident refactoring and reduce deployment anxiety.</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="904" height="478" data-attachment-id="6885" data-permalink="https://helpercode.com/2026/03/30/using-kiro-sub-agents-to-improve-test-coverage/image-22/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-15.png?fit=904%2C478&amp;ssl=1" data-orig-size="904,478" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;,&quot;alt&quot;:&quot;&quot;}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-15.png?fit=904%2C478&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-15.png?resize=904%2C478&#038;ssl=1" alt="" class="wp-image-6885"/></figure>



<p class="wp-block-paragraph">If you want to follow the how Kiro tracked than written missing unit tests &#8211; I have published the <a href="https://youtu.be/j62hqG6DzTM">full run to YouTube</a> (no audio)</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">Poor test coverage leads to production bugs, longer debugging cycles, and deployment anxiety. This solution shows the transformative power of Kiro. It combines steering files and specialized subagents. Kiro can turn technical debt into a competitive advantage. It automates comprehensive test generation in minutes rather than weeks.</p>



<p class="wp-block-paragraph">The <strong>test-gap-analyzer</strong> subagent systematically audits your codebase. It identifies untested business logic. Meanwhile, the <strong>unit-test-writer</strong> subagent generates tests that follow your team&#8217;s established conventions. Together, they remove the manual burden of writing tests for legacy code. They uphold quality standards through steering files. These files encode your naming conventions, assertion rules, and architectural patterns.</p>



<p class="wp-block-paragraph">Start enhancing your test coverage today. Teach <a href="https://kiro.dev">Kiro</a> your team&#8217;s standards. Let AI manage the repetitive work of test generation.</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://helpercode.com/2026/03/30/using-kiro-sub-agents-to-improve-test-coverage/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6838</post-id>	</item>
		<item>
		<title>Kiro for Test-Driven Development (TDD)</title>
		<link>https://helpercode.com/2026/03/16/kiro-for-test-driven-development-tdd/</link>
					<comments>https://helpercode.com/2026/03/16/kiro-for-test-driven-development-tdd/#comments</comments>
		
		<dc:creator><![CDATA[Dror Helper]]></dc:creator>
		<pubDate>Mon, 16 Mar 2026 14:12:31 +0000</pubDate>
				<category><![CDATA[Agentic Coding]]></category>
		<category><![CDATA[Kiro]]></category>
		<category><![CDATA[Unit Testing Tips]]></category>
		<category><![CDATA[Refactoring]]></category>
		<category><![CDATA[software-development]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[testing]]></category>
		<guid isPermaLink="false">https://helpercode.com/?p=6764</guid>

					<description><![CDATA[This post explores the compatibility of Test-Driven Development (TDD) with AI coding assistants, specifically using Kiro, an AI-powered IDE. The author conducts an experiment involving the Number Parser Kata to demonstrate how Kiro effectively follows TDD principles, emphasizing that TDD remains essential for ensuring that AI-generated code solves the intended problems accurately.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">You&#8217;ve spent years mastering TDD&#8217;s red-green-refactor rhythm. Now AI coding assistants write code instantly. Should you abandon the discipline that made you a better developer, or do TDD and AI work together?</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">In this post I will use <a href="https://kiro.dev/">Kiro</a> &#8211; an AI-powered IDE that enables developers build software from prototype to production through spec-driven development, intelligent agent assistance, and automated workflows.</p>
</blockquote>



<p class="wp-block-paragraph"><em>Before we see how AI handles TDD, let&#8217;s revisit the cycle that makes it work:&nbsp;<strong>Red</strong>&nbsp;(write a failing test),&nbsp;<strong>Green</strong>&nbsp;(make it pass with minimal code),&nbsp;<strong>Refactor</strong>&nbsp;(clean up while keeping tests green). This rhythm isn&#8217;t just methodology—it&#8217;s the discipline that prevents us from writing code we don&#8217;t need.</em> </p>



<p class="wp-block-paragraph">For my experiment I&#8217;ve decided to use Roy Osherove&#8217;s &#8220;<a href="https://osherove.com/tdd-kata-1">String Calculator TDD Kata</a>&#8220;, however using such a well known TDD Kata results in the LLM solving it using one of the many implementations that already exist out there, so instead before starting I have asked my trusty AI to suggest a similar problem that was not tried before and so I present to you the <em><strong>Number Parser Kata</strong></em>:</p>



<p class="wp-block-paragraph"><strong>Objective:</strong> Create a function that parses written numbers in English and returns their numeric sum.</p>



<ul class="wp-block-list">
<li>Parse written numbers (&#8220;one&#8221;, &#8220;two&#8221;, &#8220;three&#8221;) and return their sum</li>



<li>Progressively add: handling &#8220;and&#8221; connectors, compound numbers (&#8220;twenty-three&#8221;), negatives (&#8220;minus five&#8221;)</li>



<li>Examples
<ul class="wp-block-list">
<li><code>parse("one")</code>&nbsp;→&nbsp;<code>1</code></li>



<li><code>parse("five")</code>&nbsp;→&nbsp;<code>5</code></li>



<li><code>parse("one two")</code>&nbsp;→&nbsp;<code>3</code></li>



<li><code>parse("one and two")</code>&nbsp;→&nbsp;<code>3</code></li>



<li><code>parse("thirteen and fifteen")</code>&nbsp;→&nbsp;<code>28</code></li>



<li><code>parse("minus five")</code>&nbsp;→&nbsp;<code>-5</code></li>
</ul>
</li>
</ul>



<p class="wp-block-paragraph">You get the point, as a starting point I wanted to see if providing a clear task enables Kiro to write the solution test first.</p>



<h2 class="wp-block-heading">&#8220;Teaching&#8221; Kiro about TDD using Steering files</h2>



<p class="wp-block-paragraph">For this TDD experiment, I created a steering file that explicitly taught Kiro the red-green-refactor cycle, ensuring it would write minimal failing tests first rather than jumping ahead to complete solutions.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><a href="https://kiro.dev/docs/steering/"><strong>Steering files</strong>&nbsp;</a>are instruction documents you place in your project that teach Kiro your team&#8217;s coding practices and workflows—steering files encode your development methodology directly into the AI&#8217;s behavior.</p>
</blockquote>



<p class="wp-block-paragraph">Since I&#8217;m going to work on a &#8220;green field&#8221; application I&#8217;ve also added steering files outlining the tech used (python), project structure and testing best practices.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="541" height="362" data-attachment-id="6773" data-permalink="https://helpercode.com/2026/03/16/kiro-for-test-driven-development-tdd/image-7/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image.png?fit=541%2C362&amp;ssl=1" data-orig-size="541,362" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image.png?fit=541%2C362&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image.png?resize=541%2C362&#038;ssl=1" alt="A screenshot of a software interface titled 'KIRO', featuring navigational elements such as 'SPECS', 'AGENT HOOKS', and 'AGENT STEERING &amp; SKILLS', along with a workspace section listing items like 'project-structure', 'tdd-workflow', 'tech', and 'test-standards'." class="wp-image-6773" /><figcaption class="wp-element-caption">Kiro AI IDE workspace showcasing the organization of project structure, TDD workflow, tech, and test standards for streamlined development.</figcaption></figure>
</div>


<p class="wp-block-paragraph">Here&#8217;s the key steering file that teaches Kiro TDD principles, notice lines 20-35, this was a crucial part that prevents Kiro from jmping ahead with implementation, writing one test then complete implementation without working step by step</p>


<div style="--line-number-gutter-width: 2ch;" class="show-line-numbers wp-block-code">
	<div class="a8c/code__header"><div class="a8c/code__header-right"><button class="wp-element-button element-button a8c/code__btn-copy" type="button" data-copy-text="---
inclusion: always
---
# TDD Workflow
## Philosophy
This project follows strict Test-Driven Development (TDD). All code must be written in response to a failing test. No production code exists without a corresponding test that drove its creation.

## The Red-Green-Refactor Cycle
- **Red**: Write a failing test that describes the desired behavior in plain English
- **Green**: Write the minimum production code to make the test pass — nothing more
- **Refactor**: Clean up the code while keeping all tests green

## Rules
- Never write production code before a failing test exists
- Tests must fail for the right reason before implementing
- Implement only what is needed to pass the current failing test
- After each green phase, consider if refactoring is needed
- All behavior must be described in plain English before generating a test

## What &quot;Minimum&quot; Means
**CRITICAL**: &quot;Minimum&quot; means the simplest possible code that makes ONLY the current test pass.

Examples of what NOT to do:
- &#x274c; Test checks &quot;one&quot; returns 1 → Don&#039;t implement a dictionary with &quot;one&quot; through &quot;ten&quot;
- &#x274c; Test checks addition of two numbers → Don&#039;t implement multiplication, division, etc.
- &#x274c; Test checks parsing a single word → Don&#039;t implement comma-separated parsing

Examples of correct minimal implementations:
- &#x2705; Test checks &quot;one&quot; returns 1 → Use `if numbers == &quot;one&quot;: return 1`
- &#x2705; Test checks &quot;two&quot; returns 2 → Add `elif numbers == &quot;two&quot;: return 2`
- &#x2705; After 3+ similar cases → Refactor to use a dictionary (driven by duplication, not anticipation)

**The Golden Rule**: If you can delete code and the test still passes, you wrote too much code.

**Resist the urge to be &quot;clever&quot; or &quot;complete&quot;**. Let the tests drive every single line of production code. Premature generalization violates TDD principles.

## Cycle Prompt Pattern
When asked to implement a feature, always:

1. First generate a failing test for ONE specific behavior
2. Confirm the test fails
3. Then generate the minimal implementation (see &quot;What Minimum Means&quot; above)
4. Confirm all tests pass
5. Suggest refactoring opportunities (only if duplication exists)
6. Review request and existing tests to find if additional tests are needed
   - If at least one more test is needed, start another cycle by writing a failing test
   - If not, declare that requirement was met

Break each feature into individual tasks for each step in the TDD lifecycle

## Self-Check Before Implementing
Before writing production code, ask yourself:
1. What is the EXACT assertion in the failing test?
2. What is the SIMPLEST code that makes that assertion pass?
3. Am I implementing anything the test doesn&#039;t verify?
4. If I remove this line, does the test still pass? (If yes, delete it)" hidden>Copy</button></div></div>
	<div class="cm-editor">
		<div class="cm-scroller">
			
<pre><code class="language-markdown"><div class="cm-line">---</div><div class="cm-line"><span class="tok-heading">inclusion: always</span></div><div class="cm-line"><span class="tok-heading tok-meta">---</span></div><div class="cm-line"><span class="tok-heading tok-meta">#</span><span class="tok-heading"> TDD Workflow</span></div><div class="cm-line"><span class="tok-heading tok-meta">##</span><span class="tok-heading"> Philosophy</span></div><div class="cm-line">This project follows strict Test-Driven Development (TDD). All code must be written in response to a failing test. No production code exists without a corresponding test that drove its creation.</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">##</span><span class="tok-heading"> The Red-Green-Refactor Cycle</span></div><div class="cm-line"><span class="tok-meta">-</span> <span class="tok-strong tok-meta">**</span><span class="tok-strong">Red</span><span class="tok-strong tok-meta">**</span>: Write a failing test that describes the desired behavior in plain English</div><div class="cm-line"><span class="tok-meta">-</span> <span class="tok-strong tok-meta">**</span><span class="tok-strong">Green</span><span class="tok-strong tok-meta">**</span>: Write the minimum production code to make the test pass — nothing more</div><div class="cm-line"><span class="tok-meta">-</span> <span class="tok-strong tok-meta">**</span><span class="tok-strong">Refactor</span><span class="tok-strong tok-meta">**</span>: Clean up the code while keeping all tests green</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">##</span><span class="tok-heading"> Rules</span></div><div class="cm-line"><span class="tok-meta">-</span> Never write production code before a failing test exists</div><div class="cm-line"><span class="tok-meta">-</span> Tests must fail for the right reason before implementing</div><div class="cm-line"><span class="tok-meta">-</span> Implement only what is needed to pass the current failing test</div><div class="cm-line"><span class="tok-meta">-</span> After each green phase, consider if refactoring is needed</div><div class="cm-line"><span class="tok-meta">-</span> All behavior must be described in plain English before generating a test</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">##</span><span class="tok-heading"> What &quot;Minimum&quot; Means</span></div><div class="cm-line"><span class="tok-strong tok-meta">**</span><span class="tok-strong">CRITICAL</span><span class="tok-strong tok-meta">**</span>: &quot;Minimum&quot; means the simplest possible code that makes ONLY the current test pass.</div><div class="cm-line"></div><div class="cm-line">Examples of what NOT to do:</div><div class="cm-line"><span class="tok-meta">-</span> &#x274c; Test checks &quot;one&quot; returns 1 → Don&apos;t implement a dictionary with &quot;one&quot; through &quot;ten&quot;</div><div class="cm-line"><span class="tok-meta">-</span> &#x274c; Test checks addition of two numbers → Don&apos;t implement multiplication, division, etc.</div><div class="cm-line"><span class="tok-meta">-</span> &#x274c; Test checks parsing a single word → Don&apos;t implement comma-separated parsing</div><div class="cm-line"></div><div class="cm-line">Examples of correct minimal implementations:</div><div class="cm-line"><span class="tok-meta">-</span> &#x2705; Test checks &quot;one&quot; returns 1 → Use <span class="tok-meta">`</span>if numbers == &quot;one&quot;: return 1<span class="tok-meta">`</span></div><div class="cm-line"><span class="tok-meta">-</span> &#x2705; Test checks &quot;two&quot; returns 2 → Add <span class="tok-meta">`</span>elif numbers == &quot;two&quot;: return 2<span class="tok-meta">`</span></div><div class="cm-line"><span class="tok-meta">-</span> &#x2705; After 3+ similar cases → Refactor to use a dictionary (driven by duplication, not anticipation)</div><div class="cm-line"></div><div class="cm-line"><span class="tok-strong tok-meta">**</span><span class="tok-strong">The Golden Rule</span><span class="tok-strong tok-meta">**</span>: If you can delete code and the test still passes, you wrote too much code.</div><div class="cm-line"></div><div class="cm-line"><span class="tok-strong tok-meta">**</span><span class="tok-strong">Resist the urge to be &quot;clever&quot; or &quot;complete&quot;</span><span class="tok-strong tok-meta">**</span>. Let the tests drive every single line of production code. Premature generalization violates TDD principles.</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">##</span><span class="tok-heading"> Cycle Prompt Pattern</span></div><div class="cm-line">When asked to implement a feature, always:</div><div class="cm-line"></div><div class="cm-line"><span class="tok-meta">1.</span> First generate a failing test for ONE specific behavior</div><div class="cm-line"><span class="tok-meta">2.</span> Confirm the test fails</div><div class="cm-line"><span class="tok-meta">3.</span> Then generate the minimal implementation (see &quot;What Minimum Means&quot; above)</div><div class="cm-line"><span class="tok-meta">4.</span> Confirm all tests pass</div><div class="cm-line"><span class="tok-meta">5.</span> Suggest refactoring opportunities (only if duplication exists)</div><div class="cm-line"><span class="tok-meta">6.</span> Review request and existing tests to find if additional tests are needed</div><div class="cm-line">   <span class="tok-meta">-</span> If at least one more test is needed, start another cycle by writing a failing test</div><div class="cm-line">   <span class="tok-meta">-</span> If not, declare that requirement was met</div><div class="cm-line"></div><div class="cm-line">Break each feature into individual tasks for each step in the TDD lifecycle</div><div class="cm-line"></div><div class="cm-line"><span class="tok-heading tok-meta">##</span><span class="tok-heading"> Self-Check Before Implementing</span></div><div class="cm-line">Before writing production code, ask yourself:</div><div class="cm-line"><span class="tok-meta">1.</span> What is the EXACT assertion in the failing test?</div><div class="cm-line"><span class="tok-meta">2.</span> What is the SIMPLEST code that makes that assertion pass?</div><div class="cm-line"><span class="tok-meta">3.</span> Am I implementing anything the test doesn&apos;t verify?</div><div class="cm-line"><span class="tok-meta">4.</span> If I remove this line, does the test still pass? (If yes, delete it)</div></code></pre>
		</div>
	</div>
</div>


<h2 class="wp-block-heading">Running the Red-Green-Refactor cycle</h2>



<p class="wp-block-paragraph">Now that I had my initial setup &#8211; I started with the first requirement:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Create a function that parses written numbers in English and returns their numeric sum. the method signature will be: int Add(string numbers).</p>



<p class="wp-block-paragraph">If a single number is written then the output should be that number numeric value </p>
</blockquote>



<p class="wp-block-paragraph">And it worked! &#8211; Kiro Jumped in and created a first failing test followed by a trivial implementation</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="802" height="414" data-attachment-id="6786" data-permalink="https://helpercode.com/2026/03/16/kiro-for-test-driven-development-tdd/image-10/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-3.png?fit=802%2C414&amp;ssl=1" data-orig-size="802,414" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-3.png?fit=802%2C414&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-3.png?resize=802%2C414&#038;ssl=1" alt="Code snippet showing a test for the Add function in a number parsing module, checking if the input 'one' returns 1." class="wp-image-6786" /><figcaption class="wp-element-caption">Test function for the Number Parser&#8217;s Add method, validating that the input &#8216;one&#8217; returns the correct output of 1.</figcaption></figure>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1100" height="616" data-attachment-id="6779" data-permalink="https://helpercode.com/2026/03/16/kiro-for-test-driven-development-tdd/image-8/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-1.png?fit=1656%2C928&amp;ssl=1" data-orig-size="1656,928" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-1.png?fit=1024%2C574&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-1.png?resize=1100%2C616&#038;ssl=1" alt="Screenshot of a coding environment showing a Python file named 'parser.py' with a function definition comment for a number parser module, along with test session details on the side." class="wp-image-6779" /><figcaption class="wp-element-caption">Kiro setup setup for a Number Parser in Python, from left to right: files, tests, implementation and agentic chat</figcaption></figure>



<p class="wp-block-paragraph">And then continued to implement all numbers between 1-10 as well and tests for sum of two numbers &#8211; which was the test I expected &#8211; trivial and simple:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="774" height="271" data-attachment-id="6781" data-permalink="https://helpercode.com/2026/03/16/kiro-for-test-driven-development-tdd/image-9/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-2.png?fit=774%2C271&amp;ssl=1" data-orig-size="774,271" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-2.png?fit=774%2C271&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2026/03/image-2.png?resize=774%2C271&#038;ssl=1" alt="Code snippet showing a test function for adding numbers represented as words, asserting that the sum of 'one' and 'two' equals 3." class="wp-image-6781" /><figcaption class="wp-element-caption">Python test function for adding multiple written number words, asserting that &#8216;one two&#8217; equals 3.</figcaption></figure>



<p class="wp-block-paragraph">All the time continuing the cycle of Red-Green-Refactor.</p>



<p class="wp-block-paragraph">As Kiro ran, I noticed that while the code was refactored and improved, the tests remained the same. After Kiro finished, I asked for a test refactor and updated Kiro&#8217;s Steering file to ensure both tests and code would be refactored going forward. </p>



<p class="wp-block-paragraph">Once all cycles were complete, I verified no additional tests were needed by requesting a quick test review. Kiro did jump ahead at one point—creating a parameterized test for all numbers between 4 and 10—but as someone who&#8217;s trained countless developers in TDD, this is a common &#8220;human behavior&#8221; if I ever saw one.</p>



<p class="wp-block-paragraph">If you want to see the whole run (6min 50sec) you can check it on YouTube:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" class="youtube-player" width="1100" height="619" src="https://www.youtube.com/embed/xIl3-59ZrT4?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-US&#038;autohide=2&#038;wmode=transparent" allowfullscreen="true" style="border:0;" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox"></iframe>
</div></figure>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">This experiment answered my initial question:&nbsp;<strong>Yes, TDD remains valuable in the age of AI coding assistants</strong>—not despite AI&#8217;s capabilities, but because of them.</p>



<p class="wp-block-paragraph">Kiro followed the red-green-refactor cycle when guided by steering files that encoded TDD principles. It wrote failing tests first, implemented minimal solutions, and refactored code while keeping tests green. The Number Parser Kata demonstrated that AI practices disciplined development when properly instructed.</p>



<p class="wp-block-paragraph">Kiro occasionally &#8220;jumped ahead&#8221; with parameterized tests—a behavior I&#8217;ve seen countless times when training human developers in TDD. This reinforced an important insight:&nbsp;<strong>we don&#8217;t abandon the practices that made us better developers in the world of agentic coding. Instead, we encode them into how we guide our AI tools.</strong></p>



<p class="wp-block-paragraph">Some argue AI&#8217;s ability to generate complex code with tests makes TDD obsolete. <strong>This experiment suggests otherwise:</strong> TDD provides the verification layer that ensures AI-generated code actually implements the specified behavior correctly. As AI coding assistants increase in capability, the discipline of TDD becomes more important, not less—it&#8217;s the guardrail that keeps us from accepting code that compiles but doesn&#8217;t solve the right problem.</p>



<p class="wp-block-paragraph"><strong> Try this yourself:</strong>&nbsp;use the steering file from earlier in this post and give TDD with AI a spin.</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://helpercode.com/2026/03/16/kiro-for-test-driven-development-tdd/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6764</post-id>	</item>
		<item>
		<title>Upcoming speaking engagements &#8211; May 2023</title>
		<link>https://helpercode.com/2023/04/30/upcoming-speaking-engagements-may-2023/</link>
					<comments>https://helpercode.com/2023/04/30/upcoming-speaking-engagements-may-2023/#respond</comments>
		
		<dc:creator><![CDATA[Dror Helper]]></dc:creator>
		<pubDate>Sun, 30 Apr 2023 11:13:30 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://helpercode.com/?p=3656</guid>

					<description><![CDATA[I have a couple of speaking opportunities starting next week with MS Tech Summit in Warsaw and later this month I&#8217;ll be flying to Norway to speak at NDC Oslo. MS Tech summit is a conference dedicated to Microsoft technology with 100+ speakers and 8 concurrent tracks. The conference is both Virtual and in person. &#8230; <a href="https://helpercode.com/2023/04/30/upcoming-speaking-engagements-may-2023/" class="more-link">Continue reading <span class="screen-reader-text">Upcoming speaking engagements &#8211; May 2023</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I have a couple of speaking opportunities starting next week with MS Tech Summit in Warsaw and later this month I&#8217;ll be flying to Norway to speak at NDC Oslo.</p>



<div class="wp-block-media-text is-stacked-on-mobile" style="grid-template-columns:36% auto"><figure class="wp-block-media-text__media"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1100" height="1100" data-attachment-id="3659" data-permalink="https://helpercode.com/2023/04/30/upcoming-speaking-engagements-may-2023/mstechsummit/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2023/04/mstechsummit.png?fit=1125%2C1125&amp;ssl=1" data-orig-size="1125,1125" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="mstechsummit" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2023/04/mstechsummit.png?fit=1024%2C1024&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2023/04/mstechsummit.png?resize=1100%2C1100&#038;ssl=1" alt="MS Tech Summit - Warsaw" class="wp-image-3659 size-full" /></figure><div class="wp-block-media-text__content">
<p class="wp-block-paragraph"><a href="https://mstechsummit.pl/en/">MS Tech summit</a> is a conference dedicated to Microsoft technology with 100+ speakers and 8 concurrent tracks. The conference is both Virtual and in person.</p>



<p class="wp-block-paragraph">In my talk I will show how to develop .NET applications using AWS services and C# and the tools and services .NET developer can use to run their code in the cloud.</p>



<p class="wp-block-paragraph">As a bonus there&#8217;s a 30% discount if you register before May 10th.</p>
</div></div>



<div class="wp-block-media-text is-stacked-on-mobile" style="grid-template-columns:35% auto"><figure class="wp-block-media-text__media"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1100" height="575" data-attachment-id="3663" data-permalink="https://helpercode.com/2023/04/30/upcoming-speaking-engagements-may-2023/cc7e722ac236afdd8ef12ff7b3a7ceb8520540be-2000x1046-1/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2023/04/cc7e722ac236afdd8ef12ff7b3a7ceb8520540be-2000x1046-1.png?fit=2000%2C1046&amp;ssl=1" data-orig-size="2000,1046" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="cc7e722ac236afdd8ef12ff7b3a7ceb8520540be-2000&amp;#215;1046-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2023/04/cc7e722ac236afdd8ef12ff7b3a7ceb8520540be-2000x1046-1.png?fit=1024%2C536&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2023/04/cc7e722ac236afdd8ef12ff7b3a7ceb8520540be-2000x1046-1.png?resize=1100%2C575&#038;ssl=1" alt="" class="wp-image-3663 size-full" /></figure><div class="wp-block-media-text__content">
<p class="wp-block-paragraph">If you haven&#8217;t heard about <a href="https://ndcoslo.com">NDC Oslo</a> &#8211; you should! It&#8217;s one of the leading software developer conference it&#8217;s a 5 day event with more than 180 sessions delivered by 165+ speakers many of which are leaders in their field.</p>



<p class="wp-block-paragraph">I will be speaking about how to <a href="https://ndcoslo.com/agenda/testing-strategy-for-your-aspnet-core-micro-service-0fat/070zcu714g7">plan and write automated tests for ASP.NET microservices</a>.</p>



<p class="wp-block-paragraph">I&#8217;ll talk about the different types of tests, how to write unit, integration and end to end tests for you microservices and how to test your applications running in your data center or in the cloud.</p>



<p class="wp-block-paragraph">When not presenting I plan to be at the AWS booth, answering questions on .NET and cloud computing.</p>
</div></div>



<p class="wp-block-paragraph">So there you have it, if you attend on of these conferences, stop by and say hello.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://helpercode.com/2023/04/30/upcoming-speaking-engagements-may-2023/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3656</post-id>	</item>
		<item>
		<title>Learning Rust one test at a time</title>
		<link>https://helpercode.com/2021/02/07/learning-rust-one-test-at-a-time/</link>
					<comments>https://helpercode.com/2021/02/07/learning-rust-one-test-at-a-time/#respond</comments>
		
		<dc:creator><![CDATA[Dror Helper]]></dc:creator>
		<pubDate>Sun, 07 Feb 2021 19:52:44 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://helpercode.com/?p=3049</guid>

					<description><![CDATA[My second job was a lot of fun, I was fresh out of university and I got to play with graphics and draw cool effects on the screen using DirectX and OpenGL. Since then, I have worked in many other companies and learnt how to write better code but I have always had a place &#8230; <a href="https://helpercode.com/2021/02/07/learning-rust-one-test-at-a-time/" class="more-link">Continue reading <span class="screen-reader-text">Learning Rust one test at a time</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">My second job was a lot of fun, I was fresh out of university and I got to play with graphics and draw cool effects on the screen using DirectX and OpenGL. </p>



<p class="wp-block-paragraph">Since then, I have worked in many other companies and learnt how to write better code but I have always had a place in my heart for using matrix transformations to render 3D worlds using colors, reflections, lighting and shadows. That&#8217;s why when I&#8217;ve saw a book titled: &#8220;<a href="http://raytracerchallenge.com/">The Ray Tracer Challenge</a>&#8221; I knew I had to get it. The book teaches how to build a 3D renderer form scratch &#8211; using test first (TDD/BDD) approach.</p>



<div class="wp-block-image is-style-default"><figure class="aligncenter size-medium"><img data-recalc-dims="1" loading="lazy" decoding="async" width="450" height="540" data-attachment-id="3055" data-permalink="https://helpercode.com/cover/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2021/02/cover.jpg?fit=450%2C540&amp;ssl=1" data-orig-size="450,540" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="cover" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2021/02/cover.jpg?fit=450%2C540&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2021/02/cover.jpg?resize=450%2C540&#038;ssl=1" alt="" class="wp-image-3055" /></figure></div>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Since it was a long time since I&#8217;ve learned a new programming language I&#8217;ve decided to use Rust to and so I&#8217;ll re-learn something old (3D graphics, lighting) and something new (Rust).</p>



<p class="wp-block-paragraph">I have been using <a href="https://www.jetbrains.com/help/clion/rust-support.html">JetBrains Rust plugin</a> (running inside CLion) and it has been easy to use, all of the refactoring options, hints and run configurations &#8211; just work and make writing Rust code a breeze.</p>



<p class="wp-block-paragraph">I have reached chapter 4 so far and have been fun learning a new language and getting thigs to appear on the screens (only dots so far &#8211; but I&#8217;m getting there), you can check my efforts <a href="https://github.com/dhelper/RustRayTracing">on GitHub</a>, I have been trying to find time each week to progress a but, unfortunately/luckily I have just committed myself to yet another project (I promise more details in a couple of months) so my Rust endeavor will suffer. I am, looking for feedback &#8211; it&#8217;s hard to tell how things supposed to be done when starting a new language, how to name your files &#8211; do you write all of the struct code in the same place, and so on. </p>



<h3 class="wp-block-heading">My experience with Rust </h3>



<p class="wp-block-paragraph">so far it seems that Rust is a highly opinionated language, I get warnings when I write the wrong casing for method names or name my files not according to the standards &#8211; and I like it, although I&#8217;m not sure what some developers would do if they cannot argue about the right place to put their curly brackets.</p>



<figure class="wp-block-image size-large is-style-default"><img data-recalc-dims="1" loading="lazy" decoding="async" width="640" height="360" data-attachment-id="3056" data-permalink="https://helpercode.com/tabs-vs-spaces-640x360-1/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2021/02/tabs-vs-spaces-640x360-1.jpg?fit=640%2C360&amp;ssl=1" data-orig-size="640,360" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="tabs-vs-spaces-640&amp;#215;360-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2021/02/tabs-vs-spaces-640x360-1.jpg?fit=640%2C360&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2021/02/tabs-vs-spaces-640x360-1.jpg?resize=640%2C360&#038;ssl=1" alt="" class="wp-image-3056" /></figure>



<p class="wp-block-paragraph">Other than that, I found Rust to be simple to use once you get how methods are declared, operators &#8220;overloaded&#8221; and forget all you ever knew about inheritance and method overloading and learn how to use (and not abuse) macros,  it&#8217;s a bit painful at first but then  things do become a little simpler.</p>



<p class="wp-block-paragraph">Rust is a safe programming language &#8211; just as advertised, it&#8217;s impossible to shoot yourself in the foot, in fact whenever you try Rust will explain why you&#8217;re an idiot and suggest what you should have done, that is one thing I wish more compilers will do, whenever I got a compilation error the compiler told me what I did wrong, and how I might correct it. It made learning Rust so simple, although I still get the nagging feeling that I&#8217;ve used &#8216;&amp;&#8217; incorrectly, but I get that in C++ from time to time, so I guess all is well. Writing code where everything is immutable as the default, cannot be null is so liberating and helps avoid writing those checks we &lt;insert language here) developers are so familiar with, and the rust compiler really makes an effort to help you, finding unused code or suggest a better way to initialize your variables.</p>



<p class="wp-block-paragraph">But there are a few downsides here, Rust is a relatively new language and some of the core libraries are still begin developed, some of the tools and frameworks are not there yet, for example the &#8220;unit testing framework&#8221; is a set of minimal macros and that&#8217;s it, and sometimes the type system feels too rigid &#8211; for example you decide on the size of an array when you write the code (otherwise use Vector) and in fact an array of 10 items is a type of its own which is a different type from an array of 5 items, it opens a few possibilities (as I discovered when creating matrices) but close a few others.</p>



<p class="wp-block-paragraph">All in all, I enjoy writing code in Rust, its quick and intuitive but different from my Day Job&#8217;s Java/C++/C# work.</p>



<h3 class="wp-block-heading">What I think about the book </h3>



<p class="wp-block-paragraph">Before I start talking about how much I like this book, a word of warning (or disclaimer if you will), if you intend to learn BDD or TDD from this book &#8211; walk away, this book does  not intend to teach you how to write good tests or even how to write tests at all, there are better books for that depending on your language of choice. </p>



<p class="wp-block-paragraph">In fact I find some of the tests to be &#8220;less than ideal&#8221; with strange inputs, multiple asserts, not covering all of the possible scenarios, writing more than one test before rushing to the implementation and other small sins in the Test first world &#8211; but that is <strong>not the point of this book</strong>.</p>



<p class="wp-block-paragraph">This book does something different, Instead of explaining about Points, vectors, matrices and lighting it helps you create working software, one test at a time, by writing the test then the implementation I find I understand better the concepts and code, and by the way, the book does not have code snippets &#8211; just pseudo code and <a href="https://en.wikipedia.org/wiki/Cucumber_(software)#Gherkin_language">Gherkin </a>like features/tests for you to write and implement.</p>



<p class="wp-block-paragraph">I really do like the book, it helps you write tedious code in an interesting way (I mean how interesting can multiplying a vector can be), and in the end of almost every chapter you get to use the code you&#8217;ve implemented to create a working piece of software and see the code you wrote run.</p>



<p class="wp-block-paragraph">And I do like this book, instead of just reading how things are done &#8211; you get to participate, in a well written, well thought of lesson, and have something to show for at the end.</p>



<p class="wp-block-paragraph">So, if you&#8217;re interested in 3D rendering or just want to learn something new &#8211; I highly recommend this book. Read it, write the tests and then the code, other than programming, no prior knowledge needed.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Happy Coding&#8230;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://helpercode.com/2021/02/07/learning-rust-one-test-at-a-time/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3049</post-id>	</item>
		<item>
		<title>Versioning Multiple Micro-Services in a Monorepo using Maven</title>
		<link>https://helpercode.com/2020/12/29/versioning-multiple-micro-services-in-a-monorepo-using-maven/</link>
					<comments>https://helpercode.com/2020/12/29/versioning-multiple-micro-services-in-a-monorepo-using-maven/#comments</comments>
		
		<dc:creator><![CDATA[Dror Helper]]></dc:creator>
		<pubDate>Tue, 29 Dec 2020 12:30:38 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Micro-Services]]></category>
		<guid isPermaLink="false">http://helpercode.com/?p=3010</guid>

					<description><![CDATA[It is crucial that each piece of code you deploy have a unique version, it help you you track what your client is running, mark deployments with breaking changes and make your life so much easier &#8211; especially when trying to understand what changes are running at your client site in the middle of the &#8230; <a href="https://helpercode.com/2020/12/29/versioning-multiple-micro-services-in-a-monorepo-using-maven/" class="more-link">Continue reading <span class="screen-reader-text">Versioning Multiple Micro-Services in a Monorepo using Maven</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">It is crucial that each piece of code you deploy have a unique version, it help you you track what your client is running, mark deployments with breaking changes and make your life so much easier &#8211; especially when trying to understand what changes are running at your client site in the middle of the night.</p>



<p class="wp-block-paragraph">When you develop micro services it it twice as important, usually you deploy your services individually and you need to know which version of which dependency is used by your service. Another requirement many developer face is how to automatically (or manually) update your dependencies when they change.</p>



<p class="wp-block-paragraph">At one of my client&#8217;s projects we had a single repository with all of the services, which were built and deployed individually, as part of our continuous integration and deployment we&#8217;ve wanted to build only the services that were either changed or one of it&#8217;s dependencies has changed. I&#8217;ve also wanted to make sure that it&#8217;s easy to add new services to our system.</p>



<p class="wp-block-paragraph">Then I found about the <a rel="noreferrer noopener" href="http://www.mojohaus.org/versions-maven-plugin/" target="_blank">Versions Maven Plugin</a> which can be used to automatically update versions to your maven projects and it automatically make sure to update all the other projects that dependent on it. </p>



<p class="wp-block-paragraph">In my example project (<a rel="noreferrer noopener" href="https://github.com/dhelper/spring-versioning" target="_blank">source in GitHub</a>) I have three services. Each service has a server and contract projects and <em>service2 </em>depends on <em>service1 </em>contracts and <em>services3 </em>depends on both <em>service1 </em>and <em>service2</em>.</p>



<p class="wp-block-paragraph">Each service has a folder with it&#8217;s own pom file with sub folder for each sub-service.</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="610" height="1331" data-attachment-id="3015" data-permalink="https://helpercode.com/image-6/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/12/image.png?fit=610%2C1331&amp;ssl=1" data-orig-size="610,1331" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/12/image.png?fit=469%2C1024&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/12/image.png?resize=610%2C1331&#038;ssl=1" alt="" class="wp-image-3015" /></figure>



<p class="wp-block-paragraph">I&#8217;ve needed a central place to manage all of services versions so I&#8217;ve added the following to the main (aggregator) pom.xml:</p>



<pre class="wp-block-syntaxhighlighter-code">&lt;properties&gt;
    . . .

    &lt;!-- Versions --&gt;
    &lt;service1.version&gt;1.1-SNAPSHOT&lt;/service1.version&gt;
    &lt;service2.version&gt;2.1-SNAPSHOT&lt;/service2.version&gt;
    &lt;service3.version&gt;3.1-SNAPSHOT&lt;/service3.version&gt;</pre>



<p class="wp-block-paragraph">I&#8217;ve wanted to automatically update the versions in the service pom.xml file when a service versions changes so I&#8217;ve added the following in the aggregator pom.xml:</p>



<pre class="wp-block-syntaxhighlighter-code">&lt;properties&gt;
    . . .
    
    &lt;!-- auto version related --&gt;
    &lt;service.version&gt;0&lt;/service.version&gt;
    &lt;version.update.enable&gt;generate-sources&lt;/version.update.enable&gt;
    &lt;version.phase&gt;none&lt;/version.phase&gt;
    &lt;service.name&gt;-invalid-&lt;/service.name&gt;    
    . . .

&lt;/properties&gt;
&lt;build&gt;
    &lt;plugins&gt;
        &lt;plugin&gt;
            &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
            &lt;artifactId&gt;versions-maven-plugin&lt;/artifactId&gt;
            &lt;version&gt;2.7&lt;/version&gt;
            &lt;executions&gt;
                &lt;execution&gt;
                    &lt;phase&gt;${version.phase}&lt;/phase&gt;
                    &lt;goals&gt;
                        &lt;goal&gt;set&lt;/goal&gt;
                    &lt;/goals&gt;
                    &lt;id&gt;update-version&lt;/id&gt;
                    &lt;configuration&gt;
                        &lt;generateBackupPoms&gt;false&lt;/generateBackupPoms&gt;
                        &lt;artifactId&gt;${service.name}*&lt;/artifactId&gt;
                        &lt;newVersion&gt;${service.version}&lt;/newVersion&gt;
                    &lt;/configuration&gt;
                &lt;/execution&gt;
            &lt;/executions&gt;
        &lt;/plugin&gt;
    &lt;/plugins&gt;
&lt;/build&gt;</pre>



<p class="wp-block-paragraph">I&#8217;ve added three new properties that would be set from each individual service:</p>



<ul class="wp-block-list"><li>version.phase &#8211; this is when the versioning plugin would run, I needed it to run before compilation so I&#8217;ve defined a new property called <em>version.update.enable </em>with the correct version phase. The default is set to a non existent phase so that the versioning would only run for the services I need them to run. </li><li>service.name &#8211; the service artifact name, for service1 it would be service1, I&#8217;ve used <em>${service.name}* </em>because I&#8217;ve wanted all of the sub-projects (.server and .contracts) to have the same version.</li><li>service.version &#8211; here I&#8217;ll set the service version, I&#8217;ve done a trick here, as you&#8217;ll see in a minute.</li></ul>



<p class="wp-block-paragraph">Now in each service (service1\pom.xml) we have to add the following lines:</p>



<pre class="wp-block-syntaxhighlighter-code">&lt;properties&gt;
    &lt;service.name&gt;service1&lt;/service.name&gt;
    &lt;version.phase&gt;${version.update.enable}&lt;/version.phase&gt;
    &lt;service.version&gt;${service1.version}&lt;/service.version&gt;
&lt;/properties&gt;</pre>



<p class="wp-block-paragraph">Now each service defines it&#8217;s name (same as directory), set the <em>version.phase </em>using <em>version.update.enable </em>(which is set to <em>generate-sources</em>) and set the value of the version to the property defined in the root&#8217;s pom.xml.</p>



<p class="wp-block-paragraph">Now if you update the version run <em><strong>mvn compile </strong></em>the version will be updated automatically:</p>



<figure class="wp-block-image size-large is-style-default"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1100" height="1081" data-attachment-id="3027" data-permalink="https://helpercode.com/image-2-3/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/12/image-2.png?fit=1526%2C1500&amp;ssl=1" data-orig-size="1526,1500" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image-2" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/12/image-2.png?fit=1024%2C1007&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/12/image-2.png?resize=1100%2C1081&#038;ssl=1" alt="" class="wp-image-3027" /></figure>



<p class="wp-block-paragraph">Using this method we were able add versioning to all of our existing microservices and create new services easily &#8211; and it worked like a charm.</p>



<p class="wp-block-paragraph">So there you have it, automatic version update for all dependent versions with a single update, which cause all of the effected services to be built once committed.</p>



<p class="wp-block-paragraph">Happy coding&#8230;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://helpercode.com/2020/12/29/versioning-multiple-micro-services-in-a-monorepo-using-maven/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3010</post-id>	</item>
		<item>
		<title>New Pluralsight course &#8211; Unit Testing C Code in CLion</title>
		<link>https://helpercode.com/2020/12/07/new-pluralsight-course-unit-testing-c-code-in-clion/</link>
					<comments>https://helpercode.com/2020/12/07/new-pluralsight-course-unit-testing-c-code-in-clion/#comments</comments>
		
		<dc:creator><![CDATA[Dror Helper]]></dc:creator>
		<pubDate>Mon, 07 Dec 2020 21:18:30 +0000</pubDate>
				<category><![CDATA[Online Course]]></category>
		<category><![CDATA[Boost.Test]]></category>
		<category><![CDATA[CATCH]]></category>
		<category><![CDATA[CLion]]></category>
		<category><![CDATA[DocTest]]></category>
		<category><![CDATA[GTest]]></category>
		<category><![CDATA[PluralSight]]></category>
		<category><![CDATA[Unit tests]]></category>
		<guid isPermaLink="false">http://helpercode.com/?p=2986</guid>

					<description><![CDATA[From time to time I get the feeling that I have too much free time and so I set myself and look for new challenges, and although the last year has been challenging to all of us I&#8217;ve still found myself committed to create another unit testing course for Pluralsight. This time it&#8217;s unit testing &#8230; <a href="https://helpercode.com/2020/12/07/new-pluralsight-course-unit-testing-c-code-in-clion/" class="more-link">Continue reading <span class="screen-reader-text">New Pluralsight course &#8211; Unit Testing C Code in CLion</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">From time to time I get the feeling that I have too much free time and so I set myself and look for new challenges, and although the last year has been challenging to all of us I&#8217;ve still found myself committed to create another unit testing course for Pluralsight.</p>



<p class="wp-block-paragraph">This time it&#8217;s unit testing in C using <a href="https://www.jetbrains.com/clion/">JetBrains excellent CLion IDE</a>. I did not know what to expect from unit testing in C course but once I&#8217;ve started recording I found myself adding more and more content until by the end of it I&#8217;ve found that on top of covering unit testing and CLion integration, I&#8217;ve also found time (late at night) to add a quick introduction in mocking methods in C.</p>



<p class="wp-block-paragraph">If you&#8217;ve been wondering how to test your C code or interested on learning more about what CLion can do for you &#8211; check out my <a href="https://app.pluralsight.com/library/courses/unit-testing-c-code-clion/table-of-contents">Unit Testing C Code in CLion</a> course.</p>



<p class="wp-block-paragraph">I have been tiring especially with schools closing then opening (and closing again) and on top of that finding the time and place to record has been a bigger challenge than it used to be, since most of my family has been home most of the time. But it&#8217;s done now and now I get to rest &#8211; at least for a couple of days.</p>



<p class="wp-block-paragraph">The good news &#8211; now I hope to find more time to blog, I have quite a few posts I&#8217;ve been meaning to write but just could not find the time.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Until then &#8211; happy coding&#8230;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://helpercode.com/2020/12/07/new-pluralsight-course-unit-testing-c-code-in-clion/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2986</post-id>	</item>
		<item>
		<title>Easily create builders for your tests using Intellij IDEA</title>
		<link>https://helpercode.com/2020/10/26/easily-create-builders-for-your-tests-using-intellij-idea/</link>
					<comments>https://helpercode.com/2020/10/26/easily-create-builders-for-your-tests-using-intellij-idea/#respond</comments>
		
		<dc:creator><![CDATA[Dror Helper]]></dc:creator>
		<pubDate>Mon, 26 Oct 2020 11:42:59 +0000</pubDate>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[Unit Testing Tips]]></category>
		<category><![CDATA[Intellij]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JUnit]]></category>
		<category><![CDATA[Unit tests]]></category>
		<guid isPermaLink="false">http://helpercode.com/?p=2957</guid>

					<description><![CDATA[The builder pattern is one of the more useful patterns out there when creation unit tests. Instead of having a huge initialization such as: You can instead create a simple user builder object for your tests that would initialize all of the object&#8217;s properties with default values (not empty) &#8211; since you do not really &#8230; <a href="https://helpercode.com/2020/10/26/easily-create-builders-for-your-tests-using-intellij-idea/" class="more-link">Continue reading <span class="screen-reader-text">Easily create builders for your tests using Intellij IDEA</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">The builder pattern is one of the more useful patterns out there when creation unit tests.</p>



<p class="wp-block-paragraph">Instead of having a huge initialization such as:</p>



<pre class="wp-block-syntaxhighlighter-code">@Test
void validateUser_userNameIsEmpty_returnFalse(){
    var user = new User();
    user.setId("id-1");
    user.setName(null);
    user.setPhoneNumber("555-1234");
    // additional user initialization

   boolean result = userService.validate(user);

   assertFalse(result);
}</pre>



<p class="wp-block-paragraph">You can instead create a simple user builder object for your tests that would initialize all of the object&#8217;s properties with default values (not empty) &#8211; since you do not really care what the values are as long as they are valid and write the following test:</p>



<pre class="wp-block-syntaxhighlighter-code">@Test
void validateUser_userNameIsEmpty_returnFalse(){
    var user = new UserBuilder()
                      .withName(null)
                      .build();

   boolean result = userService.validate(user);

   assertFalse(result);
}</pre>



<p class="wp-block-paragraph">It helps you reduce the test code avoid duplication and if the user&#8217;s class changes in some way you do not need to fix 100+ tests. But the real benefit is that using builders in your tests is that they help to focus the test reader on what&#8217;s important in this test. This is very important because the test reader might be you trying to understand why a test you wrote three months ago started failing at 8pm on the day before a major release.</p>



<pre class="wp-block-verse">If you want to learn more about object initialization you can check my post on the subject: "<a rel="noreferrer noopener" href="https://helpercode.com/2013/12/22/on-object-creation-and-unit-tests/" target="_blank">On object creation and unit tests</a>"</pre>



<h2 class="wp-block-heading">The problem with builders</h2>



<p class="wp-block-paragraph">But it&#8217;s not all rainbows and sunshine when creation builders for your tests, it is also a painful experience, you need to create a new class, then add all of the values you need to set in that object, implement setter methods and build method and it&#8217;s not a fun experience which has caused me more often than not to avoid creationg builders until my test code has become too painful to maintain.</p>



<p class="wp-block-paragraph">But that was in the past, since I found a cool new feature in Intellij, I found out that when I create setters for a class using code generation I can choose those setters to use the builder template.</p>



<p class="wp-block-paragraph">Now creating builders for my tests is easy:</p>



<ol class="wp-block-list"><li>Create a new builder class</li><li>Copy the fields you need from the original class</li><li>Set default values for all fields</li><li>Create a <strong>build </strong>function using a constructor &#8211; or if you must setter methods </li><li>Generate all of the setter methods as build methods with a click of your keyboard (alt+insert)</li><li>Write tests using your new and shiny class.</li></ol>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="640" height="916" data-attachment-id="2965" data-permalink="https://helpercode.com/createbuilder/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/10/createbuilder.gif?fit=640%2C916&amp;ssl=1" data-orig-size="640,916" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="createbuilder" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/10/createbuilder.gif?fit=640%2C916&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/10/createbuilder.gif?resize=640%2C916&#038;ssl=1" alt="" class="wp-image-2965" /></figure>



<p class="wp-block-paragraph">Quick and simple, and relatively painless. </p>



<p class="wp-block-paragraph">If you&#8217;re a .NET developer (I know I am) you might be wondering if the same feature exist in R# and/or Visual Studio (I know I did). Unfortunately it does not I guess it&#8217;s because it was never requested and properties in .NET are implemented differently. I guess you&#8217;ll have to ask JetBrains to add this feature or create your own code template.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">And until Then&#8230; Stay healthy and happy coding&#8230;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://helpercode.com/2020/10/26/easily-create-builders-for-your-tests-using-intellij-idea/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2957</post-id>	</item>
		<item>
		<title>Better tests names using JUnit&#8217;s display names generators</title>
		<link>https://helpercode.com/2020/08/27/better-tests-names-using-junits-display-names-generators/</link>
					<comments>https://helpercode.com/2020/08/27/better-tests-names-using-junits-display-names-generators/#comments</comments>
		
		<dc:creator><![CDATA[Dror Helper]]></dc:creator>
		<pubDate>Thu, 27 Aug 2020 08:57:59 +0000</pubDate>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[JUnit]]></category>
		<category><![CDATA[Unit tests]]></category>
		<guid isPermaLink="false">http://helpercode.com/?p=2895</guid>

					<description><![CDATA[Writing unit tests can be challenging, but there is one thing that can get you on the right track &#8211; the test name. If you manage to give your test a good name &#8211; you will write a good test. Unfortunately in some (read: many) unit testing frameworks the test name must be a valid &#8230; <a href="https://helpercode.com/2020/08/27/better-tests-names-using-junits-display-names-generators/" class="more-link">Continue reading <span class="screen-reader-text">Better tests names using JUnit&#8217;s display names generators</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Writing unit tests can be challenging, but there is one thing that can get you on the right track &#8211; <strong>the test name</strong>. </p>



<p class="wp-block-paragraph">If you manage to give your test a good name &#8211; you will write a good test. </p>



<p class="wp-block-paragraph">Unfortunately in some (<em>read: many</em>) unit testing frameworks the test name must be a valid method name &#8211; because those &#8220;unit tests&#8221; are actually functions inside a class and so they looks something like this:</p>



<pre class="wp-block-syntaxhighlighter-code">public class CalculatorTests {

    @Test
    void add_passTwoPositiveNumbers_returnSum() {
        Calculator calculator = new Calculator();

        int result = calculator.add(2, 3);

        assertEquals(5, result);
    }
}</pre>



<h2 class="wp-block-heading">Test Names</h2>



<p class="wp-block-paragraph">In my tests I&#8217;ve been using the naming scheme created by <a href="https://osherove.com/blog/2005/4/3/naming-standards-for-unit-tests.html">Roy Osherove</a>. It forces you to think about the test before you write it and keep you from writing horrible unit tests.</p>



<p class="wp-block-paragraph">The test names are built from three parts:</p>



<ol class="wp-block-list"><li>The <strong>method </strong>running the test &#8211; this is the play button that would be used to execute the &#8220;experiment&#8221;</li><li>The <strong>scenario </strong>we test &#8211; what is the system state before running the method, what input is used during the test &#8211; in other words <em>&#8220;what makes this test different from any other test ever written&#8221;.</em></li><li>The <strong>expected result</strong> &#8211; what we expect to happen when we run the method (1) with the specific state (2) .</li></ol>



<p class="wp-block-paragraph">The good thing about using structured test names is that when a test fails we understand immediatly what went wrong. Test names tells use what we&#8217;re testing and what we expect to happen and together with the error message (from an assertion) we should quickly understand what went wrong, fix it and have the code back to running smoothly in no time.</p>



<h2 class="wp-block-heading">However &#8211; there is a problem</h2>



<p class="wp-block-paragraph">JUnit and it&#8217;s successor xUnit testing frameworks use methods and classes to host the &#8220;tests&#8221; and so the test &#8220;name&#8221; must be a valid function name, and so I find myself using underscores and camel-case/pascal-case to help the reader of the method locate and understand the words I&#8217;m using.</p>



<p class="wp-block-paragraph">It seems that in 2020 we&#8217;re still haven&#8217;t grasp the idea that test names <strong>do not have to be method names</strong> at least not in mainstream unit testing frameworks. I know some unit testing frameworks enable writing text as the test names but usually when I get to a company the are using one of the popular  unit testing framework which does not).</p>



<h2 class="wp-block-heading">The JUnit5 solution &#8211; test name generators</h2>



<p class="wp-block-paragraph">JUnit5 did try and solve this issue, by adding thee ability to mark your test with a test name generator:</p>



<pre class="wp-block-syntaxhighlighter-code">@DisplayNameGeneration(TestNameGenerator.class)
public class CalculatorTests {

    @Test
    void add_passTwoPositiveNumbers_returnSum() {
        Calculator calculator = new Calculator();

        int result = calculator.add(2, 3);

        assertEquals(5, result);
    }</pre>



<p class="wp-block-paragraph">The display name generators can be one of the pre-packaged name generators such as DisplayNameGenerator.ReplaceUnderscores that will automatically replace the underscores in you test names with spaces or you can write your own by extending one of the <em>DisplayNameGenerator </em>classes<em> </em>or by implementing <em>DisplayNameGenerator </em>interface.</p>



<p class="wp-block-paragraph">Then you can either use the <em>@DisplayNameGenerator</em> annotation on your test classes or methods or you can create <em>junit-platform.properties </em>file and add the line:</p>



<pre class="wp-block-preformatted">junit.jupiter.displayname.generator.default = &lt;your DN generator&gt;</pre>



<h2 class="wp-block-heading">My solution</h2>



<p class="wp-block-paragraph">I&#8217;ve wanted to split the test names into the three parts and then add brackets around the method tested and have a test name that looks: (<em><strong>method</strong></em>):  <em><strong>scenario</strong></em> -&gt; <em><strong>expected result</strong></em> and so I wrote the following code:</p>



<pre class="wp-block-syntaxhighlighter-code">public class TestNameGenerator extends DisplayNameGenerator.Standard {
    private String splitToParts(String input) {
        try {
            List&lt;String&gt; stringParts = getTestNameParts(input);

            if (stringParts.size() == 1) {
                return input;
            }

            if (stringParts.size() == 2) {
                return String.format("(%s): Always %s", stringParts.get(0), stringParts.get(1));
            }

            if (stringParts.size() == 3) {
                return String.format("(%s): %s -&gt; %s", stringParts.get(0), stringParts.get(1), stringParts.get(2));
            }

        } catch (Exception exc) {
            System.console().writer().println("Failed parsing test name");
        }

        return input;
    }

    private List&lt;String&gt; getTestNameParts(String input) {
        List&lt;String&gt; stringParts = new ArrayList&lt;&gt;();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i &lt; input.length(); ++i) {
            char ch = input.charAt(i);
            if (ch == '(') {
                break;
            }
            if (ch == '_') {
                stringParts.add(sb.toString());
                sb.setLength(0);
            } else if (Character.isUpperCase(ch) &amp;&amp; stringParts.size() &gt; 0) {
                if (sb.length() &gt; 0) {
                    sb.append(" ");
                }
                sb.append(Character.toLowerCase(ch));
            } else {
                sb.append(ch);
            }
        }

        stringParts.add(sb.toString());
        return stringParts;
    }

    @Override
    public String generateDisplayNameForMethod(Class&lt;?&gt; testClass, Method testMethod) {
        return splitToParts(
                super.generateDisplayNameForMethod(testClass, testMethod)
        );
    }
}</pre>



<p class="wp-block-paragraph">It&#8217;s quite a lot but it&#8217;s basically replacing underscores (&#8216;_&#8217;) with spaces (&#8216; &#8216;) and splitting to words based on upper case letters and also I&#8217;ve wanted to handle cases in which there are two parts to the test name. </p>



<p class="wp-block-paragraph">Now when I run the tests I see the following results:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1100" height="533" data-attachment-id="2921" data-permalink="https://helpercode.com/image-5/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/image-5.png?fit=1834%2C888&amp;ssl=1" data-orig-size="1834,888" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image-5" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/image-5.png?fit=1024%2C496&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/image-5.png?resize=1100%2C533&#038;ssl=1" alt="" class="wp-image-2921" /></figure>



<p class="wp-block-paragraph">Which is exactly what I want, having readable test names helps me write better test names, it&#8217;s hard to hide when it&#8217;s written in pain English and writing good test names helps me write better tests &#8211; but we&#8217;ve already covered that <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Happy coding&#8230; </p>
]]></content:encoded>
					
					<wfw:commentRss>https://helpercode.com/2020/08/27/better-tests-names-using-junits-display-names-generators/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2895</post-id>	</item>
		<item>
		<title>I&#8217;m an AWS Solution Architect &#8211; Professional</title>
		<link>https://helpercode.com/2020/08/23/im-an-aws-solution-architect-professional/</link>
					<comments>https://helpercode.com/2020/08/23/im-an-aws-solution-architect-professional/#respond</comments>
		
		<dc:creator><![CDATA[Dror Helper]]></dc:creator>
		<pubDate>Sun, 23 Aug 2020 13:33:08 +0000</pubDate>
				<category><![CDATA[AboutMe]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Certifications]]></category>
		<guid isPermaLink="false">http://helpercode.com/?p=2907</guid>

					<description><![CDATA[It has been three years (and a few month) since I&#8217;ve passed the AWS Solution Architect Associate exam and I was thinking about taking my knowledge (and certification) to the next level. And so last Thursday I&#8217;ve spent three and a half hours answering questions about everything AWS and passed the AWS Solution Architect Professional &#8230; <a href="https://helpercode.com/2020/08/23/im-an-aws-solution-architect-professional/" class="more-link">Continue reading <span class="screen-reader-text">I&#8217;m an AWS Solution Architect &#8211; Professional</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">It has been three years (and a few month) since I&#8217;ve passed the AWS Solution Architect Associate exam and I was thinking about taking my knowledge (and certification) to the next level.  And so last Thursday I&#8217;ve spent three and a half hours answering questions about everything AWS and passed the AWS <strong>Solution Architect Professional</strong> exam.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="240" height="240" data-attachment-id="2903" data-permalink="https://helpercode.com/aws-certified-solutions-architect-professional/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/aws-certified-solutions-architect-professional.png?fit=240%2C240&amp;ssl=1" data-orig-size="240,240" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="aws-certified-solutions-architect-professional" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/aws-certified-solutions-architect-professional.png?fit=240%2C240&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/aws-certified-solutions-architect-professional.png?resize=240%2C240&#038;ssl=1" alt="" class="wp-image-2903" /></figure></div>



<p class="wp-block-paragraph">I was not easy, it took my all of my AWS experience as well as studying every day (and night) &#8211; but I got there.</p>



<p class="wp-block-paragraph">What&#8217;s now? not sure, I&#8217;m going to relax a bit, keep writing software and blogging (obviously).</p>



<p class="wp-block-paragraph">And maybe once the current crisis will be over I&#8217;ll start talking at conferences again.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Until then &#8211; happy coding&#8230;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://helpercode.com/2020/08/23/im-an-aws-solution-architect-professional/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2907</post-id>	</item>
		<item>
		<title>Creating an .NET AWS serverless application using API Gateway with API Key</title>
		<link>https://helpercode.com/2020/08/03/creating-an-net-aws-serverless-application-using-api-gateway-with-api-key/</link>
					<comments>https://helpercode.com/2020/08/03/creating-an-net-aws-serverless-application-using-api-gateway-with-api-key/#comments</comments>
		
		<dc:creator><![CDATA[Dror Helper]]></dc:creator>
		<pubDate>Mon, 03 Aug 2020 18:12:00 +0000</pubDate>
				<category><![CDATA[TheCloud]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[API Gateway]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[AWS Lambda]]></category>
		<category><![CDATA[AWS SAM]]></category>
		<guid isPermaLink="false">http://helpercode.com/?p=2871</guid>

					<description><![CDATA[Today at work I&#8217;ve needed to create a quick solution to provide a client application with data stored in AWS. It has been a while since the last time I&#8217;ve used C# in AWS so I thought I&#8217;ll give it a try, and after a few hours of tinkering I had a solution up and &#8230; <a href="https://helpercode.com/2020/08/03/creating-an-net-aws-serverless-application-using-api-gateway-with-api-key/" class="more-link">Continue reading <span class="screen-reader-text">Creating an .NET AWS serverless application using API Gateway with API Key</span> <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Today at work I&#8217;ve needed to create a quick solution to provide a client application with data stored in AWS. It has been a while since the last time I&#8217;ve used C# in AWS so I thought I&#8217;ll give it a try, and after a few hours of tinkering I had a solution up and running, ready for integration with the client API.</p>



<h3 class="wp-block-heading">Ingredients</h3>



<ul class="wp-block-list"><li>You&#8217;ll need to have a valid AWS account, if you never, ever used AWS you can sign up for the free tier.</li><li><a rel="noreferrer noopener" href="https://visualstudio.microsoft.com/vs/community/" target="_blank">Visual Studio Community Edition &#8211; preferably 2019</a> (the current latest and greatest)</li><li>Install <a rel="noreferrer noopener" href="https://marketplace.visualstudio.com/items?itemName=AmazonWebServices.AWSToolkitforVisualStudio2017" target="_blank">AWS Toolkit for Visual Studio</a></li></ul>



<p class="wp-block-paragraph">Once you have everything installed you get to the fun part where we get to do stuff.</p>



<h3 class="wp-block-heading">Creating the initial code</h3>



<p class="wp-block-paragraph">This is simpler than you think:</p>



<p class="wp-block-paragraph">Step 1 &#8211; Open Visual Studio<br>Step 2 &#8211; create a new project<br>Step 3 &#8211; Choose a serverless application of a language of your choosing (C# of course)</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="900" height="624" data-attachment-id="2875" data-permalink="https://helpercode.com/image-1-2/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/image-1.png?fit=900%2C624&amp;ssl=1" data-orig-size="900,624" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/image-1.png?fit=900%2C624&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/image-1.png?resize=900%2C624&#038;ssl=1" alt="" class="wp-image-2875" /></figure>



<p class="wp-block-paragraph">Step 4 &#8211; fill project name, folder etc.<br>Step 5 &#8211; choose as blueprint, those are great starting points that will help you get up and running. </p>



<figure class="wp-block-image size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2876" data-permalink="https://helpercode.com/image-2-2/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/image-2.png?fit=838%2C572&amp;ssl=1" data-orig-size="838,572" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image-2" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/image-2.png?fit=838%2C572&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/image-2.png?resize=783%2C534&#038;ssl=1" alt="" class="wp-image-2876" width="783" height="534" /><figcaption>I&#8217;ve chosen the <em>ASP.NET Core Web A</em>PI blueprint hoping for the best, and I was not disappointed.</figcaption></figure>



<p class="wp-block-paragraph">At this point you will have code that looks familiar to anyone who ever wrote an ASP.NET Core API project in the past but it would run as a Lambda function behind API Gateway: </p>



<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="300" height="383" data-attachment-id="2879" data-permalink="https://helpercode.com/2020/08/03/creating-an-net-aws-serverless-application-using-api-gateway-with-api-key/capture/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/capture.png?fit=300%2C383&amp;ssl=1" data-orig-size="300,383" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Capture" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/capture.png?fit=300%2C383&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/capture.png?resize=300%2C383&#038;ssl=1" alt="" class="wp-image-2879" /></figure>



<p class="wp-block-paragraph">There&#8217;s quite a lot there both good examples on how to use Rest API by adding Controller and logic that would enable running the Lambda&#8217;s code locally (under IIS), but for the purpose of this post I&#8217;d like to focus on <em><strong>serverless.template</strong> </em>file.</p>



<h3 class="wp-block-heading">Infrastructure as code using <em>serverless.template</em></h3>



<p class="wp-block-paragraph">There are a few ways to define your resources as script/code, one of those is <a href="https://aws.amazon.com/cloudformation/">AWS CloudFormation</a> which let you define your functions, buckets and other resources using &#8220;easy&#8221; to read and quite-confusing-to-write syntax. There are better ways to author Cloud Formation templates such as <a href="https://aws.amazon.com/cdk/">AWS-CDK</a> or in this case <a href="https://aws.amazon.com/serverless/sam/">AWS SAM</a> (Serverless Application Model).</p>



<p class="wp-block-paragraph">SAM is built on top of Cloud Formation with Lambda based applications in mind and the initial template looks something like this:</p>



<pre class="wp-block-syntaxhighlighter-code">...
"Resources": {
    "AspNetCoreFunction": {
      "Type": "AWS::Serverless::Function",
      "Properties": {
        "Handler": "AWSServerless2::AWSServerless2.LambdaEntryPoint::FunctionHandlerAsync",
        "Runtime": "dotnetcore3.1",
        "CodeUri": "",
        "MemorySize": 256,
        "Timeout": 30,
        "Role": null,
        "Policies": [
          "AWSLambdaFullAccess"
        ],
        "Environment": {
          "Variables": {
            "AppS3Bucket": {...}
          }
        },
        "Events": {
          "ProxyResource": {
            "Type": "Api",
            "Properties": {
              "Path": "/{proxy+}",
              "Method": "ANY"
            }
          },
          "RootResource": {
            "Type": "Api",
            "Properties": {
              "Path": "/",
              "Method": "ANY"
            }
          }
        }
      }
    },
    "Bucket": {...}
    }
  },</pre>



<p class="wp-block-paragraph">After running the wizard we&#8217;ll end up with a Lambda function, and a Bucket (which we won&#8217;t talk about today).</p>



<p class="wp-block-paragraph">The Lambda function defines the API gateway&#8217;s paths, see the path defined as <strong>/{proxy+}</strong>? this means that calls arriving to the API gateway will be forwarded to the Lambda functions to be handled by our Controller(s). </p>



<p class="wp-block-paragraph">Right now, you can update the code and deploy the newly created Lambda from Visual Studio. I could do that and call it a day, but in my case I&#8217;ve needed to add API key to my API gateway&#8230;</p>



<h3 class="wp-block-heading">Tweaking the solution &#8211; adding API Keys</h3>



<p class="wp-block-paragraph">In order to use API key, we need to define a <em>usage plan</em> and update the Lambda/API Gateway definitions.</p>



<p class="wp-block-paragraph">First, we&#8217;ll start by defining the API Gateway&#8217;s properties, it was hidden in the background until now but now we&#8217;ll need to explicitly define it under <em>Resources</em>:</p>



<pre class="wp-block-syntaxhighlighter-code">"ApiGatewayApi": {
    "Type": "AWS::Serverless::Api",
    "Properties": {
        "StageName": "Prod",
        "Auth": {
            "ApiKeyRequired": "true"
        }
    }
}</pre>



<ul class="wp-block-list"><li>We needed to add this definition to add<em> &#8220;ApiKeyRequired&#8221;: &#8220;true&#8221;</em></li></ul>



<p class="wp-block-paragraph">Now we&#8217;ll need to update the Lambda <em>Events</em> to use the new API Gateway definitions:</p>



<pre class="wp-block-syntaxhighlighter-code">"AspNetCoreFunction": {
    "Type": "AWS::Serverless::Function",
    "Properties": {
        ...
      "Events": {
            "ProxyResource": {
                "Type": "Api",
                "Properties": {
                    "Path": "/{proxy+}",
                    "Method": "ANY",
                    "RestApiId": {
                        "Ref": "ApiGatewayApi"
                    }
                }
            },
            "RootResource": {
                "Type": "Api",
                "Properties": {
                    "Path": "/",
                    "Method": "ANY",
                    "RestApiId": {
                        "Ref": "ApiGatewayApi"
                    }
                }
            }
        }
    }
},</pre>



<ul class="wp-block-list"><li>We&#8217;ve used <em>RestApiId</em> to create a connection between the new API Gateway definition and the Lambda Endpoint.</li></ul>



<p class="wp-block-paragraph">And Finally define the new <em>API key</em>, usage plan and connect the two:</p>



<pre class="wp-block-syntaxhighlighter-code">"ApiUsagePlan": {
    "Type": "AWS::ApiGateway::UsagePlan",
    "Properties": {
        "ApiStages": [
            {
                "ApiId": {
                    "Ref": "ApiGatewayApi"
                },
                "Stage": "Prod"
            }
        ],
        "Throttle": {
            "BurstLimit": 200,
            "RateLimit": 100
        }
    }
},
"ApiUsagePlanKey": {
    "Type": "AWS::ApiGateway::UsagePlanKey",
    "Properties": {
        "KeyId": {
            "Ref": "ApiKey"
        },
        "KeyType": "API_KEY",
        "UsagePlanId": {
            "Ref": "ApiUsagePlan"
        }
    }
},
"ApiKey": {
    "Type": "AWS::ApiGateway::ApiKey",
    "Properties": {
        "Name": "my-api-key-name",
        "Enabled": "true",
        "StageKeys": [
            {
                "RestApiId": {
                    "Ref": "ApiGatewayApi"
                },
                "StageName": "Prod"
            }
        ]
    }
}</pre>



<p class="wp-block-paragraph">And we&#8217;re done, if you deploy the Lambda using the new SAM definitions you&#8217;ll have an Lambda behind an API Gateway, protected by a key which you need to pass in each message in the header (x-api-key). You can open your AWS console, navigate to your region of choice, and find the API key in the API Gateway page and then send that API key to the client and you&#8217;re done.</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1100" height="978" data-attachment-id="2886" data-permalink="https://helpercode.com/image-4/" data-orig-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/image-4.png?fit=1713%2C1523&amp;ssl=1" data-orig-size="1713,1523" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image-4" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/image-4.png?fit=1024%2C910&amp;ssl=1" src="https://i0.wp.com/helpercode.com/wp-content/uploads/2020/08/image-4.png?resize=1100%2C978&#038;ssl=1" alt="" class="wp-image-2886" /></figure>



<p class="wp-block-paragraph">Obviously, you&#8217;ll need to add authentication/authorization but that&#8217;s a story for a different time&#8230;</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">And until then &#8211; happy coding&#8230;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://helpercode.com/2020/08/03/creating-an-net-aws-serverless-application-using-api-gateway-with-api-key/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2871</post-id>	</item>
	</channel>
</rss>