<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="http://feeds.feedblitz.com/feedblitz_rss.xslt"?>
<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/"
	 xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
<channel>
	<title>Petri Kainulainen</title>
	<atom:link href="https://www.petrikainulainen.net/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.petrikainulainen.net/</link>
	<description>Developing Software With Passion</description>
	<lastBuildDate>Fri, 15 May 2026 09:54:01 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
<meta xmlns="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
<item>
<feedburner:origLink>https://www.petrikainulainen.net/programming/unit-testing/getting-started-with-mockk-the-setup/</feedburner:origLink>
		<title>Getting Started With MockK: The Setup</title>
		<link>https://feeds.feedblitz.com/~/956061056/0/petrikainulainen~Getting-Started-With-MockK-The-Setup/</link>
					<comments>https://feeds.feedblitz.com/~/956061056/0/petrikainulainen~Getting-Started-With-MockK-The-Setup/#respond</comments>
		
		<dc:creator><![CDATA[Petri Kainulainen]]></dc:creator>
		<pubDate>Fri, 15 May 2026 09:40:39 +0000</pubDate>
				<category><![CDATA[Unit Testing]]></category>
		<category><![CDATA[JUnit 5]]></category>
		<category><![CDATA[Kotlin]]></category>
		<category><![CDATA[MockK]]></category>
		<guid isPermaLink="false">https://www.petrikainulainen.net/?p=28820</guid>
					<description><![CDATA[<p>This blog post describes how we can configure the system under test and replace its dependencies with mocks when we are writing unit tests for a Kotlin application by using JUnit Jupiter and MockK. We will learn to get the required dependencies and configure the system under test by using both manual and extension-based configuration. <a rel="NOFOLLOW" class="excerpt_read_more" href="/programming/unit-testing/getting-started-with-mockk-the-setup/">Read More</a></p>
<p>The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/956061056/0/petrikainulainen~Getting-Started-With-MockK-The-Setup/">Getting Started With MockK: The Setup</a> appeared first on <a rel="NOFOLLOW" href="https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/956061056/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/956061056/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/956061056/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/956061056/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://mockk.io/">MockK</a> is a mocking library which embraces Kotlin's unique features such as "final by default", objects, and coroutines. That's why we should use it if we have to write unit tests for a Kotlin project. In this first part of my MockK tutorial, we will learn how to create mocks with MockK and JUnit Jupiter.</p>
<p>After we have finished this blog post, we:</p>
<ul>
<li>Can get the required dependencies with Maven and Gradle.</li>
<li>Understand how we can create mocks with MockK.</li>
</ul>
<p>Let's begin.</p>
<div class="note"><strong>This blog post assumes that:</strong></p>
<ul>
<li>You know how you can create a Kotlin project with <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://kotlinlang.org/docs/gradle.html">Gradle</a> or <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://kotlinlang.org/docs/maven.html">Maven</a>.</li>
<li>You are familiar with JUnit Jupiter.</li>
</ul>
</div>
<h2>Getting the Required Dependencies</h2>
<p>Before we can write tests which use MockK, we have to choose between the standard MockK API and its BDD (Behavior-Driven Development) variant. Basically, we have to choose between the classic <code>every</code>/<code>verify</code> syntax and the BDD style <code>given</code>/<code>then</code> syntax. This choice defines the MockK module which we must add to the classpath.</p>
<p>The following table identifies the different modules provided by MockK:</p>
<table class="compare-table">
<tr>
<th>Build Tool</th>
<th>Test Style</th>
<th>Group ID</th>
<th>Artifact ID</th>
<th>Configuration / Scope</th>
</tr>
<tr>
<td>Gradle</td>
<td>Standard</td>
<td><code>io.mockk</code></td>
<td><code>mockk</code></td>
<td><code>testImplementation</code></td>
</tr>
<tr>
<td>Gradle</td>
<td>BDD</td>
<td><code>io.mockk</code></td>
<td><code>mockk-bdd</code></td>
<td><code>testImplementation</code></td>
</tr>
<tr>
<td>Maven</td>
<td>Standard</td>
<td><code>io.mockk</code></td>
<td><code>mockk-jvm</code></td>
<td><code>test</code></td>
</tr>
<tr>
<td>Maven</td>
<td>BDD</td>
<td><code>io.mockk</code></td>
<td><code>mockk-bdd-jvm</code></td>
<td><code>test</code></td>
</tr>
</table>
<p><strong>Example 1: Gradle</strong></p>
<p>If we want to use the standard MockK API with Gradle, we have to add the <code>mockk</code> dependency (version 1.14.9) to the <code>testImplementation</code> dependency configuration. We can do this by adding the following line to the <code>dependencies</code> block of our <em>build.gradle.kts</em> file:</p>
<pre class="brush: java; title: ; notranslate">
testImplementation(&quot;io.mockk:mockk:1.14.9&quot;)
</pre>
<p><strong>Example 2: Maven</strong></p>
<p>If we want to use the standard MockK API with Maven, we have to add the <code>mockk-jvm</code> dependency (version 1.14.9) to the <code>test</code> scope. We can do this by adding the following dependency declaration to the <code>dependencies</code> section of our <em>pom.xml</em> file:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;dependency&gt;
    &lt;groupId&gt;io.mockk&lt;/groupId&gt;
    &lt;artifactId&gt;mockk-jvm&lt;/artifactId&gt;
    &lt;version&gt;1.14.9&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;
</pre>
<div class="note">We must use different artifact IDs for Gradle and Maven because:</p>
<ul>
<li>MockK is a <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://kotlinlang.org/docs/multiplatform/get-started.html">Kotlin Multiplatform</a> project that's published with <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://docs.gradle.org/current/userguide/publishing_gradle_module_metadata.html">Gradle module metadata</a>.</li>
<li>Because Gradle can read its own module metadata, it can resolve the correct variant automatically.</li>
<li>Because Maven cannot read Gradle's module metadata, we have to explicitly specify the variant we want to use.</li>
</ul>
</div>
<p>Next, we will take a closer look at the system under test.</p>
<h2>Introduction to the System Under Test</h2>
<p>During this blog post we will start writing tests for a component which allows us to register new user accounts. The implementation of this component is described in the following:</p>
<p>The <code>User.kt</code> file contains two data classes and one exception. These classes are:</p>
<ul>
<li>The <code>RegisterUserAccountRequest</code> class contains the information that's used to register a new user account.</li>
<li>The <code>UserAccount</code> class contains the information of a user account that's found from the database.</li>
<li>The <code>UserAccountExistsException</code> is a runtime exception that's thrown if the registered user account doesn't have a unique email address.</li>
</ul>
<p>The source code of the <code>User.kt</code> file looks as follows:</p>
<pre class="brush: java; title: ; notranslate">
data class RegisterUserAccountRequest(val email: String, val name: String)
data class UserAccount(val id: Long, val email: String, val name: String)
class UserAccountExistsException(email: String) :
    RuntimeException(&quot;The user account with email address: $email exists&quot;)
</pre>
<p>The <code>UserRepository</code> interface declares two functions:</p>
<ul>
<li>The <code>existsByEmail()</code> function returns <code>true</code> if the email address given as an argument is used by an existing user account and <code>false</code> otherwise.</li>
<li>The <code>save()</code> function saves the user account provided as an argument and returns the information that's inserted into the database.</li>
</ul>
<p>The source code of the <code>UserRepository</code> interface looks as follows:</p>
<pre class="brush: java; title: ; notranslate">
interface UserRepository {
    fun existsByEmail(email: String): Boolean
    fun save(input: RegisterUserAccountRequest): UserAccount
}
</pre>
<p>The <code>EmailService</code> interface declares one function that's used to send a welcome email to a new user after their user account has been registered. The source code of the <code>EmailService</code> interface looks as follows:</p>
<pre class="brush: java; title: ; notranslate">
interface EmailService {
    fun sendWelcomeEmail(email: String)
}
</pre>
<p>The <code>UserAccountRegistrationService</code> class has one function called <code>registerUserAccount()</code> that's implemented by following these steps:</p>
<ol>
<li>Throw the <code>UserAccountExistsException</code> if the registered user account doesn't have a unique email address.</li>
<li>Insert a new user account into the database.</li>
<li>Send the welcome email to the user.</li>
<li>Return the information that was inserted into the database.</li>
</ol>
<p>The source code of the <code>UserAccountRegistrationService</code> class looks as follows:</p>
<pre class="brush: java; title: ; notranslate">
class UserAccountRegistrationService(
    private val repository: UserRepository,
    private val emailService: EmailService
) {
    fun registerUserAccount(input: RegisterUserAccountRequest): UserAccount {
        if (repository.existsByEmail(input.email)) {
            throw UserAccountExistsException(input.email)
        }
        val registeredUserAccount = repository.save(input)
        emailService.sendWelcomeEmail(registeredUserAccount.email)
        return registeredUserAccount
    }
}
</pre>
<p>Let's move on and find out how we can create mocks with MockK and configure the system under test with JUnit Jupiter.</p>
<h2>Creating Mocks With MockK</h2>
<p>When we are writing our tests with JUnit Jupiter and we want to create mocks with MockK, we have two viable options:</p>
<ul>
<li>We can create a mock manually by invoking the <code>mockk()</code> function.</li>
<li>We can use the <code>MockKExtension</code> together with the <code>@MockK</code> and <code>@InjectMockKs</code> annotations.</li>
</ul>
<p>Let's start and find out how we can create mocks manually by using the <code>@BeforeEach</code> function.</p>
<h3>Creating Mocks Manually by Using the @BeforeEach Function</h3>
<p>When we want to replace the <code>UserRepository</code> and the <code>EmailService</code> dependencies of the <code>UserAccountRegistrationService</code> class with mocks by using the <code>@BeforeEach</code> function, we have to follow these steps:</p>
<p><strong>1.</strong> Create a new test class and add three <code>private lateinit</code> properties to the created test class:</p>
<ul>
<li>The <code>repository</code> property contains the <code>UserRepository</code> mock.</li>
<li>The <code>emailService</code> property contains the <code>EmailService</code> mock.</li>
<li>The <code>service</code> property contains the system under test (a <code>UserAccountRegistrationService</code> object).</li>
</ul>
<p>After we have added these properties to our test class, its source code looks as follows:</p>
<pre class="brush: java; highlight: [3,4,5]; title: ; notranslate">
class UserAccountRegistrationServiceManualTest {
    private lateinit var repository: UserRepository
    private lateinit var emailService: EmailService
    private lateinit var service: UserAccountRegistrationService
}
</pre>
<p><strong>2.</strong> Add a setup function to our test class and ensure that this function is invoked before a test function is run. After we have added a new setup function to our test class, its source code looks as follows:</p>
<pre class="brush: java; highlight: [9,10,11,12]; title: ; notranslate">
import org.junit.jupiter.api.BeforeEach
class UserAccountRegistrationServiceManualTest {
    private lateinit var repository: UserRepository
    private lateinit var emailService: EmailService
    private lateinit var service: UserAccountRegistrationService
    @BeforeEach
    fun configureSystemUnderTest() {
    }
}
</pre>
<p><strong>3.</strong> Implement the setup function by following these steps:</p>
<ol>
<li>Create new <code>UserRepository</code> and <code>EmailService</code> mocks by invoking the <code>mockk()</code> function and store the created mocks in the <code>repository</code> and <code>emailService</code> properties.</li>
<li>Create a new <code>UserAccountRegistrationService</code> object and store the created object in the <code>service</code> property.</li>
</ol>
<p>After we have implemented the setup function, the source code of our test class looks as follows:</p>
<pre class="brush: java; highlight: [12,13,14]; title: ; notranslate">
import io.mockk.mockk
import org.junit.jupiter.api.BeforeEach
class UserAccountRegistrationServiceManualTest {
    private lateinit var repository: UserRepository
    private lateinit var emailService: EmailService
    private lateinit var service: UserAccountRegistrationService
    @BeforeEach
    fun configureSystemUnderTest() {
        repository = mockk()
        emailService = mockk()
        service = UserAccountRegistrationService(repository, emailService)
    }
}
</pre>
<p>We have now configured the system under test by using the <code>@BeforeEach</code> function. Let's take a look at the pros and cons of this approach:</p>
<p><strong>Pros:</strong></p>
<ul>
<li><strong>Tests are isolated</strong>. Because every test function gets new mocks and a new system under test, there is no risk of "configuration leakage". In other words, stubbed functions and verifications cannot leak from one test to another.</li>
<li><strong>Doesn't require a specific test instance lifecycle mode</strong>. If we create the required mocks and the system under test in the <code>@BeforeEach</code> function, our test functions are isolated in every supported test instance lifecycle mode of JUnit Jupiter. For example, because we create new objects and assign property values before every test function, our configuration guarantees a clean slate even if JUnit Jupiter is reusing the test class instance.</li>
<li><strong>Explicit dependency injection</strong>. Because we create the system under test manually in the <code>@BeforeEach</code> function, we don't have to worry about the reflection magic that's used if we configure the system under test by using annotations.</li>
<li><strong>Can be used as a design tool</strong>. Because we have to manually create the system under test, we will feel the pain immediately if the system under test has too many dependencies. If it feels cumbersome to write the code that configures the system under test or the constructor call becomes so long that it's hard to read, we should refactor the system under test.</li>
</ul>
<p><strong>Cons:</strong></p>
<ul>
<li><strong>Requires nullable or lateinit properties</strong>. Because the properties are initialized in a <code>@BeforeEach</code> function and not in a test class constructor, we are forced to use nullable types or lateinit properties. This is a problem because:
<ul>
<li>If we use a lateinit property: we must use <code>var</code> instead of <code>val</code> and we cannot rely on compile-time null safety. In other words, the property can be accidentally reassigned outside of the <code>@BeforeEach</code> function, or we might simply forget to assign its value. The problem is that instead of a compiler error, we get a runtime error during test execution.</li>
<li>If we use a nullable type: we have to pay the "null-safety" tax (either use the "bang-bang" operator (<code>!!</code>) or do safe calls (<code>?.</code>)), we have to provide a default value (<code>null</code>) that's immediately replaced either with a mock or the tested object, and we mask the intent of the property because in Kotlin a nullable type typically means that the value can be missing which isn't the case here.</li>
</ul>
</li>
<li><strong>Requires boilerplate code</strong>. We have to write the setup code manually for every test class. This means that our test suite will have setup code that isn't, strictly speaking, required.</li>
<li><strong>Requires maintenance</strong>. If we add a new dependency to the system under test, we have to add a new lateinit property to our test class, create a new mock object in the <code>@BeforeEach</code> function, and modify the constructor call which creates the tested object.</li>
</ul>
<div class="note"><strong>Additional Reading:</strong></p>
<ul>
<li><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://docs.junit.org/6.0.3/writing-tests/test-classes-and-methods.html">JUnit User Guide: Test Classes and Methods</a></li>
<li><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://docs.junit.org/6.0.3/writing-tests/test-instance-lifecycle.html">JUnit User Guide: Test Instance Lifecycle</a></li>
<li><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://docs.junit.org/6.0.3/api/org.junit.jupiter.api/org/junit/jupiter/api/BeforeEach.html">The Javadoc of the <code>@BeforeEach</code> annotation</a></li>
<li><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://kotlinlang.org/docs/properties.html">Kotlin Language Guide: Properties</a></li>
<li><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://kotlinlang.org/docs/null-safety.html">Kotlin Language Guide: Null Safety</a></li>
</ul>
</div>
<p>Next, we will find how we can create mocks manually as immutable class properties.</p>
<h3>Creating Mocks Manually as Immutable Class Properties</h3>
<p>When we want to replace the <code>UserRepository</code> and the <code>EmailService</code> dependencies of the <code>UserAccountRegistrationService</code> class with mocks, and add these mocks and the system under test to our test class as immutable class properties, we have to create a new test class and follow these steps:</p>
<ol>
<li>Add a <code>private</code> and immutable <code>repository</code> property to our test class and ensure that it contains a <code>UserRepository</code> mock.</li>
<li>Add a <code>private</code> and immutable <code>emailService</code> property to our test class and ensure that it contains an <code>EmailService</code> mock.</li>
<li>Add a <code>private</code> and immutable <code>service</code> property to our test class and ensure that it contains a new <code>UserAccountRegistrationService</code> object. Remember to pass the <code>UserRepository</code> and the <code>EmailService</code> mocks as constructor arguments.</li>
</ol>
<p>After we have added the immutable class properties to our test class, its source code looks as follows:</p>
<pre class="brush: java; highlight: [5,6,7]; title: ; notranslate">
import io.mockk.mockk
class UserAccountRegistrationServiceManualClassPropertyTest {
    private val repository = mockk&lt;UserRepository&gt;()
    private val emailService = mockk&lt;EmailService&gt;()
    private val service = UserAccountRegistrationService(repository, emailService)
}
</pre>
<p>We have now configured the system under test by using immutable class properties. Let's take a look at the pros and cons of this approach.</p>
<p><strong>Pros:</strong></p>
<ul>
<li><strong>All class properties are immutable</strong>. They cannot be reassigned and they cannot be <code>null</code>.</li>
<li><strong>Tests are isolated (if we use the correct test instance lifecycle mode)</strong>. Because every test function gets new mocks and a new system under test, there is no risk of "configuration leakage". In other words, stubbed functions and verifications cannot leak from one test to another.</li>
<li><strong>Explicit dependency injection</strong>. Because we create the system under test manually, we don't have to worry about the reflection magic that's used if we configure the system under test by using annotations.</li>
<li><strong>Can be used as a design tool</strong>. Because we have to manually create the system under test, we will feel the pain immediately if the system under test has too many dependencies. If it feels cumbersome to write the code configures the system under test or the constructor call becomes so long that it's hard to read, we should refactor the system under test.</li>
</ul>
<p><strong>Cons:</strong></p>
<ul>
<li><strong>JUnit Jupiter must create a new test instance for every test function</strong> (this is the default behavior). As long as JUnit Jupiter creates a new test instance for every test function, there is no risk of "configuration leakage". If the JUnit Jupiter is configured the create a new test instance once per test class, a test function will inherit the stubs and recorded interactions from the previous test function (if we don't do manual cleanup). This shared state can lead to flaky tests where the outcome of one test depends on the execution order of the other tests.</li>
<li><strong>Requires boilerplate code</strong>. We have to write the setup code manually for every test class. This means that our test suite will have setup code that isn't, strictly speaking, required.</li>
<li><strong>Requires maintenance</strong>. If we add a new dependency to the system under test, we have to add a new immutable class property to our test class, create a new mock object, and modify the constructor call which creates the tested object.</li>
</ul>
<div class="note"><strong>Additional Reading:</strong></p>
<ul>
<li><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://docs.junit.org/6.0.3/writing-tests/test-instance-lifecycle.html">JUnit User Guide: Test Instance Lifecycle</a></li>
<li><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://kotlinlang.org/docs/properties.html">Kotlin Language Guide: Properties</a></li>
<li><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://kotlinlang.org/docs/null-safety.html">Kotlin Language Guide: Null Safety</a></li>
</ul>
</div>
<p>Let's move on and find out how we can create mocks by using the JUnit Jupiter extension together with the <code>@MockK</code> and <code>@InjectMockKs</code> annotations.</p>
<h3>Using the JUnit Jupiter Extension</h3>
<p>When we want to replace the <code>UserRepository</code> and the <code>EmailService</code> dependencies of the <code>UserAccountRegistrationService</code> class with mocks by using MockK JUnit Jupiter extension, we have to follow these steps:</p>
<p><strong>1.</strong> Create a new test class and add three <code>private lateinit</code> properties to the created test class:</p>
<ul>
<li>The <code>repository</code> property contains the <code>UserRepository</code> mock.</li>
<li>The <code>emailService</code> property contains the <code>EmailService</code> mock.</li>
<li>The <code>service</code> property contains the system under test (a <code>UserAccountRegistrationService</code> object).</li>
</ul>
<p>After we have added these properties to our test class, its source code looks as follows:</p>
<pre class="brush: java; highlight: [3,4,5]; title: ; notranslate">
class UserAccountRegistrationServiceExtensionTest {
    private lateinit var repository: UserRepository
    private lateinit var emailService: EmailService
    private lateinit var service: UserAccountRegistrationService
}
</pre>
<p><strong>2.</strong> Annotate the <code>repository</code> and <code>emailService</code> properties with the <code>@MockK</code> annotation. This annotation identifies the properties that contain mocks and instructs the MockK JUnit Jupiter extension to create the required mock objects. After we have annotated these properties with the <code>@MockK</code> annotation, the source code of our test class looks as follows:</p>
<pre class="brush: java; highlight: [5,6,7,8,9]; title: ; notranslate">
import io.mockk.impl.annotations.MockK
class UserAccountRegistrationServiceExtensionTest {
    @MockK
    private lateinit var repository: UserRepository
    @MockK
    private lateinit var emailService: EmailService
    private lateinit var service: UserAccountRegistrationService
}
</pre>
<p><strong>3.</strong> Annotate the <code>service</code> property with the <code>@InjectMockKs</code> annotation. This annotation identifies the property initialized by the MockK JUnit Jupiter extension and instructs it to replace the dependencies of the created object with mocks. After we have done this, the source code of our test class looks as follows:</p>
<pre class="brush: java; highlight: [12]; title: ; notranslate">
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.MockK
class UserAccountRegistrationServiceExtensionTest {
    @MockK
    private lateinit var repository: UserRepository
    @MockK
    private lateinit var emailService: EmailService
    @InjectMockKs
    private lateinit var service: UserAccountRegistrationService
}
</pre>
<p><strong>4.</strong> Register the used JUnit Jupiter extension by annotating our test class with the <code>@ExtendWith</code> annotation. After we have registered the <code>MockKExtension</code>, the source code of our test class looks as follows:</p>
<pre class="brush: java; highlight: [6]; title: ; notranslate">
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.MockK
import io.mockk.junit5.MockKExtension
import org.junit.jupiter.api.extension.ExtendWith
@ExtendWith(MockKExtension::class)
class UserAccountRegistrationServiceExtensionTest {
    @MockK
    private lateinit var repository: UserRepository
    @MockK
    private lateinit var emailService: EmailService
    @InjectMockKs
    private lateinit var service: UserAccountRegistrationService
}
</pre>
<p>We have now configured the system under test by using the MockK JUnit Jupiter extension. Let's take a look at the pros and cons of this approach:</p>
<p><strong>Pros:</strong></p>
<ul>
<li><strong>Tests are isolated</strong>. The MockK JUnit Jupiter extension ensures that every test function gets clean mocks. In other words, it makes sure that stubbed functions and verifications cannot leak from one test to another.</li>
<li><strong>Minimal Boilerplate</strong>. We don't have to manually invoke the <code>mockk()</code> function or invoke the constructor of the tested class. We can simply describe what we want by using the <code>@MockK</code> and <code>@InjectMockKs</code> annotations, and the MockK JUnit Jupiter extension will do the hard lifting for us.</li>
<li><strong>Clean Class Structure</strong>. Because the MockK JUnit Jupiter extension creates the mock objects and the tested object, our test class looks clean. All properties are listed at the top of the test class, and the <code>@MockK</code> and <code>@InjectMockKs</code> annotations make it clear what's mocked and what's tested.</li>
</ul>
<p><strong>Cons:</strong></p>
<ul>
<li><strong>Requires nullable or lateinit properties</strong>. Because the test class properties are initialized by the MockK JUnit Jupiter extension after the test class is instantiated (and not in a test class constructor), we are forced to use nullable types or lateinit properties. This is a problem because:
<ul>
<li>If we use a lateinit property: we must use <code>var</code> instead of <code>val</code> and we cannot rely on compile-time null safety. In other words, the property can be accidentally reassigned, or we might simply forget to assign its value. The problem is that instead of a compiler error, we get a runtime error during test execution.</li>
<li>If we use a nullable type: we have to pay the "null-safety" tax (either use the "bang-bang" operator (<code>!!</code>) or do safe calls (<code>?.</code>)), we have to provide a default value (<code>null</code>) that's immediately replaced either with a mock or the tested object, and we mask the intent of the property because in Kotlin a nullable type typically means that the value can be missing which isn't the case here.</li>
</ul>
</li>
<li><strong>Hides bad design</strong>. Because it's so easy to create a new mock and inject it into the system under test, we might not realize that the system under test has too many dependencies until it's too late. In other words, we don't feel the "constructor friction" that acts as a design tool.</li>
<li><strong>Relies on reflection and "magic"</strong>. The MockK JUnit Jupiter extension relies heavily on reflection. This leads into a "magic" behavior that's harder to debug than plain Kotlin code. Also, if something goes wrong, it's likely that we will get a confusing error message at runtime instead of a clean compilation error.</li>
</ul>
<div class="note"><strong>Additional Reading:</strong></p>
<ul>
<li><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://docs.junit.org/6.0.3/extensions/registering-extensions.html">JUnit User Guide: Registering Extensions</a></li>
<li><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://mockk.io/#junit5">MockK User Guide: JUnit 5</a></li>
<li><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://kotlinlang.org/docs/properties.html">Kotlin Language Guide: Properties</a></li>
<li><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://kotlinlang.org/docs/null-safety.html">Kotlin Language Guide: Null Safety</a></li>
</ul>
</div>
<p>We can now get the required dependencies with Maven and Gradle, and we understand how we can create mocks with MockK. Let's summarize what we learned from this blog post.</p>
<h2>Summary</h2>
<p>This blog post has taught us four things:</p>
<ul>
<li>If we want to use the standard MockK API with Gradle, we have to add the <code>mockk</code> dependency to the <code>testImplementation</code> dependency configuration. We don't have to specify the variant we want to use because Gradle can read its own .module metadata and resolve the correct variant automatically.</li>
<li>If we want to use the standard MockK API with Maven, we have to add the <code>mockk-jvm</code> dependency to the <code>test</code> scope. We must explicitly specify the variant we want to use because Maven cannot read Gradle's .module metadata.</li>
<li>We must choose whether we want to couple our tests to a specific test instance lifecycle mode or ensure that our tests are working as expected regardless of the lifecycle configuration. This decision dictates how we can configure the system under test.</li>
<li>We must make a trade-off between automation and design feedback. The <code>MockKExtension</code> and annotations reduce boilerplate code, but the manual configuration acts as an architectural design tool which alerts us when a class has too many dependencies.</li>
</ul>
<p><strong>P.S. You can <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://github.com/pkainulainen/mockk-examples/tree/main/introduction">get the example application from Github</a></strong>.</p>
<p>The post <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net/programming/unit-testing/getting-started-with-mockk-the-setup/">Getting Started With MockK: The Setup</a> appeared first on <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/956061056/0/petrikainulainen">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/956061056/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/956061056/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/956061056/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/956061056/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&#160;</div>]]>
</content:encoded>
					
					<wfw:commentRss>https://feeds.feedblitz.com/~/956061056/0/petrikainulainen~Getting-Started-With-MockK-The-Setup/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>https://www.petrikainulainen.net/monthly/software-development-monthly-4-2026/</feedburner:origLink>
		<title>Software Development Monthly 4 / 2026</title>
		<link>https://feeds.feedblitz.com/~/955802102/0/petrikainulainen~Software-Development-Monthly/</link>
					<comments>https://feeds.feedblitz.com/~/955802102/0/petrikainulainen~Software-Development-Monthly/#respond</comments>
		
		<dc:creator><![CDATA[Petri Kainulainen]]></dc:creator>
		<pubDate>Tue, 12 May 2026 15:10:46 +0000</pubDate>
				<category><![CDATA[Monthly]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[Spring Framework]]></category>
		<guid isPermaLink="false">https://www.petrikainulainen.net/?p=29120</guid>
					<description><![CDATA[<p>The Software Development Monthly is a monthly blog post that highlights interesting or useful blog posts which I read during the previous month. This blog post shares 24 interesting or useful blog posts which I read during April 2026. <a rel="NOFOLLOW" class="excerpt_read_more" href="/monthly/software-development-monthly-4-2026/">Read More</a></p>
<p>The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/955802102/0/petrikainulainen~Software-Development-Monthly/">Software Development Monthly 4 / 2026</a> appeared first on <a rel="NOFOLLOW" href="https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/955802102/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/955802102/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/955802102/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/955802102/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<p>The Software Development Monthly is a monthly blog post that shares interesting or useful content which I consumed during the previous month. This blog post is always published on the eight day of the month.</p>
<p>Let's begin!</p>
<div class="note">
<strong>Table of Contents:</strong></p>
<ul>
<li><a href="#ai">AI</a></li>
<li><a href="#cloud">Cloud</a></li>
<li><a href="#sw-development">Software Development</a></li>
</ul>
</div>
<h2 id="ai">AI</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://sockpuppet.org/blog/2026/03/30/vulnerability-research-is-cooked/">Vulnerability Research Is Cooked</a> argues that a substantial amount of vulnerability research will be replaced with AI agents which will scan code bases for zero day vulnerabilities.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.hollandtech.net/claude-is-not-your-architect/">Claude Is Not Your Architect. Stop Letting It Pretend.</a> explains why we shouldn't let Claude (or any other AI agent) to sit on the driver's seat.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://futurism.com/artificial-intelligence/ai-boiling-frog-human-cognition-study">AI Use Appears to Have a "Boiling Frog" Effect on Human Cognition</a> summarizes the results of a research which claims that AI improves short term performance, but this improvement comes at a heavy cognitive cost.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.jetbrains.com/idea/2026/03/ai-assisted-java-application-development-with-agent-skills/">AI-Assisted Java Application Development with Agent Skills</a> describes how we can optimize the context size by leveraging agent skills.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://spring.io/blog/2026/04/07/spring-ai-agentic-patterns-6-memory-tools">Spring AI Agentic Patterns (Part 6): AutoMemoryTools — Persistent Agent Memory Across Sessions</a> explains how we can give our AI agents a long-term memory that can be accessed by different sessions.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://spring.io/blog/2026/04/15/spring-ai-session-management">Spring AI Agentic Patterns (Part 7): Session API — Event-Sourced Short-Term Memory with Context Compaction</a> provides an introduction to Spring AI Session which adds support for storing the conversation history to a short-term memory. </p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://alexop.dev/posts/the-software-factory/">The Software Factory: Why Your Team Will Never Work the Same Again</a> explains how the rise of software factories is changing the way we write code.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://leehanchung.github.io/blogs/2026/04/05/the-ai-great-leap-forward/">The AI Great Leap Forward</a> argues that the current AI boom is a 'Great Leap Forward' that destroys software quality by prioritizing quantity and speed over human expertise.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.democratic-economy.org/total-skill-collapse-is-how-ai-makes-idiocracy-a-reality/">Total Skill Collapse Is How AI Makes Idiocracy a Reality</a> argues that AI model collapse is accelerated by the fact that no one has incentive to publish original content on the internet.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://larsfaye.com/articles/agentic-coding-is-a-trap">Agentic Coding is a Trap</a> explains that agentic coding is a trap because over time developers lose both the ability to write code and the deep system understanding required to maintain complex software.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://github.blog/news-insights/company-news/github-copilot-is-moving-to-usage-based-billing/">GitHub Copilot is moving to usage-based billing</a> announces that GitHub Copilot moves from flat-rate subscriptions to usage-based billing.</p>
<h2 id="cloud">Cloud</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.allthingsdistributed.com/2026/04/s3-files-and-the-changing-face-of-s3.html">S3 Files and the changing face of S3</a> introduces a new AWS feature called S3 files which allows us to use S3 as a network attached file system.</p>
<h2 id="sw-development">Software Development</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://frederickvanbrabant.com/blog/2026-04-04-whats-in-it-for-me-architecture/">"What’s In It For Me" Architecture</a> argues that a good architect has excellent soft skills and provides three tips that help architects to convince other people to implement their designs.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://bold-edit.com/devlog/one-year-rewrite.html">A Year Long Rewrite</a> describes the challenges the author faced when they decided to rewrite the code of their text editor.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://jon.chrt.dev/2026/04/15/things-you-didnt-know-about-indexes.html">Things you didn't know about indexes</a> provides an introduction to database indexes and identifies some pitfalls which make our queries slower than they could be.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://purplesyringa.moe/blog/no-one-owes-you-supply-chain-security/">No one owes you supply-chain security</a> argues that open-source developers aren't responsible for the supply-chain security of the companies who profit from the open-source software.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://fagnerbrack.com/the-danger-of-modern-open-source-c15dd5206346">The Danger of "Modern" Open Source</a> examines the risks of the modern open-source ecosystem where companies exploit open-source maintainers for free. </p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://jvogel.me/posts/2026/java-is-fast-your-code-might-not-be">Java Is Fast. Your Code Might Not Be.</a> argues that the performance issues of Java applications are caused by inefficient coding patterns.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://jvogel.me/posts/2026/one-method-using-71-percent-of-cpu">One Method Was Using 71% of CPU. Here's the Flame Graph.</a> explains how we can investigate the performance of a Java application and demonstrates how the implementation of one method can lead to a massive bottleneck.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.jbrains.ca/permalink/when-you-can-safely-leave-sprints-behind">When You Can Safely Leave Sprints Behind</a> argues that the traditional time-boxed sprints are useful when we are trying to build good habits, but we can move forward to continuous flow models once our workflow is stable and predictable.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/all-things-software/spring-boot-configuration-properties-at-scale-884f494721ac">Spring Boot Configuration Properties at Scale</a> describes how we can manage complex Spring Boot configurations which are used by huge applications.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.infoq.com/articles/spring-team-spring-7-boot-4/">The Spring Team on Spring Framework 7 and Spring Boot 4</a> highlights the architectural and functional improvements introduced in Spring Framework 7 and Spring Boot 4.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://mitchellh.com/writing/ghostty-leaving-github">Ghostty Is Leaving GitHub</a> explains that Ghostly is leaving GitHub because of GitHub outages.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.sivalabs.in/before-you-judge-get-curious/">Before You Judge, Get Curious</a> describes why we should ask questions instead of judging people who disagree with us.</p>
<p>The post <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net/monthly/software-development-monthly-4-2026/">Software Development Monthly 4 / 2026</a> appeared first on <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/955802102/0/petrikainulainen">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/955802102/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/955802102/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/955802102/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/955802102/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&#160;</div>]]>
</content:encoded>
					
					<wfw:commentRss>https://feeds.feedblitz.com/~/955802102/0/petrikainulainen~Software-Development-Monthly/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-4-2026/</feedburner:origLink>
		<title>Clean Test Automation Monthly 4 / 2026</title>
		<link>https://feeds.feedblitz.com/~/955230170/0/petrikainulainen~Clean-Test-Automation-Monthly/</link>
					<comments>https://feeds.feedblitz.com/~/955230170/0/petrikainulainen~Clean-Test-Automation-Monthly/#respond</comments>
		
		<dc:creator><![CDATA[Petri Kainulainen]]></dc:creator>
		<pubDate>Mon, 04 May 2026 16:13:28 +0000</pubDate>
				<category><![CDATA[Monthly]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[Playwright]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[TestContainers]]></category>
		<guid isPermaLink="false">https://www.petrikainulainen.net/?p=29130</guid>
					<description><![CDATA[<p>The Clean Test Automation Monthly is a monthly blog post that highlights interesting or useful test automation content which I read during the current month. This blog post shares 16 interesting or useful blog posts which I read during April 2026. <a rel="NOFOLLOW" class="excerpt_read_more" href="/monthly/clean-test-automation-monthly-4-2026/">Read More</a></p>
<p>The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/955230170/0/petrikainulainen~Clean-Test-Automation-Monthly/">Clean Test Automation Monthly 4 / 2026</a> appeared first on <a rel="NOFOLLOW" href="https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/955230170/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/955230170/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/955230170/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/955230170/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a><h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-4-2025/">Clean Test Automation Monthly 4 / 2025</a></li><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-4-2024/">Clean Test Automation Monthly 4 / 2024</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<p>The Clean Test Automation Monthly is a monthly blog post that shares interesting or useful test automation content which I consumed during the current month. This blog post is always published on the first day of the "next" month.</p>
<p>Let's begin!</p>
<div class="note">
<strong>Table of Contents:</strong></p>
<ul>
<li><a href="#design">Test  Design</a></li>
<li><a href="#backend">Backend</a></li>
<li><a href="#ui-end-to-end">UI / End-to-End</a></li>
</ul>
</div>
<h2 id="design">Test Design</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.ontestautomation.com/my-thoughts-on-self-healing-in-test-automation/">My thoughts on 'self-healing' in test automation</a> defines the term self-healing test automation and explains why it's a bad idea.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.thegreenreport.blog/articles/rethinking-your-test-strategy-for-ai-powered-features/rethinking-your-test-strategy-for-ai-powered-features.html">Rethinking Your Test Strategy for AI-Powered Features</a> is a comprehensive article which explains what we have to take into account when we are testing AI-powered features.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/@oluwasayo/youre-not-meta-build-fast-teams-with-fast-tests-20b47694db52">You’re Not Meta: Build Fast Teams with Fast Tests</a> argues that for most companies writing high-speed test suites is critical for ensuring that we can move forward as fast as possible.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.jeffschomay.com/letting-ai-play-my-game">Letting AI play my game</a> explains how the author used AI for testing his game where a crossword builds the map of an old-school dungeon crawler. </p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://dragonsforelevenses.com/2026/04/08/you-climbed-the-test-pyramid-now-eat-a-custard-slice/">You Climbed the Test Pyramid. Now Eat a Custard Slice</a> introduces a new mental model that ignores technical scope and categorizes tests by the value they provide. </p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://foojay.io/today/eliminating-flaky-tests-to-end-world-hunger/">Eliminating Flaky Tests to End World Hunger</a> explains why flaky tests are bad, identifies five reasons why our tests are flaky, and highlights seven strategies that help us to get rid of flaky tests.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://testingil.com/2026/04/the-flaky-test-files-the-case-of-the-state-pollution.html">The Flaky Test Files: The Case of the State Pollution</a> descibes how state pollution causes flaky tests.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://automationpanda.com/2026/04/27/bdd-gherkin-guidelines-for-ai-coding-and-testing/">BDD Gherkin Guidelines for AI Coding and Testing</a> announces the release of Gherkin Guidelines for AI. It's an open source context file that helps AI agents to write better Gherkin scenarios.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://martinelli.ch/how-and-why-to-trace-use-cases-and-tests/">How and Why to Trace Use Cases and Tests</a> explains why we must be able to link tests with use cases, describes how we can do it with a custom annotation, and announces the release of the AI Unified Process Navigator for IntelliJ plugin which makes the tracking process easier and faster (if we use IntelliJ Idea).</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.davidmello.com/software-testing/test-automation/how-to-handle-failing-tests-caused-by-known-bugs">How to Handle Failing Tests Caused by a Known Bug</a> argues that if a test case fails because of a bug that cannot be fixed immediately, we should configure our test framework to skip the failed test case.</p>
<h2 id="backend">Backend</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.elastic.co/search-labs/blog/elasticsearch-integration-tests">Testing Elasticsearch. It just got simpler.</a> describes how Elasticsearch 9.x and Testcontainers 2.x have made it easier to write tests for code which uses Elasticsearch.</p>
<h2 id="ui-end-to-end">UI / End-to-End</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.abelenekes.com/p/signals-are-not-guarantees">Signals Are Not Guarantees</a> argues that many end-to-end tests contain assertions which are written on the wrong level, and explains how we can fix this problem.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/@martinmarchetto/evolving-pom-from-page-objects-to-agent-friendly-design-38c074ec8519">Evolving POM: From Page Objects to Agent-Friendly Design</a> describes how we can move from the classic page objects to page objects which can be leveraged by AI agents.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://currents.dev/posts/migrating-from-selenium-to-playwright-the-complete-guide">Migrating from Selenium to Playwright: The Complete Guide</a> explains how we can evaluate the costs and risks of the migration, identifies four situations when the migration makes no sense, and describes how we can get the job done if we decide to do it.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.davidmello.com/software-testing/test-automation/playwright-accessibility-testing-axe-lighthouse-limitations">Playwright Accessibility Testing: What axe and Lighthouse Miss</a> identifies the accessibility issues which are missed by automated accessibility tools, describes how we can write better accessibility tests, and explains what must be tested manually.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://tech.trivago.com/post/2026-04-15-my-2-cents-ill-gladly-spend-them-to-stop-staring-at-test-logs">My 2 Cents: I'll gladly spend them to stop staring at test logs</a> describes how Trivago built an AI tool which analyzes test failures and publishes its analysis on Github Actions workflow summary.</p>
<p>The post <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-4-2026/">Clean Test Automation Monthly 4 / 2026</a> appeared first on <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/955230170/0/petrikainulainen">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/955230170/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/955230170/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/955230170/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/955230170/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a><h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-4-2025/">Clean Test Automation Monthly 4 / 2025</a></li><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-4-2024/">Clean Test Automation Monthly 4 / 2024</a></li></ul>&#160;</div>]]>
</content:encoded>
					
					<wfw:commentRss>https://feeds.feedblitz.com/~/955230170/0/petrikainulainen~Clean-Test-Automation-Monthly/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>https://www.petrikainulainen.net/monthly/software-development-monthly-3-2026/</feedburner:origLink>
		<title>Software Development Monthly 3 / 2026</title>
		<link>https://feeds.feedblitz.com/~/953900468/0/petrikainulainen~Software-Development-Monthly/</link>
					<comments>https://feeds.feedblitz.com/~/953900468/0/petrikainulainen~Software-Development-Monthly/#respond</comments>
		
		<dc:creator><![CDATA[Petri Kainulainen]]></dc:creator>
		<pubDate>Thu, 16 Apr 2026 15:03:36 +0000</pubDate>
				<category><![CDATA[Monthly]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Claude Code]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[jOOQ]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<guid isPermaLink="false">https://www.petrikainulainen.net/?p=29061</guid>
					<description><![CDATA[<p>The Software Development Monthly is a monthly blog post that highlights interesting or useful blog posts which I read during the previous month. This blog post shares 32 interesting or useful blog posts which I read during March 2026. <a rel="NOFOLLOW" class="excerpt_read_more" href="/monthly/software-development-monthly-3-2026/">Read More</a></p>
<p>The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/953900468/0/petrikainulainen~Software-Development-Monthly/">Software Development Monthly 3 / 2026</a> appeared first on <a rel="NOFOLLOW" href="https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/953900468/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/953900468/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/953900468/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/953900468/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<p>The Software Development Monthly is a monthly blog post that shares interesting or useful content which I consumed during the previous month. This blog post is always published on the eight day of the month.</p>
<p>Let's begin!</p>
<div class="note">
<strong>Table of Contents:</strong></p>
<ul>
<li><a href="#ai">AI</a></li>
<li><a href="#cloud">Cloud</a></li>
<li><a href="#sw-development">Software Development</a></li>
</ul>
</div>
<h2 id="ai">AI</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://lucianonooijen.com/blog/why-i-stopped-using-ai-code-editors/">Why I stopped using AI code editors</a> warns that overusing AI code editors can lead to a loss of technical intuition and fundamental engineering skills.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://fagnerbrack.com/ai-as-a-coding-assistant-is-the-wrong-mental-model-ff77e1b39f9a">Writing code was never the bottleneck</a> argues that writing code faster is a reasonable goal, but it doesn't eliminate the real bottlenecks. The author identifies some of these bottlenecks and describes how we can remove them with Claude Code and Github Actions.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://futurism.com/artificial-intelligence/ai-brain-fry">AI Use at Work Is Causing "Brain Fry", Researchers Find, Especially Among High Performers</a> explains that constant interaction with AI tools can lead to cognitive overload, fatigue, and slower decision-making.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://alexeyondata.substack.com/p/how-i-dropped-our-production-database">How I Dropped Our Production Database and Now Pay 10% More for AWS</a> is a post mortem of an incident where a Claude Code agent wiped the production AWS infrastructure (including the database) and deleted all automated backups.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://boristane.com/blog/the-software-development-lifecycle-is-dead/">The Software Development Lifecycle Is Dead</a> argues that AI agents have collapsed the traditional software development lifecycle into a tight loop of intent, execution, and observation.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://apenwarr.ca/log/20260316">Every layer of review makes you 10x slower</a> explains how every layer of approval drastically decreases our velocity, and argues that even though AI can generate code faster, the only way to sustainably increase velocity is to do fewer reviews.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://nanonets.com/blog/ai-agent-hacks-mckinsey/">AI Agent Hacks McKinsey: 5 Situations When You Should Not Deploy Agents</a> identifies five situations where we shouldn't use AI agents.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://boreal.social/post/ai-wont-make-you-rich-but-fixing-bugs-in-ai-slopware-will">AI won't make you rich. But fixing bugs in AI slopware will</a> argues that debugging and stabilizing AI generated code will be the next big economic opportunity for developers.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://andrewmurphy.io/blog/if-you-thought-the-speed-of-writing-code-was-your-problem-you-have-bigger-problems">If you thought the speed of writing code was your problem - you have bigger problems</a> argues that if we increase the amount of generated code with AI without addressing the real bottlenecks, we will only create "traffic jams" which reduce the amount of delivered value.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://notes.visaint.space/ai-coding-is-gambling/">AI Coding is Gambling</a> describes how coding has changed from an act that requires thinking to a form of gambling where developers pull a slot machine for solutions, and argues that this process makes the development work less satisfactory.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.ivanturkovic.com/2026/02/25/ai-made-writing-code-easier-engineering-harder/">AI Made Writing Code Easier. It Made Being an Engineer Harder.</a> argues that AI tools have made code generation faster, but the software engineering role has become more taxing, and the AI tools have caused an identity crisis for developers who love writing code.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.dailydoseofds.com/p/anatomy-of-the-claude-folder">Anatomy of the <em>.claude/</em> Folder</a> provides a comprehensive tutorial to the contents of the <em>.claude/</em> directory. For example, the author provides an introduction to commands, rules, skills, and agents.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://mariozechner.at/posts/2026-03-25-thoughts-on-slowing-the-fuck-down/">Thoughts on slowing the fuck down</a> warns that agentic code generation can create unrecoverable technical debt, and argues that we should slow down and put the developer back to the driver's seat.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://martinelli.ch/ai-tools-for-developers-are-not-enough/">AI Tools for Developers Are Not Enough</a> explains that even though teams can generate code faster than ever before, this doesn't guarantee that they will solve the right problems. The author argues that if we want to build the right thing faster, we need AI tools which support the whole software development lifecycle.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.frankel.ch/writing-agent-skill/">Writing an agent skill</a> explains how we can optimize Claude Code's token usage by writing agent skills.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://piotrminkowski.com/2026/03/24/claude-code-template-for-spring-boot/">Claude Code Template for Spring Boot</a> introduces the author's Claude Code template for Spring Boot applications. This template leverages both agents and skills, and its goal is to help us to generate production ready Spring Boot applications.</p>
<h2 id="cloud">Cloud</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://onecloudplease.com/blog/bucketsquatting-is-finally-dead">Bucketsquatting is (Finally) Dead</a> defines the term 'bucketsquatting' and explains how AWS solved this issue by introducing account specific S3 namespaces.</p>
<h2 id="sw-development">Software Development</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://terriblesoftware.org/2026/03/03/nobody-gets-promoted-for-simplicity/">Nobody Gets Promoted for Simplicity</a> argues that engineering culture often values over-engineering and ignores the value of simple solutions.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://sushantdhiman.dev/things-i-miss-about-spring-boot-after-switching-to-go/">Things I miss about Spring Boot after switching to Go</a> identifies six Spring Boot features the author misses and highlights three things Go does better.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://unplannedobsolescence.com/blog/xml-cheap-dsl/">XML is a Cheap DSL</a> argues that XML is an effective tool for building domain-specific languages.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://neciudan.dev/name-your-effects">Start naming your <code>useEffect</code> functions, you will thank me later</a> argues that naming <code>useEffect</code> functions makes our code cleaner and helps us to identify effects that shouldn't exist.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://thinkpol.ca/2026/03/24/the-junior-developer-pipeline-is-broken-and-nobody-has-a-plan-to-fix-it/">The junior developer pipeline is broken, and nobody has a plan to fix it</a> explores the problems caused by the collapsing junior developer hiring pipeline and identifies solutions that could help us solve them.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.iankduncan.com/engineering/2026-02-05-github-actions-killing-your-team">GitHub Actions Is Slowly Killing Your Engineering Team</a> compares GitHub Actions and Buildkite, and argues that we should use Buildkite instead of GitHub Actions.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://foojay.io/today/java-for-scripting/">JavaScript (No, Not That One): Modern Automation with Java</a> highlights modern Java features that have transformed Java into a viable scripting language.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://daniel.haxx.se/blog/2026/03/26/dont-trust-verify/">Don’t trust, verify</a> explains why we should verify that the tools we use were released by the correct "source" and haven't been tampered with.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://safedep.io/axios-npm-supply-chain-compromise/">axios Compromised: npm Supply Chain Attack via Dependency Injection</a> is a comprehensive analysis of the supply chain attack where the popular axios NPM package was used to deliver malware. </p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://github.com/axios/axios/issues/10636">Post Mortem: axios npm supply chain compromise</a> is the official post mortem of the axios supply chain attack.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.jongallant.com/2026/03/announcing-grut">Announcing grüt - A Terminal File Explorer with Git, GitHub, and AI Integration</a> introduces a new terminal-based file explorer that works in Linux, MacOS, and Windows.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://hanno.codes/2026/03/17/java-26-is-here/">Java 26 Is Here, And With It a Solid Foundation for the Future</a> summarizes the key changes and new features introduced in Java 26.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.sivalabs.in/feel-left-behind-in-tech-this-is-90-day-comeback-plan/">Feeling Left Behind in Tech? This Is Your 90-Day Comeback Plan</a> introduces a structured 90-day strategy that helps experienced developers to modernize their skill sets.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://piotrminkowski.com/2026/03/19/speed-up-java-startup-with-spring-boot-and-project-leyden/">Speed up Java Startup with Spring Boot and Project Leyden</a> explains how we can achieve up to a 75% faster startup time for Spring Boot applications.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.jooq.org/managing-sensitive-data-in-jooq-3-21-logs/">Managing Sensitive Data in jOOQ 3.21+ Logs</a> describes how we can exclude sensitive data from jOOQ logs.</p>
<p>The post <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net/monthly/software-development-monthly-3-2026/">Software Development Monthly 3 / 2026</a> appeared first on <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/953900468/0/petrikainulainen">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/953900468/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/953900468/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/953900468/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/953900468/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&#160;</div>]]>
</content:encoded>
					
					<wfw:commentRss>https://feeds.feedblitz.com/~/953900468/0/petrikainulainen~Software-Development-Monthly/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-3-2026/</feedburner:origLink>
		<title>Clean Test Automation Monthly 3 / 2026</title>
		<link>https://feeds.feedblitz.com/~/953460086/0/petrikainulainen~Clean-Test-Automation-Monthly/</link>
					<comments>https://feeds.feedblitz.com/~/953460086/0/petrikainulainen~Clean-Test-Automation-Monthly/#respond</comments>
		
		<dc:creator><![CDATA[Petri Kainulainen]]></dc:creator>
		<pubDate>Tue, 07 Apr 2026 14:30:20 +0000</pubDate>
				<category><![CDATA[Monthly]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Angular]]></category>
		<category><![CDATA[Clean Tests]]></category>
		<category><![CDATA[Playwright]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<guid isPermaLink="false">https://www.petrikainulainen.net/?p=29031</guid>
					<description><![CDATA[<p>The Clean Test Automation Monthly is a monthly blog post that highlights interesting or useful test automation content which I read during the current month. This blog post shares 12 interesting or useful blog posts which I read during March 2026. <a rel="NOFOLLOW" class="excerpt_read_more" href="/monthly/clean-test-automation-monthly-3-2026/">Read More</a></p>
<p>The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/953460086/0/petrikainulainen~Clean-Test-Automation-Monthly/">Clean Test Automation Monthly 3 / 2026</a> appeared first on <a rel="NOFOLLOW" href="https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/953460086/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/953460086/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/953460086/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/953460086/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a><h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-3-2025/">Clean Test Automation Monthly 3 / 2025</a></li><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-3-2024/">Clean Test Automation Monthly 3 / 2024</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<p>The Clean Test Automation Monthly is a monthly blog post that shares interesting or useful test automation content which I consumed during the current month. This blog post is always published on the first day of the "next" month.</p>
<p>Let's begin!</p>
<div class="note">
<strong>Table of Contents:</strong></p>
<ul>
<li><a href="#design">Test  Design</a></li>
<li><a href="#backend">Backend</a></li>
<li><a href="#ui-end-to-end">UI / End-to-End</a></li>
</ul>
</div>
<h2 id="design">Test Design</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://testerstories.com/2026/02/ai-and-testing-using-local-models-for-testing/">AI and Testing: Using Local Models for Testing</a> demonstrates how we can use local AI models for generating test cases and Playwright tests.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://testingil.com/2026/03/your-api-tests-are-passing-thats-the-problem.html">Your API Tests Are Passing. That’s the Problem</a> argues that a green API test suite can create a false sense security, especially, if our test suite contains so called shallow assertions.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://bencane.com/posts/2026-03-26/">Generating code faster is only valuable if you can validate every change</a> introduces a testing strategy that helps us to ensure that rapid code generation won't introduce bugs.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/@jaychopra05/the-testing-pyramid-is-a-relic-here-is-what-actually-works-20882083563a">The Testing Pyramid is a Relic. Here is What Actually Works.</a> argues that the testing pyramid doesn't work when we are writing modern distributed systems, and introduces a testing strategy which concentrates on static analysis, integration tests, and observability.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.thegreenreport.blog/articles/who-tests-the-tests-ai-qa-and-the-verification-paradox/who-tests-the-tests-ai-qa-and-the-verification-paradox.html">Who Tests the Tests? AI, QA, and the Verification Paradox</a> explains what "don't trust without verification" means if we generate automated tests with AI.</p>
<h2 id="backend">Backend</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.ontestautomation.com/writing-tests-with-claude-code-part-1-initial-results/">Writing tests with Claude Code - part 1 - initial results</a> describes what the author learned when he used Claude Code for generating automated tests for a Spring Boot REST API.</p>
<h2 id="ui-end-to-end">UI / End-to-End</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.qawolf.com/blog/why-qa-wolf-chose-playwright-over-cypress">Why We Chose Playwright Over Cypress</a> compares Playwright and Cypress, and explains why the author decided to use Playwright.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://elaichenkov.github.io/posts/17-playwright-testing-mistakes-you-should-avoid/">17 Playwright Testing Mistakes You Should Avoid</a> helps us to write better Playwright tests by identifying 17 mistakes we shouldn't make.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://tkdodo.eu/blog/test-ids-are-an-a11y-smell">Test IDs are an a11y smell</a> explains why the author thinks that we shouldn't use <code>data-testid</code> and describes how we can write tests which don't require test ids.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.halfstackdevs.tech/blog/making-code-coverage-work-with-playwright-without-going-insane">Making Code Coverage Work with Playwright</a> explains how we can generate code coverage reports for Playwright tests with <code>@bgotink/playwright-coverage</code>.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.thegreenreport.blog/articles/your-tests-are-green-your-app-is-broken/your-tests-are-green-your-app-is-broken.html">Your Tests Are Green. Your App Is Broken</a> identifies a situation where our application is broken even though our tests pass, and provides one possible solution to this problem.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://timdeschryver.dev/blog/introducing-angular-testing-library-zoneless">Introducing Angular Testing Library Zoneless</a> introduces the new <code>@testing-library/angular/zoneless</code> subpackage which is basically q trimmed down version of the original Angular Testing Library.</p>
<p>The post <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-3-2026/">Clean Test Automation Monthly 3 / 2026</a> appeared first on <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/953460086/0/petrikainulainen">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/953460086/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/953460086/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/953460086/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/953460086/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a><h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-3-2025/">Clean Test Automation Monthly 3 / 2025</a></li><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-3-2024/">Clean Test Automation Monthly 3 / 2024</a></li></ul>&#160;</div>]]>
</content:encoded>
					
					<wfw:commentRss>https://feeds.feedblitz.com/~/953460086/0/petrikainulainen~Clean-Test-Automation-Monthly/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>https://www.petrikainulainen.net/monthly/software-development-monthly-2-2026/</feedburner:origLink>
		<title>Software Development Monthly 2 / 2026</title>
		<link>https://feeds.feedblitz.com/~/950014982/0/petrikainulainen~Software-Development-Monthly/</link>
					<comments>https://feeds.feedblitz.com/~/950014982/0/petrikainulainen~Software-Development-Monthly/#respond</comments>
		
		<dc:creator><![CDATA[Petri Kainulainen]]></dc:creator>
		<pubDate>Thu, 12 Mar 2026 13:53:08 +0000</pubDate>
				<category><![CDATA[Monthly]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Kotlin]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Spring Modulith]]></category>
		<guid isPermaLink="false">https://www.petrikainulainen.net/?p=28990</guid>
					<description><![CDATA[<p>The Software Development Monthly is a monthly blog post that highlights interesting or useful blog posts which I read during the previous month. This blog post shares 25 interesting or useful blog posts which I read during February 2026. <a rel="NOFOLLOW" class="excerpt_read_more" href="/monthly/software-development-monthly-2-2026/">Read More</a></p>
<p>The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/950014982/0/petrikainulainen~Software-Development-Monthly/">Software Development Monthly 2 / 2026</a> appeared first on <a rel="NOFOLLOW" href="https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/950014982/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/950014982/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/950014982/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/950014982/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<p>The Software Development Monthly is a monthly blog post that shares interesting or useful content which I consumed during the previous month. This blog post is always published on the seventh day of the month.</p>
<p>Let's begin!</p>
<div class="note">
<strong>Table of Contents:</strong></p>
<ul>
<li><a href="#ai">AI</a></li>
<li><a href="#sw-development">Software Development</a></li>
</ul>
</div>
<h2 id="ai">AI</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://hbr.org/2026/02/ai-doesnt-reduce-work-it-intensifies-it">AI Doesn’t Reduce Work — It Intensifies It</a> argues that AI causes workload creep where employees will increase their workload until they start to suffer from cognitive fatigue and burnout.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/@jeremydaly/context-is-now-a-first-class-architectural-concern-955eea1ca7e4">Context Is Now a First-Class Architectural Concern</a> explains that context is no longer just data. It's a critical concern that must be designed and limited so that we can ensure that using AI is economically viable.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://openai.com/index/inside-our-in-house-data-agent/">Inside OpenAI’s in-house data agent</a> describes how OpenAPI build an in-house data agent that allows their employees to query over 600 petabytes of internal data and reduces the time it takes to get answers to their questions.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.thepragmaticcto.com/p/lines-of-code-are-back-and-its-worse">Lines of Code Are Back (And It's Worse Than Before)</a> argues that AI-assisted coding has revived the lines of code (LOC) as a primary metric of productivity and explains why LOC is still an awful way to measure productivity.</p>
<p>An AI Agent Published a Hit Piece on Me (<a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://theshamblog.com/an-ai-agent-published-a-hit-piece-on-me/">Part 1</a>, <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://theshamblog.com/an-ai-agent-published-a-hit-piece-on-me-part-2/">Part 2</a>, <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://theshamblog.com/an-ai-agent-published-a-hit-piece-on-me-part-3/">Part 3</a>, and <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://theshamblog.com/an-ai-agent-wrote-a-hit-piece-on-me-part-4/">Part 4</a>) provides a detailed account of an incident where an AI agent published a hit piece against an open source developer who closed a pull request opened by the AI agent.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://chaosguru.substack.com/p/who-opened-the-door">Who opened the door?</a> covers an incident where an AI agent started a smear campaign against a developer and identifies a question that's not asked by anyone else.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://siddhantkhare.com/writing/ai-fatigue-is-real">AI fatigue is real and nobody talks about it</a> argues that even though AI helps us to finish individual tasks faster, it increases the time (and mental energy) needed to coordinate AI agents and review the finished work.</p>
<p>Minions: Stripe’s one-shot, end-to-end coding agents <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents">Part 1</a> and <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents-part-2">Part 2</a> introduces homegrown and unattended AI agents which produce over a thousand merged pull request every week.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://tomwojcik.com/posts/2026-02-15/finding-the-right-amount-of-ai/">What AI coding costs you</a> identifies the negative effects of overrelying on AI tools, and argues that we should find a balance between AI assisted coding and old fashioned manual coding.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://jackcamerano.com/blog/a-message-to-devs-at-the-frontier/">A Message To Devs At The Frontier</a> argues that developers should be curious and embrace the new opportunities instead of simply ignoring AI assisted engineering.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://martinelli.ch/two-flavors-of-spec-driven-development-and-why-i-clearly-prefer-one/">Two Flavors of Spec-Driven Development and Why I Clearly Prefer One</a> introduces two interpretations of spec-driven development and explains why the author thinks that one of them is essential for building business-critical systems.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.scottsmitelli.com/articles/you-dont-have-to/">You don’t have to if you don’t want to</a> is a long and an old-fashioned rant about generative AI.</p>
<h2 id="sw-development">Software Development</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://javaevolved.github.io/">Java has evolved. Your code can too</a> highlights 113 code snippets and allows us to compare the old and modern implementation side by side.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://yieldcode.blog/post/farewell-rust/">Farewell, Rust</a> explains why the author started using Node.js instead of Rust when he is doing web development.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://words.filippo.io/dependabot/">Turn Dependabot Off</a> argues that we shouldn't use Dependabot and explains what we should do instead.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://shiftmag.dev/code-isnt-slowing-your-project-down-communication-is-7889/">Code Isn’t Slowing Your Project Down, Communication Is</a> explains that delays in large organizations are rarely caused by the complexity of the produced code and argues that these delays are caused by poor communication, unclear processes, and clashing priorities.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.jetbrains.com/kotlin/2026/02/building-modular-monoliths-with-kotlin-and-spring/">Building Modular Monoliths With Kotlin and Spring</a> explains why we should consider building modular monoliths and describes how we can build them with Kotlin and Spring Modulith.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.jetbrains.com/idea/2026/02/migrating-to-modular-monolith-using-spring-modulith-and-intellij-idea/">Migrating to Modular Monolith using Spring Modulith and IntelliJ IDEA</a> describes how we can migrate from a traditional monolith to a modular monolith.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://ianbull.com/posts/software-architecture">Sinks, Not Pipes: Software Architecture in the Age of AI</a> introduces techniques that help us to deal with AI agents that lack the long-term memory humans use to navigate poorly structured code bases.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.seangoedecke.com/how-i-estimate-work/">How I estimate work as a staff software engineer</a> explains why estimating is hard, argues that an estimate is a political tool, and describes how the author estimates work.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.jbrains.ca/permalink/deadlines-as-an-act-of-love">Deadlines As An Act Of Love</a> argues that a deadline isn't an attempt to control employees. Instead, deadlines help us to schedule our work and support (or not to support) each other's objectives.</p>
<p>The post <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net/monthly/software-development-monthly-2-2026/">Software Development Monthly 2 / 2026</a> appeared first on <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/950014982/0/petrikainulainen">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/950014982/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/950014982/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/950014982/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/950014982/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&#160;</div>]]>
</content:encoded>
					
					<wfw:commentRss>https://feeds.feedblitz.com/~/950014982/0/petrikainulainen~Software-Development-Monthly/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-2-2026/</feedburner:origLink>
		<title>Clean Test Automation Monthly 2 / 2026</title>
		<link>https://feeds.feedblitz.com/~/949021628/0/petrikainulainen~Clean-Test-Automation-Monthly/</link>
					<comments>https://feeds.feedblitz.com/~/949021628/0/petrikainulainen~Clean-Test-Automation-Monthly/#respond</comments>
		
		<dc:creator><![CDATA[Petri Kainulainen]]></dc:creator>
		<pubDate>Sun, 01 Mar 2026 16:23:50 +0000</pubDate>
				<category><![CDATA[Monthly]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Clean Tests]]></category>
		<category><![CDATA[Mockito]]></category>
		<category><![CDATA[Playwright]]></category>
		<category><![CDATA[Rest Assured]]></category>
		<category><![CDATA[TestNG]]></category>
		<guid isPermaLink="false">https://www.petrikainulainen.net/?p=28951</guid>
					<description><![CDATA[<p>The Clean Test Automation Monthly is a monthly blog post that highlights interesting or useful test automation content which I read during the current month. This blog post shares 16 interesting or useful blog posts which I read during February 2026. <a rel="NOFOLLOW" class="excerpt_read_more" href="/monthly/clean-test-automation-monthly-2-2026/">Read More</a></p>
<p>The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/949021628/0/petrikainulainen~Clean-Test-Automation-Monthly/">Clean Test Automation Monthly 2 / 2026</a> appeared first on <a rel="NOFOLLOW" href="https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/949021628/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/949021628/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/949021628/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/949021628/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a><h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-2-2025/">Clean Test Automation Monthly 2 / 2025</a></li><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-2-2024/">Clean Test Automation Monthly 2 / 2024</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<p>The Clean Test Automation Monthly is a monthly blog post that shares interesting or useful test automation content which I consumed during the current month. This blog post is always published on the first day of the "next" month.</p>
<p>Let's begin!</p>
<div class="note">
<strong>Table of Contents:</strong></p>
<ul>
<li><a href="#design">Test  Design</a></li>
<li><a href="#backend">Backend</a></li>
<li><a href="#ui-end-to-end">UI / End-to-End</a></li>
</ul>
</div>
<h2 id="design">Test Design</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://theqacrew.substack.com/p/how-to-keep-your-smoke-test-suite">How to Keep Your Smoke Testing Useful</a> argues that we should keep our smoke test suite as small (and fast) as possible and concentrate on testing things that matter.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://kiss-and-solid.com/blog/why-tdd-matters">The Big TDD Misunderstanding</a> argues that we should write our tests from the user's perspective and provides four tips that help us to write good tests.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.thegreenreport.blog/articles/a-field-guide-to-not-overengineering-test-automation/a-field-guide-to-not-overengineering-test-automation.html">A Field Guide to Not Overengineering Test Automation</a> describes how we can avoid writing an over-engineered test framework that requires more maintenance than our application.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://testpappy.wordpress.com/2026/01/29/when-you-outsource-testing-to-the-ai-you-loose-the-ability-to-understand-your-system/">When you outsource testing to the AI, you lose the ability to understand your system</a> explains that if we outsource testing to AI, we will loose our mental model of the application because we don't get the understanding that's traditionally gained by writing tests and reading code.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://thetestingpirate.be/posts/2026/2026-01-28_whyaiwontsaveyourflakytests/">Why AI won't save your Flaky Tests</a> argues that if we use AI for fixing flaky tests, we will only hide the architectural issues which cause our tests to fail randomly. </p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/@dingraham01/lessons-i-wish-i-knew-when-i-started-in-test-automation-a97f8d283042">Lessons I Wish I Knew When I Started in Test Automation</a> identifies five lessons the author would have wanted to learn sooner.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.ontestautomation.com/refactoring-the-rest-assured-net-code-with-claude-code/">Refactoring the RestAssured.Net code with Claude Code</a> describes how the author used Claude Code to refactor the codebase of the RestAssured.Net project and explains what the author learned from this experiment.</p>
<h2 id="backend">Backend</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.baeldung.com/java-mockito-dont-mock-collections">Why We Should Not Mock Collections With Mockito</a> explains why we should use real collections instead of mock objects when we are writing tests for code that uses collections (this a good advice for model objects as well).</p>
<p>Data Driven API Testing in Java with Rest-Assured and TestNG: <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/javarevisited/data-driven-api-testing-in-java-with-rest-assured-and-testng-part-1-275795ca2c62">Part 1</a>, <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/javarevisited/data-driven-api-testing-in-java-with-rest-assured-and-testng-part-2-06029e688efe">Part 2</a>, <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/javarevisited/data-driven-api-testing-in-java-with-rest-assured-and-testng-part-3-3eed3cc1e39f">Part 3</a>, <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/javarevisited/data-driven-api-testing-in-java-with-rest-assured-and-testng-part-4-3e90355085d5">Part 4</a>, and <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/javarevisited/data-driven-api-testing-in-java-with-rest-assured-and-testng-part-5-e7fcde4203cc">Part 5</a> describes how we can write data-driven tests with Rest Assured and TestNG (use the friend link if you don't have a Medium account).</p>
<h2 id="ui-end-to-end">UI / End-to-End</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://martinelli.ch/how-i-solved-smtp-timeouts-with-mailpit-and-javamail/">How I solved SMTP Timeouts with Mailpit and JavaMail</a> explains how the author solved a DNS resolution issue which caused test failures when the system under test tried to send an email to localhost.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.thegreenreport.blog/articles/testing-error-boundaries-by-breaking-contracts-not-code/testing-error-boundaries-by-breaking-contracts-not-code.html">Testing Error Boundaries by Breaking Contracts, Not Code</a> argues that we should test our frontend applications by intercepting successful API responses and injecting "contract violations" (such as missing fields or unexpected data types). This helps us to ensure that our UI degrades gracefully instead of crashing.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://tlolkema.substack.com/p/using-agent-skills-to-write-playwright">Using agent skills to write Playwright tests</a> describes how the author generates end-to-end tests by leveraging AI agents.</p>
<p>The post <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-2-2026/">Clean Test Automation Monthly 2 / 2026</a> appeared first on <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/949021628/0/petrikainulainen">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/949021628/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/949021628/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/949021628/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/949021628/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a><h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-2-2025/">Clean Test Automation Monthly 2 / 2025</a></li><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-2-2024/">Clean Test Automation Monthly 2 / 2024</a></li></ul>&#160;</div>]]>
</content:encoded>
					
					<wfw:commentRss>https://feeds.feedblitz.com/~/949021628/0/petrikainulainen~Clean-Test-Automation-Monthly/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>https://www.petrikainulainen.net/monthly/software-development-monthly-1-2026/</feedburner:origLink>
		<title>Software Development Monthly 1 / 2026</title>
		<link>https://feeds.feedblitz.com/~/946239539/0/petrikainulainen~Software-Development-Monthly/</link>
					<comments>https://feeds.feedblitz.com/~/946239539/0/petrikainulainen~Software-Development-Monthly/#respond</comments>
		
		<dc:creator><![CDATA[Petri Kainulainen]]></dc:creator>
		<pubDate>Thu, 12 Feb 2026 16:08:16 +0000</pubDate>
				<category><![CDATA[Monthly]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Quarkus]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Spring AI]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<guid isPermaLink="false">https://www.petrikainulainen.net/?p=28772</guid>
					<description><![CDATA[<p>The Software Development Monthly is a monthly blog post that highlights interesting or useful blog posts which I read during the previous month. This blog post shares 24 interesting or useful blog posts which I read during January 2026. <a rel="NOFOLLOW" class="excerpt_read_more" href="/monthly/software-development-monthly-1-2026/">Read More</a></p>
<p>The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/946239539/0/petrikainulainen~Software-Development-Monthly/">Software Development Monthly 1 / 2026</a> appeared first on <a rel="NOFOLLOW" href="https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/946239539/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/946239539/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/946239539/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/946239539/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<p>The Software Development Monthly is a monthly blog post that shares interesting or useful content which I consumed during the previous month. This blog post is always published on the seventh day of the month.</p>
<p>Let's begin!</p>
<div class="note">
<strong>Table of Contents:</strong></p>
<ul>
<li><a href="#ai">AI</a></li>
<li><a href="#sw-development">Software Development</a></li>
</ul>
</div>
<h2 id="ai">AI</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://python.plainenglish.io/the-death-of-the-code-monkey-why-i-fear-for-the-class-of-2026-13dbf531a76f">We’re not concerned enough about the future of junior-level software engineering</a> explains that because AI has basically removed the need for junior developers, companies will be in serious trouble when the current senior developers and architects retire because there won't be people who can replace them.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.vibe.academy/blog/john-henry-problem-racing-ai">The John Henry Problem - Why Racing Against AI is a Losing Game</a> argues that developers who compete with an AI are winning a race that doesn't matter.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://antirez.com/news/158">Don't fall into the anti-AI hype</a> argues that developers shouldn't ignore AI because of moral reasons and recommends that every developer should test these new AI tools and see if they are helpful for them.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://addyo.substack.com/p/the-80-problem-in-agentic-coding">The 80% Problem in Agentic Coding</a> explains that even though AI can generate "most of the code" quite easily, generating "the rest" is a lot more challenging.</p>
<p>Spring AI Agentic Patterns <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://spring.io/blog/2026/01/13/spring-ai-generic-agent-skills">Part 1</a>, <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://spring.io/blog/2026/01/16/spring-ai-ask-user-question-tool">Part 2</a>, <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://spring.io/blog/2026/01/20/spring-ai-agentic-patterns-3-todowrite">Part 3</a>, <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://spring.io/blog/2026/01/27/spring-ai-agentic-patterns-4-task-subagents">Part 4</a>, and <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://spring.io/blog/2026/01/29/spring-ai-agentic-patterns-a2a-integration">Part 5</a> is a series of blog posts which highlights the features of the spring-ai-agent-utils toolkit that provides agentic patterns for Spring AI.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://info.michael-simons.eu/2026/01/19/some-thoughts-about-using-ai-coding-tools/">Some thoughts about using AI-Coding tools</a> argues that while AI tools can generate decent code, they don't necessarily increase the productivity of an experienced developer.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.sivalabs.in/stepping-into-crazy-ai-world/">Stepping into Crazy AI World</a> argues that developers should pretty much ignore AI hype and concentrate on learning how they can use AI tools for delivering software faster than ever before.</p>
<h2 id="sw-development">Software Development</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.pcloadletter.dev/blog/craftsmanship-is-dead/">Software craftsmanship is dead</a> argues that software development projects tend to favor speed and short-term metrics over writing high-quality and maintainable code.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://addyosmani.com/blog/21-lessons/">21 Lessons From 14 Years at Google</a> identifies the software development lessons gathered from 14 years at Google.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://nesbitt.io/2026/01/02/how-dependabot-actually-works.html">How Dependabot Actually Works</a> describes how Dependabot identifies the required dependency updates and creates PRs.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://addyosmani.com/blog/next-two-years/">The Next Two Years of Software Engineering</a> identifies five crucial questions that will define software engineering for the next two years.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://lab174.com/blog/202601-yaml-norway/">YAML? That’s Norway problem</a> is an interesting and funny post which explains why the country code <code>NO</code> is parsed as <code>false</code>.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://lalitm.com/post/why-senior-engineers-let-bad-projects-fail/">Why Senior Engineers Let Bad Projects Fail</a> explains that sometimes the most "senior" move is to stay silent and let a flawed project fail.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://alexanderfashakin.substack.com/p/make-it-make-sense-nobody-clicked-the-wrong-button">Make It Make Sense</a> argues that massive failures happen when the meaning of data or UI is left implicit.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.frankel.ch/checked-exceptions-lambdas/">Checked exceptions and lambdas</a> identifies three different approaches which help us to use checked exceptions with lambdas.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.baeldung.com/maven-4-upgrades">What’s New in Maven 4</a> highlights the key features of Maven 4.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://quarkus.io/blog/building-large-applications/">Towards faster builds</a> describes how the Quarkus team improved the build time of Quarkus applications when they got feedback that the build time was noticeably higher than the build time of a similar Spring Boot application.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://newsletter.francofernando.com/p/software-design-principles-that-matter">Software Design Principles That Matter</a> identifies three software design principles which help us to build flexible and maintainable code.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.jetbrains.com/idea/2026/01/spring-boot-debugging-now-remote/">Spring Boot Debugging – Now Remote</a> describes how we can debug a remote Spring Boot application with IntelliJ Idea.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://openjdk.org/projects/amber/design-notes/beyond-records">Data-Oriented Programming for Java: Beyond Records</a> introduces the next phase of data-oriented programming for the Java programming language: carrier classes and interfaces.</p>
<p>The post <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net/monthly/software-development-monthly-1-2026/">Software Development Monthly 1 / 2026</a> appeared first on <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/946239539/0/petrikainulainen">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/946239539/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/946239539/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/946239539/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/946239539/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&#160;</div>]]>
</content:encoded>
					
					<wfw:commentRss>https://feeds.feedblitz.com/~/946239539/0/petrikainulainen~Software-Development-Monthly/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-1-2026/</feedburner:origLink>
		<title>Clean Test Automation Monthly 1 / 2026</title>
		<link>https://feeds.feedblitz.com/~/944744150/0/petrikainulainen~Clean-Test-Automation-Monthly/</link>
					<comments>https://feeds.feedblitz.com/~/944744150/0/petrikainulainen~Clean-Test-Automation-Monthly/#respond</comments>
		
		<dc:creator><![CDATA[Petri Kainulainen]]></dc:creator>
		<pubDate>Wed, 04 Feb 2026 16:15:50 +0000</pubDate>
				<category><![CDATA[Monthly]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[JUnit 5]]></category>
		<category><![CDATA[TestContainers]]></category>
		<guid isPermaLink="false">https://www.petrikainulainen.net/?p=28732</guid>
					<description><![CDATA[<p>The Clean Test Automation Monthly is a monthly blog post that highlights interesting or useful test automation content which I read during the current month. This blog post shares 16 interesting or useful blog posts which I read during January 2026. <a rel="NOFOLLOW" class="excerpt_read_more" href="/monthly/clean-test-automation-monthly-1-2026/">Read More</a></p>
<p>The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/944744150/0/petrikainulainen~Clean-Test-Automation-Monthly/">Clean Test Automation Monthly 1 / 2026</a> appeared first on <a rel="NOFOLLOW" href="https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/944744150/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/944744150/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/944744150/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/944744150/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a><h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-1-2025/">Clean Test Automation Monthly 1 / 2025</a></li><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-1-2024/">Clean Test Automation Monthly 1 / 2024</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<p>The Clean Test Automation Monthly is a monthly blog post that shares interesting or useful test automation content which I consumed during the current month. This blog post is always published on the last day of the month.</p>
<p>Let's begin!</p>
<div class="note">
<strong>Table of Contents:</strong></p>
<ul>
<li><a href="#design">Test  Design</a></li>
<li><a href="#backend">Backend</a></li>
<li><a href="#ui-end-to-end">UI / End-to-End</a></li>
</ul>
</div>
<h2 id="design">Test Design</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.ploeh.dk/2026/01/26/ai-generated-tests-as-ceremony/">AI-generated tests as ceremony</a> argues that if we use AI to generate tests after writing our code, we reduce testing to a hollow ceremony and miss the opportunity to see the tests fail before they pass.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.todo.space/2025/12/27/buying-the-right-test-coverage/">Buying the Right Test Coverage (With a Deductible)</a> suggests that we should treat automated tests as an economic trade-off and write only the tests which have an acceptable return of investment.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~www.ministryoftesting.com/articles/back-to-the-basics-rethinking-how-we-use-ai-in-testing">Back to the basics: Rethinking how we use AI in testing</a> argues that AI should be used to support, not replace, human expertise and domain knowledge.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://testerstories.com/2025/12/testing-for-quality-betting-on-value/">Testing for Quality, Betting on Value</a> explains that even though testing can verify if a product works, it cannot ensure that we have built the right thing.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/@deep.naik/stop-chasing-100-coverage-a-pragmatic-frontend-testing-pyramid-60520cd9a00e">Stop Chasing 100% Coverage: A Pragmatic Frontend Testing Pyramid</a> argues that we should concentrate on writing the correct tests instead of chasing the 100% test coverage.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/qualitynexus/automation-is-not-quality-and-never-was-4ea016eddad1">Automation Is Not Quality, And Never Was</a> explains why automated tests don't help us to create "quality".</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/qualitynexus/designing-api-test-coverage-for-microservices-25ebb342e82d">Designing API Test Coverage for Microservices</a> argues that we shouldn't rely on high test coverage percentages. Instead, we should select the required test cases by doing risk-based prioritization.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://foojay.io/today/flaky-tests-a-journey-to-beat-them-all/">Flaky Tests: a journey to beat them all</a> defines the term flaky test and identifies three methods the author used to eliminate them.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://sourcehawk.medium.com/testing-is-not-about-bugs-its-about-becoming-a-better-engineer-6165e465de09">The Thing Everyone Misses About Tests</a> argues that writing tests helps us to become better engineers.</p>
<h2 id="backend">Backend</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://odrotbohm.de/2025/12/rethinking-spring-application-integration-testing/">Rethinking Spring Application Integration Testing</a> argues that Spring integration tests should shift from traditional horizontal slicing to vertical and functional slices.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.baeldung.com/java-testng-rerun-only-failed-tests">How to Execute Tests Selectively in TestNG</a> explores multiple strategies for re-running failed TestNG tests.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://medium.com/@majorbalu/revolutionizing-integration-testing-with-testcontainers-a-modern-enterprise-approach-8f27605f720b">Revolutionizing Integration Testing with TestContainers: A Modern Enterprise Approach</a> explains how we can use Testcontainers for running "real" external services which are used by the system under test.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://eliasnogueira.com/custom-junit-5-extensions-for-testing/">Custom JUnit 5 Extensions for Testing</a> explains how we can simplify our test suites by writing custom JUnit 5 extensions.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://foojay.io/today/testing-emails-with-testcontainers-and-mailpit/">Testing Emails with Testcontainers and Mailpit</a> describes how we can write end-to-end tests for code that sends emails.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://foojay.io/today/introduction-to-behavior-driving-development-with-java-and-mongodb/">Introduction to Behavior Driving Development with Java and MongoDB</a> describes how we can write BDD tests for MongoDB repositories with Java and Cucumber.</p>
<h2 id="ui-end-to-end">UI / End-to-End</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.thegreenreport.blog/articles/automating-push-notification-testing-with-appium/automating-push-notification-testing-with-appium.html">Automating Push Notification Testing with Appium</a> describes how we can write tests which ensure that push notifications are sent and received correctly.</p>
<p>The post <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-1-2026/">Clean Test Automation Monthly 1 / 2026</a> appeared first on <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/944744150/0/petrikainulainen">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/944744150/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/944744150/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/944744150/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/944744150/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a><h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-1-2025/">Clean Test Automation Monthly 1 / 2025</a></li><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-1-2024/">Clean Test Automation Monthly 1 / 2024</a></li></ul>&#160;</div>]]>
</content:encoded>
					
					<wfw:commentRss>https://feeds.feedblitz.com/~/944744150/0/petrikainulainen~Clean-Test-Automation-Monthly/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>https://www.petrikainulainen.net/monthly/software-development-monthly-12-2025/</feedburner:origLink>
		<title>Software Development Monthly 12 / 2025</title>
		<link>https://feeds.feedblitz.com/~/939864599/0/petrikainulainen~Software-Development-Monthly/</link>
					<comments>https://feeds.feedblitz.com/~/939864599/0/petrikainulainen~Software-Development-Monthly/#respond</comments>
		
		<dc:creator><![CDATA[Petri Kainulainen]]></dc:creator>
		<pubDate>Thu, 08 Jan 2026 17:51:42 +0000</pubDate>
				<category><![CDATA[Monthly]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Clean Code]]></category>
		<category><![CDATA[Kotlin]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<guid isPermaLink="false">https://www.petrikainulainen.net/?p=28679</guid>
					<description><![CDATA[<p>The Software Development Monthly is a monthly blog post that highlights interesting or useful blog posts which I read during the previous month. This blog post shares 19 interesting or useful blog posts which I read during December 2025. <a rel="NOFOLLOW" class="excerpt_read_more" href="/monthly/software-development-monthly-12-2025/">Read More</a></p>
<p>The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/939864599/0/petrikainulainen~Software-Development-Monthly/">Software Development Monthly 12 / 2025</a> appeared first on <a rel="NOFOLLOW" href="https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/939864599/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/939864599/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/939864599/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/939864599/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a><h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/software-development-monthly-4-2026/">Software Development Monthly 4 / 2026</a></li><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-3-2026/">Clean Test Automation Monthly 3 / 2026</a></li><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/software-development-monthly-2-2026/">Software Development Monthly 2 / 2026</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<p>The Software Development Monthly is a monthly blog post that shares interesting or useful content which I consumed during the previous month. This blog post is always published on the seventh day of the month.</p>
<p>Let's begin!</p>
<div class="note">
<strong>Table of Contents:</strong></p>
<ul>
<li><a href="#ai">AI</a></li>
<li><a href="#sw-development">Software Development</a></li>
</ul>
</div>
<h2 id="ai">AI</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.thrownewexception.com/does-ai-make-engineers-more-productive-its-complicated/">Does AI make engineers more productive? It’s complicated</a> argues that even though AI helps us to write code faster, it may not improve overall productivity.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.scottlogic.com/2025/12/15/the-specification-renaissance-skills-and-mindset-for-spec-driven-development.html">The Specification Renaissance? Skills and Mindset for Spec-Driven Development</a> argues that as AI-generated code becomes more common, our ability to write clear specifications that define what we want to build becomes the new bottleneck.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://mameli.dev/blog/ai_workflow_eng/">My 2026 Coding Stack</a> highlights the author's AI coding stack for 2026. The author's goal is to maintain flexibility and avoid being locked into a single provider.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://verbosemode.dev/p/from-autocomplete-to-co-author-my">From Autocomplete to Co-Author: My Year with AI</a> reflects on a year of using AI and explains how AI evolved from a simple autocomplete tool to a co-author which generates code that requires minimal changes.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://bytesauna.com/post/insight-debt">On insight debt</a> argues that if we concentrate on shipping features without understanding why they work, we take "insight debt" that makes our code hard to change.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.pcloadletter.dev/blog/pr-review-ai-slop-resilience/">Make your PR process resilient to AI slop</a> argues that AI-generated code isn't a problem as long as we have a proper code review process.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://newsletter.eng-leadership.com/p/ai-coding-tools-are-not-the-problem">AI Coding Tools Are Not the Problem, Lack of Accountability Is</a> argues that the issue with AI-generated code is the lack of accountability when developers ship code without understanding and reviewing it.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://simonwillison.net/2025/Dec/31/the-year-in-llms/">2025: The year in LLMs</a> summarizes the AI breakthroughs of 2025, and highlights the shift toward reasoning models and autonomous agents.</p>
<h2 id="sw-development">Software Development</h2>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.jbrains.ca/permalink/a-central-conflict-in-readable-code">A Central Conflict in 'Readable' Code</a> argues that if we want to make our code simpler, we must be ready to make it less familiar (temporarily).</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://piotrminkowski.com/2025/12/15/grpc-spring/">gRPC in Spring Boot</a> describes how we can use the Spring gRPC project for implementing gRPC endpoints and explains how we can write a gPRC client that invokes our new endpoints.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.baeldung.com/spring-api-versioning">API Versioning in Spring</a> identifies five strategies for implementing API versioning in a Spring Boot web application.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://spring.io/blog/2025/12/18/next-level-kotlin-support-in-spring-boot-4">Next level Kotlin support in Spring Boot 4</a> describes how Spring Boot 4 makes our life easier when we are writing Spring Boot applications with Kotlin.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://blog.jetbrains.com/kotlin/2025/12/the-ultimate-guide-to-successfully-adopting-kotlin-in-a-java-dominated-environment/">The Ultimate Guide to Successfully Adopting Kotlin in a Java-Dominated Environment</a> introduces a five-part tutorial that helps Java developers to adopt Kotlin. This tutorial addresses both technical and organizational challenges which we might face during this transition.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://vladmihalcea.com/spring-transactional-annotation/">The best way to use the Spring @Transactional annotation</a> provides a quick introduction to the <code>@Transactional</code> annotation and describes how the author uses it to configure transaction boundaries.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://github.com/johnousterhout/aposd-vs-clean-code">A Philosophy of Software Design vs Clean Code</a> documents the debate between Robert "Uncle Bob" Martin and John Ousterhout on what's the best way to write clean code.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://loggingsucks.com/">Logging sucks. And here's how to make it better</a> explains why traditional logging sucks, and describes how we can solve this problem and make our logs useful again.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://sushantdhiman.substack.com/p/cs-books-ill-be-reading-in-2026">CS Books I'll be reading in 2026</a> highlights five books the author will read in 2026.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.pcloadletter.dev/blog/clever-code/">Write code that you can understand when you get paged at 2am</a> argues that if we want to prevent on-call disasters, we must prioritize simple and readable code over "clever" abstractions which are impossible to understand in the middle of the night.</p>
<p><a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://sashafoundtherootcauseagain.substack.com/p/the-case-against-microservices">The Case Against Microservices</a> argues that for most organizations, the drawbacks of micro services outweigh their benefits when compared to a well-structured monolith.</p>
<p>The post <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net/monthly/software-development-monthly-12-2025/">Software Development Monthly 12 / 2025</a> appeared first on <a href="http://feeds.feedblitz.com/~/t/0/0/petrikainulainen/~https://www.petrikainulainen.net">Petri Kainulainen</a>.</p>
<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/939864599/0/petrikainulainen">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/939864599/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Add to LinkedIn" href="https://feeds.feedblitz.com/_/16/939864599/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/linkedin20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/939864599/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/939864599/PetriKainulainen"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a><h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/software-development-monthly-4-2026/">Software Development Monthly 4 / 2026</a></li><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/clean-test-automation-monthly-3-2026/">Clean Test Automation Monthly 3 / 2026</a></li><li><a rel="NOFOLLOW" href="https://www.petrikainulainen.net/monthly/software-development-monthly-2-2026/">Software Development Monthly 2 / 2026</a></li></ul>&#160;</div>]]>
</content:encoded>
					
					<wfw:commentRss>https://feeds.feedblitz.com/~/939864599/0/petrikainulainen~Software-Development-Monthly/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments></item>
</channel></rss>

