{"id":1393,"date":"2026-03-12T13:53:09","date_gmt":"2026-03-12T13:53:09","guid":{"rendered":"https:\/\/razvanvancea.ro\/blog\/?p=1393"},"modified":"2026-03-12T14:43:18","modified_gmt":"2026-03-12T14:43:18","slug":"understanding-race-conditions-in-test-automation","status":"publish","type":"post","link":"https:\/\/razvanvancea.ro\/blog\/2026\/03\/12\/understanding-race-conditions-in-test-automation\/","title":{"rendered":"Understanding Race Conditions in Test Automation"},"content":{"rendered":"<div id=\"bsf_rt_marker\"><\/div>\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"1393\" class=\"elementor elementor-1393\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-e09d8a8 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"e09d8a8\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-09c112c\" data-id=\"09c112c\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-45e77dd elementor-widget elementor-widget-text-editor\" data-id=\"45e77dd\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Lately, I\u2019ve been hearing the term \u201crace condition\u201d more and more often &#8211; during conference talks, team discussions, or testing presentations.<\/p><p>Most of the time, it\u2019s mentioned as if everyone already understands it.\u00a0<br \/><br \/>In this article, we\u2019ll break it down in plain language and look at why race conditions matter for software testers &amp; developers.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-7c1bf41 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"7c1bf41\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-10c18c8\" data-id=\"10c18c8\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-93efc3f elementor-widget elementor-widget-heading\" data-id=\"93efc3f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">The idea behind a race condition<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-7c5eafd elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"7c5eafd\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-da8904a\" data-id=\"da8904a\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-fe38158 elementor-widget elementor-widget-text-editor\" data-id=\"fe38158\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>A race condition happens when multiple operations try to access or modify the same resource at the same time, and the final result depends on the timing of those operations.<\/p><p>Think of it like two people racing to complete a task first.<\/p><p>If the outcome changes depending on who finishes first, you have a race condition.<\/p><p>In software, the \u201cracers\u201d are usually:<\/p><ul><li>threads<\/li><li>processes<\/li><li>pervices<\/li><li>API calls<\/li><li>users interacting with the system simultaneously<\/li><\/ul><p>When these actions happen in the wrong order, the system may behave unpredictably.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-9d6537b elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"9d6537b\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-232d50f\" data-id=\"232d50f\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-3e82492 elementor-widget elementor-widget-heading\" data-id=\"3e82492\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Real-world analogy<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-d9822a4 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"d9822a4\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-1d34ae2\" data-id=\"1d34ae2\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-6dca3d0 elementor-widget elementor-widget-text-editor\" data-id=\"6dca3d0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Imagine two coworkers trying to update the same shared spreadsheet.<\/p><ol><li>Both open the file.<\/li><li>Person A changes the value to 10.<\/li><li>Person B changes the value to 15.<\/li><li>Whoever saves last overwrites the other change.<\/li><\/ol><p>The final value depends entirely on who saved last.<\/p><p>The system had no mechanism to coordinate the updates, so the result became unpredictable.<\/p><p>That is essentially a race condition.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-e0fbc53 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"e0fbc53\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-e14c8e3\" data-id=\"e14c8e3\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-8fd4377 elementor-widget elementor-widget-heading\" data-id=\"8fd4377\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">How to reduce race conditions in Playwright?<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-a1135ef elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"a1135ef\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-a3fd70a\" data-id=\"a3fd70a\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-db64ebe elementor-widget elementor-widget-text-editor\" data-id=\"db64ebe\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>A test might work perfectly on a fast local machine but fail intermittently in CI.<\/p><p>When timing changes, the race outcome changes.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-8fcb1e0 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"8fcb1e0\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-867c526\" data-id=\"867c526\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-6b34d6c elementor-widget elementor-widget-text-editor\" data-id=\"6b34d6c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>The key idea is simple:<\/p>\n<p>Wait for meaningful conditions, not time.<\/p>\n<p>Avoid fixed delays like this:<\/p>\n<p><em>await page.waitForTimeout(2000);<\/em><\/p>\n<p>Instead, wait for signals that confirm the system is ready.<\/p>\n<p>Wait for UI state<br><em>await expect(page.locator(&#8216;.dashboard&#8217;)).toBeVisible();<br><\/em><br>Wait for network activity<br><em>await page.waitForResponse(resp =&gt;<\/em><br><em>resp.url().includes(&#8216;\/orders&#8217;) &amp;&amp; resp.status() === 200<\/em><em>);<\/em><\/p>\n<p>Wait for stable UI behavior<br><em>await expect(page.getByText(&#8216;Success&#8217;)).toBeVisible();<\/em><\/p>\n<p>These patterns make tests more deterministic.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-524ee48 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"524ee48\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-b8ae92e\" data-id=\"b8ae92e\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-655656d elementor-widget elementor-widget-heading\" data-id=\"655656d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Practical testing mindset<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-32b71f0 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"32b71f0\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-b6f3490\" data-id=\"b6f3490\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-33c5020 elementor-widget elementor-widget-text-editor\" data-id=\"33c5020\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>When writing automation tests, it helps to ask one simple question:<\/p><p><strong>\u201cWhat exactly tells me the system is ready for the next step?\u201d<\/strong><\/p><p>Not:<\/p><p>\u201cHas enough time passed?\u201d<\/p><p>But:<\/p><p>\u201cWhat signal proves the operation is complete?\u201d<\/p><p>The answer might be:<\/p><ul><li>a visible UI element<\/li><li>a completed network request<\/li><li>a database update reflected in the UI<\/li><\/ul><p>Waiting for the right signal removes the race.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-b78da1e elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"b78da1e\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-acdd58f\" data-id=\"acdd58f\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-97c54db elementor-widget elementor-widget-heading\" data-id=\"97c54db\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Final thoughts<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-234fdd0 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"234fdd0\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-4ac9513\" data-id=\"4ac9513\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-ec23e75 elementor-widget elementor-widget-text-editor\" data-id=\"ec23e75\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Most flaky tests are simply tests that lost the race against the application.<\/p><p>Frameworks like Playwright reduce many timing issues with auto-waiting, but good test design is still essential.<\/p><p>Reliable tests are usually the ones that:<\/p><ul><li>wait for meaningful conditions<\/li><li>avoid arbitrary timeouts<\/li><li>synchronise with the application state<\/li><\/ul><p>In other words, the goal is simple:<\/p><p><strong>Make sure your test and your application are no longer racing each other.<\/strong><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-6f83bc9 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"6f83bc9\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-5d4b90a\" data-id=\"5d4b90a\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-20c55b3 elementor-widget elementor-widget-spacer\" data-id=\"20c55b3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9813b2d elementor-widget elementor-widget-text-editor\" data-id=\"9813b2d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Enjoyed this article?<br \/>I share more practical automation tips on\u00a0<a href=\"https:\/\/www.youtube.com\/c\/LearnwithRV\/videos\" target=\"_blank\" rel=\"noopener\"><strong>YouTube<\/strong><\/a>\u00a0and\u00a0<a href=\"https:\/\/www.linkedin.com\/in\/razvanvancea\/\" target=\"_blank\" rel=\"noopener\"><strong>LinkedIn<\/strong><\/a>.<\/p><p><strong>Need structured guidance instead of learning alone?<\/strong><br \/>I offer\u00a0<strong>1-on-1 mentoring<\/strong>\u00a0&#8211; learn more \u2192\u00a0<strong><a href=\"https:\/\/razvanvancea.ro\/1on1.html\" target=\"_blank\" rel=\"noopener\">HERE<\/a><\/strong><\/p><p>Or email me at\u00a0<strong>iamqarv [at] gmail [dot] com<\/strong><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Lately, I\u2019ve been hearing the term \u201crace condition\u201d more and more often &#8211; during conference&#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[10],"tags":[],"class_list":["post-1393","post","type-post","status-publish","format-standard","hentry","category-programming"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/razvanvancea.ro\/blog\/wp-json\/wp\/v2\/posts\/1393","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/razvanvancea.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/razvanvancea.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/razvanvancea.ro\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/razvanvancea.ro\/blog\/wp-json\/wp\/v2\/comments?post=1393"}],"version-history":[{"count":11,"href":"https:\/\/razvanvancea.ro\/blog\/wp-json\/wp\/v2\/posts\/1393\/revisions"}],"predecessor-version":[{"id":1410,"href":"https:\/\/razvanvancea.ro\/blog\/wp-json\/wp\/v2\/posts\/1393\/revisions\/1410"}],"wp:attachment":[{"href":"https:\/\/razvanvancea.ro\/blog\/wp-json\/wp\/v2\/media?parent=1393"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/razvanvancea.ro\/blog\/wp-json\/wp\/v2\/categories?post=1393"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/razvanvancea.ro\/blog\/wp-json\/wp\/v2\/tags?post=1393"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}