{"data":{"allMarkdownRemark":{"edges":[{"node":{"id":"2cda3518-ba96-5257-97f4-6f0ec1f69eb1","frontmatter":{"category":"Engineering","title":"Bug Police Officer","date":"2023-11-21","summary":"What I present today is how to use police techniques and their mindset to detect and solve bugs in software, so that you can be the best software developer that society can provide.","thumbnail":{"relativePath":"pages/bug-police-officer/bug-police-officer.png","childImageSharp":{"resolutions":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsSAAALEgHS3X78AAAC20lEQVQ4y32S208TURCHF6rvvPpI/Ad8MzFIIlESaAuoAZVehEppd7fQFqjhIgiBQhEUaoFy6wUCghRrCFKQi4orhgQ0XOIFA8FoqOKTaHyg7e54zpYWUOsks2fOmd98Z85mCOIPqyNtUQf33Xp7XOZl+7oEua3AfvpgzkTZo4hIVq9oC8PQGluh7M4hpdYh0fl2aFFfh1a1AcQX2oGUWV0ol2si7bH/auAQsFptE+C4VesUZUnscPxMMxyLa2FXikXsKnIc4zOca9M5hVhbs1cT0fKzuniBkbTnSqU2iBeaA/KMZg47jmVSB9RSDjXW6BXdgv8+mf8vpDMar02qzlMG+gGkKz1cunI06Lkergid3VF1xR3URrRG2k48HZziRf31wxVrzCI01I4HZNQYh73RNBF4P7sAvUZXGdZMOMajcU1E2G3aRjDuJ4I9oAV+fQPY2fB9fbsE2OHHhg9+bkOP0dWENdP9k4JbtIP4C2qinfzq0LQTN8i+I8HTE0eZoak18H8B3/dN1rezyeKYGZx8h5L8pVjbr7EcYoTpnryG8AVLhuqYLk2Dtir/nnfrzQqA7xMLvs/s1uoylObd91ZRvboPRZUxIX2oNtxpB+osZDV0j44mR7wfKy+CRVsHGsM0++oxAwsTL8BgGGUTVAxc0r0EinJ7jXSvLlQXZmBqCTUQHBW6h1YWMhBPLkKfvsi/XprAJimfQbLCw4kVY9xZ5Qxco0ZZCenxn6MYyCmcAwSlcS1m8B3yHzXw066nh8dTtfOQSD3fldETsF12Emq1Fi6BmueSNLNcJjXDjZVL4GEJCSJybjcFaQtQDd8ZYuwDCQgOtWpgMl35CMRZrkCi3MMN5athuVgIomwPpGS7QCx3Q7WmGKrIm1ySfCSAZhNwTfCtQOwDY8v5DrVXO9wZGZ2Qkmb2J6fe5SipGV6XXIE8tKI9CNPMIEy1otjKiZAGa3ENz0MMzPoNzyOqI3a+TN4AAAAASUVORK5CYII=","width":460,"height":325,"src":"/static/19a57f273a6f7441d951955ce11fae27/b3029/bug-police-officer.png","srcSet":"/static/19a57f273a6f7441d951955ce11fae27/b3029/bug-police-officer.png 1x"}}},"authorName":"Bruno Morais","authorDescription":"Bruno is a Senior Software Engineer at AUTO1 Group.","authorAvatar":{"relativePath":"pages/bug-police-officer/avatar.jpeg","childImageSharp":{"resolutions":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAQDAQX/xAAXAQEBAQEAAAAAAAAAAAAAAAABAwIE/9oADAMBAAIQAxAAAAGmbSadPSZMPIBLBy1//8QAHBAAAwABBQAAAAAAAAAAAAAAAQIDIQAQERIj/9oACAEBAAEFAqOVEql2047LLDc7A+i5H//EABcRAQEBAQAAAAAAAAAAAAAAAAEAEBL/2gAIAQMBAT8BC5jP/8QAGREAAwADAAAAAAAAAAAAAAAAAAECEBET/9oACAECAQE/AW9HSSsf/8QAGhAAAQUBAAAAAAAAAAAAAAAAAQACEBEhQf/aAAgBAQAGPwLBZRa4VFYt5Jj/xAAcEAADAAIDAQAAAAAAAAAAAAAAAREhURAxYXH/2gAIAQEAAT8ho6G+i0ElVBP0c6AzfMaH3OHLLoTIz//aAAwDAQACAAMAAAAQcC98/8QAGREAAwADAAAAAAAAAAAAAAAAABExEFGB/9oACAEDAQE/EGQbRPcf/8QAGxEAAgIDAQAAAAAAAAAAAAAAAAERMVFhscH/2gAIAQIBAT8QuM2dElucejs//8QAGxABAQEBAAMBAAAAAAAAAAAAAREAITFBYXH/2gAIAQEAAT8QEiRCoPrgpVComQJxnQidLfOE1gCkvzQ9j4TPv80LcHh6dw+UV3//2Q==","width":50,"height":50,"src":"/static/8d7223890dda036e0121799406a35506/d2d31/avatar.jpeg","srcSet":"/static/8d7223890dda036e0121799406a35506/d2d31/avatar.jpeg 1x,\n/static/8d7223890dda036e0121799406a35506/0b804/avatar.jpeg 1.5x,\n/static/8d7223890dda036e0121799406a35506/753c3/avatar.jpeg 2x,\n/static/8d7223890dda036e0121799406a35506/31ca8/avatar.jpeg 3x"}}},"headerImage":{"relativePath":"pages/bug-police-officer/bug-police-officer.png","childImageSharp":{"resolutions":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsSAAALEgHS3X78AAAC20lEQVQ4y32S208TURCHF6rvvPpI/Ad8MzFIIlESaAuoAZVehEppd7fQFqjhIgiBQhEUaoFy6wUCghRrCFKQi4orhgQ0XOIFA8FoqOKTaHyg7e54zpYWUOsks2fOmd98Z85mCOIPqyNtUQf33Xp7XOZl+7oEua3AfvpgzkTZo4hIVq9oC8PQGluh7M4hpdYh0fl2aFFfh1a1AcQX2oGUWV0ol2si7bH/auAQsFptE+C4VesUZUnscPxMMxyLa2FXikXsKnIc4zOca9M5hVhbs1cT0fKzuniBkbTnSqU2iBeaA/KMZg47jmVSB9RSDjXW6BXdgv8+mf8vpDMar02qzlMG+gGkKz1cunI06Lkergid3VF1xR3URrRG2k48HZziRf31wxVrzCI01I4HZNQYh73RNBF4P7sAvUZXGdZMOMajcU1E2G3aRjDuJ4I9oAV+fQPY2fB9fbsE2OHHhg9+bkOP0dWENdP9k4JbtIP4C2qinfzq0LQTN8i+I8HTE0eZoak18H8B3/dN1rezyeKYGZx8h5L8pVjbr7EcYoTpnryG8AVLhuqYLk2Dtir/nnfrzQqA7xMLvs/s1uoylObd91ZRvboPRZUxIX2oNtxpB+osZDV0j44mR7wfKy+CRVsHGsM0++oxAwsTL8BgGGUTVAxc0r0EinJ7jXSvLlQXZmBqCTUQHBW6h1YWMhBPLkKfvsi/XprAJimfQbLCw4kVY9xZ5Qxco0ZZCenxn6MYyCmcAwSlcS1m8B3yHzXw066nh8dTtfOQSD3fldETsF12Emq1Fi6BmueSNLNcJjXDjZVL4GEJCSJybjcFaQtQDd8ZYuwDCQgOtWpgMl35CMRZrkCi3MMN5athuVgIomwPpGS7QCx3Q7WmGKrIm1ySfCSAZhNwTfCtQOwDY8v5DrVXO9wZGZ2Qkmb2J6fe5SipGV6XXIE8tKI9CNPMIEy1otjKiZAGa3ENz0MMzPoNzyOqI3a+TN4AAAAASUVORK5CYII=","width":600,"height":424,"src":"/static/19a57f273a6f7441d951955ce11fae27/b7ca8/bug-police-officer.png","srcSet":"/static/19a57f273a6f7441d951955ce11fae27/b7ca8/bug-police-officer.png 1x"}}}},"html":"<h3>Table of contents:</h3>\n<ol>\n<li>\n<p>Sense of Security</p>\n<ol>\n<li>Why does feeling safe matter?</li>\n<li>Strategic actions</li>\n<li>A test as a Cop</li>\n</ol>\n</li>\n<li>\n<p>Treat the injured first</p>\n<ol>\n<li>Prioritizing what matters</li>\n<li>The appropriate Mental Model</li>\n<li>Ask before trying to find out</li>\n</ol>\n</li>\n<li>\n<p>Trust your tools</p>\n<ol>\n<li>When less is more</li>\n<li>Efficient distribution of efforts</li>\n<li>Confidence that avoids shame</li>\n</ol>\n</li>\n<li>\n<p>Communication via Radio</p>\n<ol>\n<li>Q-code</li>\n<li>The Language and the Domain</li>\n</ol>\n</li>\n<li>Bug is in jail</li>\n</ol>\n<p><strong>What I present today is how to use police techniques and their mindset to detect and solve bugs in software, so that you can be the best software developer that society can provide.</strong></p>\n<p>For some years, I worked as a police officer in Brazil and I can say that it is a challenging career. The first step was to pass a national test, where knowledge of various laws was required. Criminal laws, traffic laws, and even the laws of physics.</p>\n<p>The second step was to pass a battery of medical exams. Almost perfect health was necessary to be able to practice the profession, in addition to having most of the parts of the human body.</p>\n<p>The third step was the psychological examination. It was necessary to have a clear mind and not have impulses different from those expected from a person who must protect other people.</p>\n<p>As a fourth part, there was also the fitness test, a test in which career candidates had to prove they had sufficient strength and speed to carry out daily police tasks. Running, pull-ups, sit-ups and long jump are examples of what was required.</p>\n<p>The last stage was the Police Academy, where for three months those from now on known as students would learn and prove the learning of several new skills: first aid, use of firearms (pistols, carbines, submachine guns, etc.), non-lethal weapons, martial arts, public policy, and many other disciplines.</p>\n<p>All this so that society receives the best police officer that its people can provide. So, what about using some of the following principles and techniques to become the best software developer that society can provide?</p>\n<h2>Sense of Security</h2>\n<h3>Why does feeling safe matter?</h3>\n<p>Without needing to be a security expert, you already know that it is impossible to have a completely safe city. Even if we reached the point of having perfect police officers, which in itself is impossible, we would not have a police officer for every citizen. In general, the recommendation is 300 police officers for every 100 thousand inhabitants.</p>\n<p>Aware of this limitation, that it is not possible to guarantee complete security for all citizens, police agencies work with the concept of a sense of security. Through strategic actions to combat crime, citizens' feeling that they are safe is increased. This mental condition gives them peace of mind when working, studying, and carrying out their daily tasks.</p>\n<h3>Strategic actions</h3>\n<p>This sense of security also affects criminals. The common visibility of police officers carrying out their duties in strategic places, as well as effective actions to combat crime, make criminals stay away from that place.</p>\n<p>Notice that ending 100% of crime is impossible, what we do well is limit its actions. From here we can extract our first lesson when dealing with software: perfect code, totally bug-free, is impossible.</p>\n<p>Despite this conclusion, the fact that it is impossible does not mean that we should simply ignore the problem. On the contrary, we can, like the police, create strategic actions to combat Bugs. To the point that Bugs themselves will run away from our code.</p>\n<h3>A test as a Cop</h3>\n<p>Test Driven Development - TDD is a strategic action that provides a feeling of security in your code. Before the crime occurs, you position police officers in a specific region. Before the Bug occurs, you position the test in a specific place in your code.</p>\n<p>Robert C. Martin, in his book \"Clean Code: A HandBook of Agile Software Craftsmanship\", teaches us that writing unit tests before writing production code is just the tip of the iceberg in defining TDD. There must be a continuous cycle of improvement, in which there is always a test covering the code you are developing and this security that the code is protected allows you to play with it, and work with it. After all, whatever problem may happen, there is a police-test there to protect you.</p>\n<h2>Treat the injured first</h2>\n<h3>Prioritizing what matters</h3>\n<p>One of the functions of Highway Police Officers is to provide first aid in the event of traffic accidents. There are often serious injuries that must be treated as urgently as possible, as even 1 minute can make the difference between life and death.</p>\n<p>The first step when arriving at a traffic accident site is to mark the location appropriately to prevent other accidents. We must use lighting devices and other appliances to make it clear to other vehicles that there is a danger there.</p>\n<p>The police officer must then check the condition of all the injured to prioritize them according to the severity of each situation.</p>\n<p>Once the treatment of each injured person has been completed and, if necessary, they have been taken to the hospital, it is time to survey the accident site. At this stage, the police officer begins to collect all the information relating to the accident to have sufficient information so that a decision can be made on the cause of the accident and, when applicable, any culprits.</p>\n<h3>The appropriate Mental Model</h3>\n<p>This is the mental model that you and I must adopt when we are faced with a Bug. Although several procedures have been adopted to prevent it from occurring, it is a fatality that can happen. It's like when the highway was well designed, the vehicles were up to date with maintenance, but even so, due to carelessness or misunderstanding on the part of the driver, an accident happens.</p>\n<p>As in the case of traffic accidents, the first step to take is to secure the environment so that the Bug does not cause other problems. If possible, we can revert the application version to one in which the Bug did not appear. We can use a feature flag to temporarily disable a feature. Regardless of the method used to stop the bleeding, the important thing is that we must focus on treating the injured first rather than looking for culprits.</p>\n<p>We have to agree with David Thomas and Andrew Hunt, in their work \"The Pragmatic Programmer: your journey to mastery\" that facing Bugs is a sensitive subject for most developers. Instead of treating the issue as a problem to be solved, some approach it with denial, pointing fingers, lame excuses, or simply apathy. It's exactly the opposite of what is expected!</p>\n<p>Instead of looking for the culprit in a traffic accident, we must first assist the victims and stop the bleeding. In software, instead of finding out who inserted the Bug, we must solve it.</p>\n<h3>Ask before trying to find out</h3>\n<p>When treating an injured person in an emergency, one approach is to use the Glasgow Scale to determine the patient's consciousness. On this scale, one of the components is the verbal response.</p>\n<p>The injured person is asked simple questions, and by analyzing the responses, we can assess the level of consciousness and consequently the level of urgency of their care.</p>\n<p>You and I must carefully read every error message that is displayed during the Bug, it may contain vital information so that we can resolve the problem.</p>\n<p>You may be thinking, but what if there is no error message? If we are just faced with an incorrect result? Well, this also happens in traffic accidents, it is not uncommon for there to be an unconscious victim who cannot answer questions.</p>\n<p>When we discussed the sense of security, we talked about the importance of tests in our application. Go and build a test that can reproduce that Bug, so you can extract the information you need to solve it.</p>\n<p>Think of these tests like the motor tests that highway patrol officers perform on unconscious victims to check their level of consciousness: do the eyes open in response to pain? Is there a pupillary response to light stimulation? Mentally translate this into software language: Does the Bug repeat itself when I enter this and that parameter? And if I insert this new argument, does it happen too?</p>\n<p>To decide on a Bug, data is needed. If you don't receive this data, you must extract it.</p>\n<h2>Trust your tools</h2>\n<h3>When less is more</h3>\n<p>Police work is very complex and your day-to-day job involves the fight for life and protection of the most important assets for society. There would be no point in having a modern and efficient selection and training process for the development of police officers if they were not given the appropriate tools for their work.</p>\n<p>And when I say appropriate, I don't mean they are minimally capable of performing the task, as the result delivered is directly related to the quality and safety of the tools. For an excellent result, not only the police officers but their tools must also be excellent.</p>\n<p>In the police agency I worked for, one of the work tools used was an Austrian pistol known worldwide for its safety and efficiency. The Glock 17 pistol was developed to meet the strict criteria of the Austrian army who wanted to replace the model used during the Second World War.</p>\n<p>In addition to requirements on durability, efficiency, and reliability, safety against accidental firing was one of the pivots of the new model.</p>\n<p>But how did a knife factory manage to deliver the pistol model that would prove to be the safest? Well, it can be said that, in addition to intense testing, the secret to reliability was simplicity and maintainability. The person responsible for the project designed the equipment with as few parts as possible, minimizing complexity. Today the Glock pistol is made with an average of 35 parts, which is a much smaller quantity than other pistols on the market.</p>\n<p>With a simpler design, so-called first-level maintenance is much easier. Equipment users can easily perform maintenance procedures, making the equipment's efficiency last for decades.</p>\n<p>Of course, you must already remember the principle with the acronym KISS, which stands for Keep it Simple (omitting the last word because I don't want to offend the reader). The secret of that renowned pistol model was not in the used materials, but in being simple. The secret of maintaining your software in good shape is to keep it simple, having a specific component for each task. When a problem arises, you will know exactly which component to look for, as each component has a responsibility, this is the principle of Single Responsibility.</p>\n<p>Because of all this, when you are at a shooting range practicing your aim, the police officer knows that if he is not hitting the target, most likely, the error is in his procedure and not in the equipment.</p>\n<p>Allan Kelly, in one of his contributions to the Book \"97 Things Every Programmer Should Know\", corroborates this idea that we should trust our tools when dealing with Bugs. Considering our tools are widely used, mature, and in use by multiple companies, we have little reason to doubt their quality.</p>\n<p>Of course, a prototype, version 0.1, is much more fragile than a library that has been on the market for several years. We are also not saying that it is impossible to have bugs in compilers.</p>\n<p>But considering how rare compiler bugs are, what we are saying is that in the search for a Bug solution, we should trust our tools and look at our piece of code first.</p>\n<h3>Efficient distribution of efforts</h3>\n<p>Imagine it as an efficient distribution of efforts. The library or compiler code has already been reviewed and tested for many years by countless people. As for that little piece of code of yours, only God knows who besides you has looked at it on your team.</p>\n<p>On one of those days, I managed to solve an unpleasant bug that occurred in one of our services. It was a non-deterministic error in our test suite, that is, the Bug only pushed out its head when no one was looking.</p>\n<p>This type of non-deterministic error generally involves three types of origin: multithread, time sensitivity, and dissynchrony between construction and cleaning of test data.</p>\n<p>Analyzing the body of the failed test, after several hours, of course, I began to strongly distrust the way we created timestamps with a native Java library. After all, the test seemed perfect to me, if there was an error it must have been somewhere else.</p>\n<h3>Confidence that avoids shame</h3>\n<p>But, aware of this lesson that we should trust our tools, especially since the component in question had been in Java for 9 years, I ignored this distrust. This saved me a lot of time and embarrassment, as I'm going to share that the error was elsewhere.</p>\n<p>Our test suite ran all tests in a single thread, so it wouldn't be a concurrency issue. But it also ran each test in a deterministic but unpredictable order. Therefore, the source of the intermittent problem must be in some specific order in which the tests were performed.</p>\n<p>After several hours of analyzing the logs, I was able to identify two tests that failed when run in sequence. It turned out that, although our tests performed a test data cleaning routine after each execution, a simple typo had silently overwritten the cleaning method in one of the tests, which generated data inconsistency if such tests were executed in a specific order.</p>\n<h2>Communication via Radio</h2>\n<h3>Q-code</h3>\n<p>I remember that one of the first systems I developed when I worked in the police was one to replace the sending of statistics through radio communication. Many years ago, each police station was supposed to send daily work statistics via radio. Data such as number of people and vehicles inspected, car accidents, etc.</p>\n<p>This took a lot of time as the audio quality of radio communications was not always ideal. The interlocutors spent a lot of time transmitting and confirming each piece of information. All this using Q-Code</p>\n<p>The Q-Code is a standardized collection of three-letter codes used in radio communication. The use of Q-code even in voice transmissions makes communication safer and more efficient. Each set of three letters, always starting with the letter Q, has a specific meaning that is known to the interlocutors.</p>\n<p>I could see that two of those codes were widely used among police officers in radio communication: QAP and QSL.</p>\n<p>QAP was used when you wanted to transmit a message. Let's say someone wanted to talk to me, so he said on the radio: \"Bruno, QAP?\". This could be translated as \"Bruno, are you ready to hear a message?\"</p>\n<p>My answer could be QAP or for example QRM. If I responded with QAP, I was signaling that yes, I was ready to receive the message. If you responded with QRM, I would be informing you that at that moment the communication is being interfered with.</p>\n<p>During communication, the second most used Q-Code appears, QSL. At the end of each message, the sender ends it with the QSL. This means that he is asking the receiver to confirm whether they received the message. It would be something like: \"There is a suspicious vehicle heading towards your team, QSL?\" If I had understood the entire message, I should respond with a simple \"QSL\". In the absence of a response, the sender repeats the message until receiving confirmation from the receiver.</p>\n<p>Each message is concluded with a QSL, and its reception is confirmed with a QSL. Does this remind you of any transmission control protocol out here, used on the internet?</p>\n<p>The main thing here is that a large amount of knowledge is condensed into three letters, in a language that provides interlocutors with efficiency and security. Eric Evans, the author of \"Domain-Driven Design: Tackling Complexity in the Heart of Software\", would agree with me that there is a principle here that should also be adopted in software development.</p>\n<h3>The Language and the Domain</h3>\n<p>A language specific to the domain, which considers possible interference from the environment, a ubiquitous language that is known by all interlocutors, can be the difference between life and death, between success and damnation of a project.</p>\n<p>When a project does not have its own language for that domain, this creates the need for numerous translations between interlocutors. Developers have to translate for domain experts. These, in turn, have to translate their demands to developers. Even among developers, there may be a need for translations.</p>\n<p>All these translations make concepts confusing and the consequences of a lack of mutual understanding can be disastrous.</p>\n<p>The importance of this in trying to arrest a Bug goes much further than compilation errors or exceptions. It goes through the swampy characteristic that the software may be logically working almost perfectly, but it is not delivering what was expected by the stakeholder.</p>\n<p>Let's look at the following pieces of code:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>order<span class=\"token punctuation\">.</span>status <span class=\"token operator\">!=</span> completed<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n     <span class=\"token comment\">// (...)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>order<span class=\"token punctuation\">.</span><span class=\"token function\">isFullyRefunded</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n     <span class=\"token comment\">// (...)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Here we have a small example of two ways of expressing the same situation. In the second piece of code, a common language between developers and domain experts was used. Here, possible logical errors can be easily noticed, without the need to keep in mind what the possible states of the Order are and what the expected state is for that case.</p>\n<p>See the following code:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token class-name\">Payment</span> newPayment <span class=\"token operator\">=</span> payment<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>What do you expect from this code? Does it add ten dollars to the payment? Ten transactions, inbound or outbound? Will the method create a new payment object or will it just change the value of the payment variable and create a new reference called newPayment?</p>\n<p>A lesson also taken from the book \"Clean Code: A HandBook of Agile Software Craftsmanship\" shows that clear communication must also take place between software developers. Functions must communicate exactly what they are doing.</p>\n<p>If you have to look at the function's implementation to know what it's actually doing, that's a big sign that you need to rename it.</p>\n<h2>Bug is in jail</h2>\n<p>I'm very grateful that you've made it this far, you've certainly learned a lot about police activity and how some of its principles can be applied to combat and remove Bugs from your software.</p>\n<p>By applying this knowledge you will be able to work more confidently in your code, giving you peace in your daily life and also allowing you to experiment and discover new things.</p>\n<p>Your aim will be improved and you will get straight to the point, avoiding damage instead of first looking for the culprits. You become bolder and go further because you know you can trust your tools. This leaves you more time to refine your code and seek excellence.</p>\n<p>Finally, not only will your code be safe and efficient, but its result will also be in line with what your customers expect because through effective communication you can accurately deliver what was demanded from you.</p>\n<p>The result of all this is that Bug is in jail, lives are no longer in danger, and you can go home at the end of your shift to enjoy the rest of the day with your family which is looking forward to welcoming their hero back.</p>","fields":{"slug":"/bug-police-officer/","tags":["debugging","testing","TDD","DDD"]}}},{"node":{"id":"d53c49b4-fba1-5071-b078-79bbf0f23344","frontmatter":{"category":"Engineering","title":"A wild Thread appeared! Multithreaded Testing and Thread-safety","date":"2023-02-24","summary":"Today we'll talk a little about how threads work on computers and how to extract more value from concurrent tasks. For this, I will present techniques on how to develop and especially how to test code that uses multiple threads, avoiding the main pitfalls that involve this theme. Of course, along the way, you'll also learn more about Java's Concurrent package, non-blocking algorithms, immutability, and more. However, we need to start by talking a little bit about butter.","thumbnail":null,"authorName":"Bruno Morais","authorDescription":"Bruno is a Senior Software Engineer at AUTO1 Group.","authorAvatar":{"relativePath":"pages/a-wild-thread-appeared-multithreaded-testing-and-thread-safety/avatar.jpeg","childImageSharp":{"resolutions":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAQDAQX/xAAXAQEBAQEAAAAAAAAAAAAAAAABAwIE/9oADAMBAAIQAxAAAAGmbSadPSZMPIBLBy1//8QAHBAAAwABBQAAAAAAAAAAAAAAAQIDIQAQERIj/9oACAEBAAEFAqOVEql2047LLDc7A+i5H//EABcRAQEBAQAAAAAAAAAAAAAAAAEAEBL/2gAIAQMBAT8BC5jP/8QAGREAAwADAAAAAAAAAAAAAAAAAAECEBET/9oACAECAQE/AW9HSSsf/8QAGhAAAQUBAAAAAAAAAAAAAAAAAQACEBEhQf/aAAgBAQAGPwLBZRa4VFYt5Jj/xAAcEAADAAIDAQAAAAAAAAAAAAAAAREhURAxYXH/2gAIAQEAAT8ho6G+i0ElVBP0c6AzfMaH3OHLLoTIz//aAAwDAQACAAMAAAAQcC98/8QAGREAAwADAAAAAAAAAAAAAAAAABExEFGB/9oACAEDAQE/EGQbRPcf/8QAGxEAAgIDAQAAAAAAAAAAAAAAAAERMVFhscH/2gAIAQIBAT8QuM2dElucejs//8QAGxABAQEBAAMBAAAAAAAAAAAAAREAITFBYXH/2gAIAQEAAT8QEiRCoPrgpVComQJxnQidLfOE1gCkvzQ9j4TPv80LcHh6dw+UV3//2Q==","width":50,"height":50,"src":"/static/8d7223890dda036e0121799406a35506/d2d31/avatar.jpeg","srcSet":"/static/8d7223890dda036e0121799406a35506/d2d31/avatar.jpeg 1x,\n/static/8d7223890dda036e0121799406a35506/0b804/avatar.jpeg 1.5x,\n/static/8d7223890dda036e0121799406a35506/753c3/avatar.jpeg 2x,\n/static/8d7223890dda036e0121799406a35506/31ca8/avatar.jpeg 3x"}}},"headerImage":null},"html":"<h1>A wild Thread appeared! Multithreaded Testing and Thread-safety</h1>\n<p><a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/0fc0ab78e60b645d61810b733618e058/a231e/wild_appeared.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 568px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 73.94366197183098%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAAC60lEQVQ4y4VTzU8TURDfszev/jV6MzHxaGLi0YsHSTDGaKBUY2LUGhC/QBCUSktrAWkLLVDaSkERTCr02wKlBftBMUDbLbu03RnnPdgGNOgkv8y8eTO/mZ15K9RqtX2C/C8oisI1AMiSLMuIyG2mD+8rpAuEZoEukBzI9Elg90yyuU0MhiIYCkdxKRjBdDaHqhwWvyuwYDKAgWxQ7T99lAObm3mIL6/C7Nw8DBqMYB91gry/D4eEEkHLCavVKhCYk+NoZ+ysauYTxTJ+GLKi0TSIU14f7knSUcKDDll1tXWFksrlMpYlmYKUOplKyEbY129Gg8GE0Vic5zJ/nZB5fiZXIBELY6kk4ox3HOdnxnHBacHMxro6n3qnlUoFI9EfGPi2gDvb238T6nuHUNfwCJy6x/iiTYcPHj7BtrZ2DLxrxWxylROycVRrhGqF2/VFKDU+rmOEugc6PH3qDGgabkHns1a413wHmm7egOeNVyG5HOfLYEmHYzkJrPsDwm7tfbx09gLoNC04+8mD3iEDfveO4RfPJP88Vfyhr+iasaF3zkkYR/fnUZyYtmImvw5ra0ncLexKFKYVLp+/jhfPXYH2xmvwtEUDrikf1KiqvF+BYrEIdrsdbDY7mC0m6HrTAa+7O0h3kn4FnV0v4ePIMFgsFszlctLeXlkrmE0WHDCYwdTfD/19b8HpdIDDMUZwkO2EkZERlqCQrbgmXYp7yq143B6u2dlqtdZcLpcyPDwsuiYnWgSfbxp3drahWCpBJpuDZDJ5bD7ssxcXFzEajWImk8FIhP6UUJCfE4lE/cmRX8rn8xphaWkJ11PrkM1mIR6Pw8rKCtBbA1EU+TKIEAqFAi+0tbVF81qDYDAIgUAANjY2gK+YJBaLSel0ulmgQPT7/VQ1hOFwGFOpFLIi7Mze3v9E/c8pXqY5Ngl6vX5vYGBANJvNosFgEFXbaDSWyOagOZZoOXXYbDYOsoukizRfsben59d7vf72b8fyJLW9nd3vAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    ></span>\n    <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\"\n        alt=\"wild-appeared\"\n        title=\"\"\n        src=\"/static/0fc0ab78e60b645d61810b733618e058/a231e/wild_appeared.png\"\n        srcset=\"/static/0fc0ab78e60b645d61810b733618e058/01db7/wild_appeared.png 148w,\n/static/0fc0ab78e60b645d61810b733618e058/ede92/wild_appeared.png 295w,\n/static/0fc0ab78e60b645d61810b733618e058/a231e/wild_appeared.png 568w\"\n        sizes=\"(max-width: 568px) 100vw, 568px\"\n      />\n  </span>\n  </a></p>\n<p>Today we'll talk a little about how threads work on computers and how to extract more value from concurrent tasks. For this, I will present techniques on how to develop and especially how to test code that uses multiple threads, avoiding the main pitfalls that involve this theme.</p>\n<p>Of course, along the way, you'll also learn more about Java's Concurrent package, non-blocking algorithms, immutability, and more. However, we need to start by talking a little bit about butter.</p>\n<p>Butter is a product that is part of everyday life for many people. Present in cookies, cakes, bread, sweets, and snacks, as well as other culinary items that make our mouths water just imagining.</p>\n<p>Butter is not recent; we have historical records of its manufacturing process over 2500 BC. Most often made with cow's milk but it can also be produced with the milk of other mammals such as sheep, goats, and buffalo.</p>\n<p>Salt has been added to butter since ancient times as a method of preservation, but over time salt has lost this importance as the supply chain has become generally refrigerated. Today, so to speak, salt is added only for taste.</p>\n<p>Sometimes food colorings are added to butter, in Brazil, for example, it is common to use Annatto seeds.</p>\n<p>And one thing I really like to eat is bread and butter. In fact, a delicious slice of bread just out of the oven with a little butter on top, which starts to melt on the hot bread. Oh, how delicious!</p>\n<p>Sadly, my wife happens to like hazelnut cream on top of her bread. And this created a problem with our breakfast, now we have to get two knives dirty to apply the toppings that we like. A knife for the butter, and another knife for the hazelnut cream.</p>\n<p>However, our concern for the environment and its natural resources, which are not unlimited, made us rethink this process.</p>\n<p>Let's turn this problem into a software. After all, Moore's law has given us processors with more and more cores, and as nowadays virtually all computers have multiple execution cores, a computer must be able to simulate my kitchen.</p>\n<p>First, we need a straightforward Bread that takes 50 milliseconds to be ready (what a blazing fast oven, huh!?)</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">Bread</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">private</span> <span class=\"token class-name\">String</span> name <span class=\"token operator\">=</span> <span class=\"token string\">\"bread\"</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token keyword\">public</span> <span class=\"token class-name\">Bread</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">try</span> <span class=\"token punctuation\">{</span>\n           <span class=\"token class-name\">TimeUnit</span><span class=\"token punctuation\">.</span>MILLISECONDS<span class=\"token punctuation\">.</span><span class=\"token function\">sleep</span><span class=\"token punctuation\">(</span><span class=\"token number\">50</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">InterruptedException</span> e<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n           <span class=\"token class-name\">Thread</span><span class=\"token punctuation\">.</span><span class=\"token function\">currentThread</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">interrupt</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token punctuation\">}</span>\n   <span class=\"token punctuation\">}</span>\n\n   <span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">setTopping</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> toppingName<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>name <span class=\"token operator\">+=</span> <span class=\"token string\">\" with \"</span> <span class=\"token operator\">+</span> toppingName<span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n\n   <span class=\"token annotation punctuation\">@Override</span>\n   <span class=\"token keyword\">public</span> <span class=\"token class-name\">String</span> <span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">return</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>name<span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Now we need a naive knife that can apply the topping to our bread.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">Knife</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">private</span> <span class=\"token class-name\">String</span> topping<span class=\"token punctuation\">;</span>\n\n   <span class=\"token keyword\">public</span> <span class=\"token class-name\">Knife</span> <span class=\"token function\">setTopping</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> topping<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>topping <span class=\"token operator\">=</span> topping<span class=\"token punctuation\">;</span>\n       <span class=\"token keyword\">return</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token punctuation\">}</span>\n\n   <span class=\"token keyword\">public</span> <span class=\"token class-name\">Knife</span> <span class=\"token function\">applyToppingTo</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Bread</span> bread<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>topping <span class=\"token operator\">!=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n           bread<span class=\"token punctuation\">.</span><span class=\"token function\">setTopping</span><span class=\"token punctuation\">(</span>topping<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n           topping <span class=\"token operator\">=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">;</span>\n       <span class=\"token punctuation\">}</span>\n       <span class=\"token keyword\">return</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>We can verify that everything is working using a test. I'm using the <a href=\"https://assertj.github.io/doc/\"><ins>AssertJ</ins></a> library, a java assertion library which I do recommend that you have a look on at, as it could enhance your tests and improve readability.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Test</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">givenKnifeWhenApplyToppingToThenChangeBreadName</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">var</span> knife <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Knife</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> bread <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Bread</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n   knife<span class=\"token punctuation\">.</span><span class=\"token function\">setTopping</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"butter\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">applyToppingTo</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token function\">assertThat</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">hasToString</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"bread with butter\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>It seems good, lets's see what happens when we are hungry and want 10 pieces of bread made at the same time! For that, we will need a basket where we will put all the cooked bread.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Test</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">givenHungryThenCook10BreadsAtTheSameTime</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">var</span> basket <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ArrayList</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Bread</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> knife <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Knife</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> <span class=\"token number\">10</span><span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">var</span> bread <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Bread</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       knife<span class=\"token punctuation\">.</span><span class=\"token function\">setTopping</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"butter\"</span><span class=\"token punctuation\">)</span>\n               <span class=\"token punctuation\">.</span><span class=\"token function\">applyToppingTo</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       basket<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n   <span class=\"token function\">assertThat</span><span class=\"token punctuation\">(</span>basket<span class=\"token punctuation\">)</span>\n           <span class=\"token punctuation\">.</span><span class=\"token function\">isNotEmpty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n           <span class=\"token punctuation\">.</span><span class=\"token function\">allSatisfy</span><span class=\"token punctuation\">(</span>bread <span class=\"token operator\">-></span> <span class=\"token function\">assertThat</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">hasToString</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"bread with butter\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Oops!, it worked, but it took too much time. Each bread takes 50 milliseconds to be ready, so now the whole process is taking 500 milliseconds. If we consider the real-world cook time for bread, it could take hours to cook all those pieces of bread like this.</p>\n<h2>Multiple Threads</h2>\n<p>I know what to do, we just need more workforce! I will call my wife to help me. As I said, the majority of current computer machines have more than one core, which allows us to work in parallel. Joshua Bloch, in his book Effective Java, warns that we should prefer executors, tasks, and streams to threads, but for simplicity let me demonstrate this problem using threads by hand.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Test</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">givenHungryThenCook10BreadsWithMyWife</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">var</span> basket <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ArrayList</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Bread</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> knife <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Knife</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token class-name\">Runnable</span> preparation <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">var</span> bread <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Bread</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       knife<span class=\"token punctuation\">.</span><span class=\"token function\">setTopping</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"butter\"</span><span class=\"token punctuation\">)</span>\n               <span class=\"token punctuation\">.</span><span class=\"token function\">applyToppingTo</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       basket<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> <span class=\"token number\">5</span><span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">var</span> me <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Thread</span><span class=\"token punctuation\">(</span>preparation<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token keyword\">var</span> myWife <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Thread</span><span class=\"token punctuation\">(</span>preparation<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       me<span class=\"token punctuation\">.</span><span class=\"token function\">start</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       myWife<span class=\"token punctuation\">.</span><span class=\"token function\">start</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n   <span class=\"token function\">assertThat</span><span class=\"token punctuation\">(</span>basket<span class=\"token punctuation\">)</span>\n           <span class=\"token punctuation\">.</span><span class=\"token function\">isNotEmpty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n           <span class=\"token punctuation\">.</span><span class=\"token function\">allSatisfy</span><span class=\"token punctuation\">(</span>bread <span class=\"token operator\">-></span> <span class=\"token function\">assertThat</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">hasToString</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"bread with butter\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>But wait, the test is failing, what is going wrong?</p>\n<div class=\"gatsby-highlight\" data-language=\"tex\"><pre class=\"language-tex\"><code class=\"language-tex\">java.lang.AssertionError: \nExpecting actual not to be empty</code></pre></div>\n<p>It is like the basket is empty, but we didn't change the process at all despite adding the new threads. Yes, it is a common problem that every software engineer faces when starting to work with multiple threads (or multi-thread apps).</p>\n<h2>Java's Concurrent Package</h2>\n<p>In fact, there is a thread that is responsible for running the test suite which executes each step on our test in sequential order. But when we delegate part of the process to other threads, it follows its flow without waiting for them to finish their job. When it reaches the assertion, the previously created threads have not finished creating their bread. That is why our basket is empty.</p>\n<p>Please, don't listen to this evil inner thought suggesting that it is just a matter of creating a Thread.sleep() or something like that, so that the assertion waits for the other threads. It will give you a slow and fragile test. On one hand, if you give it a big delay time, it will slow down your tests. On the other hand, with a small delay, the result could vary depending on the processing power of the machine where the tests are being executed.</p>\n<h3>Testing</h3>\n<p>The answer for cases like those is to use some tools from java's concurrent package. We have to ensure that both workers start to do their job at the same time. As a second requirement, we need that the test thread verifies the assertion only after the job is done by the other threads. For this, we can use a CountDownLatch like those below. CountDownLatch is a synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. It does it by holding the thread until the count reaches 0.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Test</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">givenHungryThenCook10BreadsWithMyWife</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token class-name\">InterruptedException</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">var</span> basket <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ArrayList</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Bread</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> knife <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Knife</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> startGate <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">CountDownLatch</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> endGate <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">CountDownLatch</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token class-name\">Runnable</span> preparation <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">try</span> <span class=\"token punctuation\">{</span>\n           startGate<span class=\"token punctuation\">.</span><span class=\"token function\">await</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">InterruptedException</span> e<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n           <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">RuntimeException</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token punctuation\">}</span>\n       <span class=\"token keyword\">var</span> bread <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Bread</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       knife<span class=\"token punctuation\">.</span><span class=\"token function\">setTopping</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"butter\"</span><span class=\"token punctuation\">)</span>\n               <span class=\"token punctuation\">.</span><span class=\"token function\">applyToppingTo</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       basket<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       endGate<span class=\"token punctuation\">.</span><span class=\"token function\">countDown</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> <span class=\"token number\">5</span><span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">var</span> me <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Thread</span><span class=\"token punctuation\">(</span>preparation<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token keyword\">var</span> myWife <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Thread</span><span class=\"token punctuation\">(</span>preparation<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       me<span class=\"token punctuation\">.</span><span class=\"token function\">start</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       myWife<span class=\"token punctuation\">.</span><span class=\"token function\">start</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n\n   startGate<span class=\"token punctuation\">.</span><span class=\"token function\">countDown</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   endGate<span class=\"token punctuation\">.</span><span class=\"token function\">await</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token function\">assertThat</span><span class=\"token punctuation\">(</span>basket<span class=\"token punctuation\">)</span>\n           <span class=\"token punctuation\">.</span><span class=\"token function\">hasSize</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">)</span>\n           <span class=\"token punctuation\">.</span><span class=\"token function\">allSatisfy</span><span class=\"token punctuation\">(</span>bread <span class=\"token operator\">-></span> <span class=\"token function\">assertThat</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">hasToString</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"bread with butter\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The startGate will hold all threads so that they start virtually at the same time when the test execution reaches the startGate.countDown(). After that, the assertion will not be verified before the endGate reaches zero, which will only happen when all threads have finished their tasks.</p>\n<p>The bad news is that we have a problem with this current implementation. If you are unlucky enough (or simply repeat this test a few times), you will face the following error:</p>\n<div class=\"gatsby-highlight\" data-language=\"tex\"><pre class=\"language-tex\"><code class=\"language-tex\">java.lang.AssertionError: \nExpected size:&lt;10&gt; but was:&lt;6&gt; in:\n&lt;[bread with butter,\n    bread with butter,\n    bread with butter,\n    bread with butter,\n    bread with butter,\n    bread with butter]&gt;</code></pre></div>\n<p>It happened because we are using as our basket an ArrayList, which states in its documentation:</p>\n<p>\"<em>Note that this implementation <strong>is not synchronized</strong>. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally.</em>\"</p>\n<h3>Synchronized Collections</h3>\n<p>In other words, this implementation of the List interface is not thread-safe. Once more, to face this issue, we have at our disposal other collection implementations on the concurrent package. Instead of ArrayList, we could use CopyOnWriteArrayList or a ConcurrentLinkedQueue.</p>\n<p>As the first one is more efficient in use cases where mutations are less frequent than other operations, let's stick with ConcurrentLinkedQueue.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">var</span> basket <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ConcurrentLinkedQueue</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>But as soon as you execute the test repeatedly, you will see errors like those:</p>\n<div class=\"gatsby-highlight\" data-language=\"tex\"><pre class=\"language-tex\"><code class=\"language-tex\">java.lang.AssertionError: \nExpecting all elements of:\n  &lt;[bread with butter,\n    bread with butter,\n    bread with butter,\n    bread with butter,\n    bread with null,\n    bread with null,\n    bread with butter,\n    bread with butter,\n    bread with butter,\n    bread with butter]&gt;\nto satisfy given requirements, but these elements did not:\n\n  &lt;bread with null&gt; \nExpecting actual&#39;s toString() to return:\n  &lt;&quot;bread with butter&quot;&gt;\nbut was:\n  &lt;bread with null&gt;</code></pre></div>\n<p>We should have a problem in another part of the code, could you imagine where it is?</p>\n<p>Things get worse when my wife starts to make her bread with hazelnut cream:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Test</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">givenHungryThenCook10BreadsWithMyWife</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token class-name\">InterruptedException</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">var</span> basket <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ConcurrentLinkedQueue</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> knife <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Knife</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> startGate <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">CountDownLatch</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> endGate <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">CountDownLatch</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token class-name\">Function</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">Runnable</span><span class=\"token punctuation\">></span></span> preparation <span class=\"token operator\">=</span> topping <span class=\"token operator\">-></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">try</span> <span class=\"token punctuation\">{</span>\n           startGate<span class=\"token punctuation\">.</span><span class=\"token function\">await</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">InterruptedException</span> e<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n           <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">RuntimeException</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token punctuation\">}</span>\n       <span class=\"token keyword\">var</span> bread <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Bread</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       knife<span class=\"token punctuation\">.</span><span class=\"token function\">setTopping</span><span class=\"token punctuation\">(</span>topping<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">applyToppingTo</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       basket<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       endGate<span class=\"token punctuation\">.</span><span class=\"token function\">countDown</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> <span class=\"token number\">5</span><span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">var</span> me <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Thread</span><span class=\"token punctuation\">(</span>preparation<span class=\"token punctuation\">.</span><span class=\"token function\">apply</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"butter\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       me<span class=\"token punctuation\">.</span><span class=\"token function\">start</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token keyword\">var</span> myWife <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Thread</span><span class=\"token punctuation\">(</span>preparation<span class=\"token punctuation\">.</span><span class=\"token function\">apply</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"hazelnut cream\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       myWife<span class=\"token punctuation\">.</span><span class=\"token function\">start</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n\n   startGate<span class=\"token punctuation\">.</span><span class=\"token function\">countDown</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   endGate<span class=\"token punctuation\">.</span><span class=\"token function\">await</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token function\">assertThat</span><span class=\"token punctuation\">(</span>basket<span class=\"token punctuation\">)</span>\n           <span class=\"token punctuation\">.</span><span class=\"token function\">hasSize</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">)</span>\n           <span class=\"token punctuation\">.</span><span class=\"token function\">haveExactly</span><span class=\"token punctuation\">(</span><span class=\"token number\">5</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Condition</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span>bread <span class=\"token operator\">-></span> bread<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">contains</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"butter\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"butter bread\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n           <span class=\"token punctuation\">.</span><span class=\"token function\">haveExactly</span><span class=\"token punctuation\">(</span><span class=\"token number\">5</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Condition</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span>bread <span class=\"token operator\">-></span> bread<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">contains</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"hazelnut\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"hazelnutcream bread\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>First, notice the use of a new helper method from AssertJ, we specified that the collection should have exactly 5 items that satisfy a condition.</p>\n<p>The Condition entity from the AssertJ library helps us to create a whole new set of assertions. If you are interested, please take a look at a delicious example in the appendix of this article.</p>\n<p>But let's come back to our bread story. After executing the test now with hazelnut cream, sometimes we face errors that are even strange:</p>\n<div class=\"gatsby-highlight\" data-language=\"tex\"><pre class=\"language-tex\"><code class=\"language-tex\">java.lang.AssertionError: \nExpecting elements:\n&lt;[bread with hazelnut cream,\n    bread with hazelnut cream,\n    bread with hazelnut cream,\n    bread with hazelnut cream,\n    bread with butter,\n    bread with hazelnut cream,\n    bread with butter,\n    bread with butter,\n    bread with hazelnut cream,\n    bread with hazelnut cream]&gt;\n to have exactly 5 times &lt;butter bread&gt;</code></pre></div>\n<p>Why do we have only 3 bread with butter, but 7 bread with hazelnut cream?</p>\n<h2>Summary so far</h2>\n<p>Before advancing, let's recap what we have seen until now:</p>\n<ul>\n<li>\n<p>Most today's computers have multiple cores, allowing us to get even more value from concurrent tasks;</p>\n</li>\n<li>\n<p>Working with multiple threads creates some difficulties when we depend on timing to verify our tests' assertions, nothing that couldn't be handled using tools from java's Concurrent package, like CountDownLatch;</p>\n</li>\n<li>\n<p>AssertJ is a java assertion library that helps us to improve our tests also on their readability.</p>\n</li>\n<li>\n<p>We should keep in mind that not all classes are thread-safe, like ArrayList for example. When many threads will share access to a common collection, we should use one of the thread-safe Collection implementations from the Concurrent package;</p>\n</li>\n</ul>\n<p>Ok, with all that knowledge in mind let's figure out what is the reason for the weird errors that we are facing.</p>\n<h2>Thread-safety</h2>\n<h3>Race Condition</h3>\n<p>First of all, this is a typical symptom of a Race Condition, or more specifically, a Data Race. Quoting Brian Goetz, in the book Java Concurrency in Practice</p>\n<p>\"<em>A race condition occurs when the correctness of a computation depends on the relative timing or interleaving of multiple threads by the runtime; in other words, when getting the right answer relies on lucky timing.</em>\"</p>\n<p>On our baking issue, we have multiple threads fighting to access the same shared property. My wife and I are fighting for toppings at the same knife.</p>\n<p>In the real world, one could think of it like this:</p>\n<ol>\n<li>\n<p>I get my knife and put butter on that;</p>\n</li>\n<li>\n<p>Just when I leave the knife to take the bread, my wife gets that knife and puts hazelnut cream on it;</p>\n</li>\n<li>\n<p>I take back the knife and, with tears in my eyes, realize that I'm topping my bread with some strange brown cream;</p>\n</li>\n<li>\n<p>Now my wife with her bread in hand stares at an empty knife, trying to figure out who is sabotaging her.</p>\n</li>\n</ol>\n<p><a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/1ff9d1c27bf3ef283302379138cd5bed/f680c/Race-Condition.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 420px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 70.95238095238095%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsSAAALEgHS3X78AAACJElEQVQ4y21TyY7TQBDNJ/EjCPEViAtXOCEOiOXGjobRhJFgBpGQ3fHSbXe3ux3b8WQYBBckLnxJPbqdzZ5weKpyLa+2dsefTIgHnPwZp2DWlDGFHqfxSNL7jxUdnS5pMhIUeGvfNobNGZ1/NTQYpMS9KXVUFFEhNDxviZlFU24xmVYYjFdr+7wdFwYFuue/0BteYZFE6ER+RB/mPyCFomWaUKEElamo5RalRaVjWghZo1Rtv8tbakEiZNThvk/B9AiCM9KJQX94AR5lWEiJTKgaTvfnOb70LyG5bvkcTB2TQkYMHc+P6Y1XYhwZKm1gFCyQxmkrKVcSLMwQ+Hltv14sE86m1oRJEFImjTOSc7rkw4S1LBq+vEXcIBRhRMZUyKR2+2kRXe+m6XOjq90kDUI2m9PrkzMEVhZpWjvzTcJoYi85K6CTfaf1+EGGs953CGbq2BahN/ao+/YRhv0+ldrYBe+7Go4rTGdle5+bYm7X/x2Z2UfdjX9jygt7FNEIkDDJXs/EFutu27tu7tAeZaViFDKh3RHknmix0bdJmZAH+zy8sjLQsSbnMPavqYPtu8pTXQc65KlZ6yptdCtbxTaEEalwYY2ajCzwp3yIv9U9VPkKT+/cxPO7t3B1+RPdZw9w//YNaM52hXJL7uD0wkrFODrh1CMZJfaDkWQCF/IYlTyxj1vg88sn6B2/ck8K37rv8OnFY8gwRMrjOrkJZ+NzH/8AC+N/l13ojqEAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    ></span>\n    <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\"\n        alt=\"Race-Condition\"\n        title=\"\"\n        src=\"/static/1ff9d1c27bf3ef283302379138cd5bed/f680c/Race-Condition.png\"\n        srcset=\"/static/1ff9d1c27bf3ef283302379138cd5bed/4c3b3/Race-Condition.png 148w,\n/static/1ff9d1c27bf3ef283302379138cd5bed/d72a6/Race-Condition.png 295w,\n/static/1ff9d1c27bf3ef283302379138cd5bed/f680c/Race-Condition.png 420w\"\n        sizes=\"(max-width: 420px) 100vw, 420px\"\n      />\n  </span>\n  </a></p>\n<p>It could only work if each one of us does the topping at the perfect timing, that is, only getting the knife when the work of the other one is done.</p>\n<p><a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/9eb569fa960bd58a894af409fce7ccca/f680c/Race-Condition-Lucky-timming.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 420px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 70.95238095238095%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsSAAALEgHS3X78AAACKklEQVQ4y3VSy47TQBDMt/Ax/AcnjnBHSFwBiQMs4iGR5UACyZJsYo8f47E9Mx4/kpDdRUJCe0f8RhczdhI57O6h1D1d45ruag/C5ZJEJCj0BUV+FzukFDNBi3NJ70439P7zmpbneVtzXLS7kwQJjSeGZjNNgnk0UJxTkxdgbA3fgu2wz4NgjaW3wXyxhedvDvz+Thw1GI5/YTq/QpVxDHjI6WPwEzJXtNYZNSqnlXbocpOpNnfcyp6bW+C4dZFTHic0EGFIkfcBuUioyAzO5j+QcgOdanz7fgHfb1ArCZMrlHfAcZXUkDzBgIUpnbAVFtzQSkrwqEKRadjOWjEnXNl6X6B/7nJpo+oEsyimUhpXJEe6blzs532Rfayl7An3BPOYkzEblLKgKpd3dlHJY3EpCqhD9z3BxA/ozacRIhsbrXfkzRHDoLab3iCz/oq4xJfpJfLEtJ0eCbIFo+HbZ5ifndGqMNbgjnTYC7qPEisymW1bT5Xtznl968iJ/amH6TU80dil5Df86sNkPX/t3ds9tEvZqhSNzKgTOfaw2l0ue7HFf7XjLSuDItXUvaZxM9qOtOmsUPqQ16o4PNAT5KTiyo5TUq0U/mwf4rp5YTuo8Xf7AL/rV6iLC/DZVzy6fw9sfApvNMRjmyfzKVambqdo7EMqERjEHiPJU3cgLTgu1QmabAItElyp16jTSbuIyH48fP4EwluCTUY4ffkUKfMtl7VCWqQQQYh/P3d/SRDg4P0AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    ></span>\n    <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\"\n        alt=\"Race-Condition-Lucky-timming\"\n        title=\"\"\n        src=\"/static/9eb569fa960bd58a894af409fce7ccca/f680c/Race-Condition-Lucky-timming.png\"\n        srcset=\"/static/9eb569fa960bd58a894af409fce7ccca/4c3b3/Race-Condition-Lucky-timming.png 148w,\n/static/9eb569fa960bd58a894af409fce7ccca/d72a6/Race-Condition-Lucky-timming.png 295w,\n/static/9eb569fa960bd58a894af409fce7ccca/f680c/Race-Condition-Lucky-timming.png 420w\"\n        sizes=\"(max-width: 420px) 100vw, 420px\"\n      />\n  </span>\n  </a></p>\n<p>About our code, we have at least two problems in it: 1) we set the topping and add it to the bread in two different steps; and 2) when we add the topping to the bread, its removal from the knife also occurs in a separate step.</p>\n<p>Because of that, just before a thread applies the topping to the bread, another thread could change the topping or even remove it. And again, just before removing the topping from the knife, another thread could use that knife to add topping to other bread.</p>\n<p>That is why in the last two test logs we got some bread without topping, and more bread with one of the toppings than the other.</p>\n<h3>Atomicity</h3>\n<p>We wrote those naive classes just to enlighten the lack of atomicity in them, but even single-line codes like <code class=\"language-text\">++i</code> are not atomic, in fact, it comprehends three operations: 1) get the value; 2) add one to it; and 3) update the value back.</p>\n<p>What we should do is enforce the concept of atomicity, which means that each of our tasks should be considered as one. One indivisible task, an atom.</p>\n<p>Java has a built-in mechanism that allows us to achieve atomicity, which is called “synchronized block”.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">synchronized</span><span class=\"token punctuation\">(</span>lock<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token comment\">// Code that handles the shared memory</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>We can use any java object to act as a lock, and it will ensure that only one thread that acquires that lock will be able to execute the code within. When the thread finishes its job, it releases that lock so that other threads could do the same thing.</p>\n<p>It is also allowed to create a synchronized method, just by adding the synchronized keyword before the return type of the method. Doing so, the lock will be the object on which the method is being invoked.</p>\n<p>Ok, let's stop talking, and let's get our hands dirty!</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Test</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">givenHungryThenCook10BreadsWithMyWife</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token class-name\">InterruptedException</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">var</span> basket <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ConcurrentLinkedQueue</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> knife <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Knife</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> startGate <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">CountDownLatch</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> endGate <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">CountDownLatch</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token class-name\">Function</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">Runnable</span><span class=\"token punctuation\">></span></span> preparation <span class=\"token operator\">=</span> topping <span class=\"token operator\">-></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">try</span> <span class=\"token punctuation\">{</span>\n           startGate<span class=\"token punctuation\">.</span><span class=\"token function\">await</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">InterruptedException</span> e<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n           <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">RuntimeException</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token punctuation\">}</span>\n       <span class=\"token keyword\">synchronized</span> <span class=\"token punctuation\">(</span>knife<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n           <span class=\"token keyword\">var</span> bread <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Bread</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n           knife<span class=\"token punctuation\">.</span><span class=\"token function\">setTopping</span><span class=\"token punctuation\">(</span>topping<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">applyToppingTo</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n           basket<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span>bread<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n           endGate<span class=\"token punctuation\">.</span><span class=\"token function\">countDown</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token punctuation\">}</span>\n   <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token comment\">// (...) omitted for brevity</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Now the fix of our code is just a matter of adding a synchronized block using the knife as the lock. With this, only one thread at a time can take the knife and execute the code inside it.</p>\n<h3>Thread blocking</h3>\n<p>\"Oh! This is the solution for everything, we should synchronize everything!\" Think twice.  Synchronization isn't for free; it creates a performance problem, as now all other threads are blocked waiting for the availability of the lock, which in our case is the knife.</p>\n<p>In our kitchen, we could say that when my wife touches the knife I become blocked, waiting for her. If the phone rings, she should say: \"darling, please answer the phone\". But I will be blocked, I'll not be able to do anything except wait for her to leave the knife.</p>\n<p>A blocked thread goes to the TIMED_WAITING state, and during this time it can not be used. It is really advisable to keep track of how many threads our applications are using because threads are a scarce resource.</p>\n<p>But there is light at the end of the tunnel, at least in this concern you should know that Java 19 is coming up with the concept of <a href=\"https://blogs.oracle.com/javamagazine/post/java-loom-virtual-threads-platform-threads\"><ins>Virtual threads</ins></a>, in its Project Loom. This new feature will cut the one-to-one relationship between Java threads and OS threads, which means that more than one Java virtual thread will be able to use the same OS thread. With that, when some virtual thread gets blocked by an I/O operation, for example, another virtual thread can perform calculations on that same OS thread.</p>\n<p>But, as we said, until there we should use our threads with wisdom.</p>\n<h3>Nonblocking Algorithms</h3>\n<p>\"But, what to do?\", you could ask. Well, if you need better performance you can use Nonblocking Synchronization. Nonblocking algorithms are widely used by JVMs implementations, Operational Systems, and in Java itself to implement locks and other concurrent data structures.</p>\n<p>Those Nonblocking algorithms are way more complicated to design and implement, but they provide better performance by avoiding the thread block itself and give us other benefits like being immune to Deadlock.</p>\n<p>To provide a simple example of Deadlock, imagine that my wife and I are in the living room. The remote controller of the TV and the sofa are Locks. To watch TV, a person needs to sit on the sofa and press the button on the remote controller. A Deadlock would occur if I get the remote controller and my wife sits on the sofa. She will be blocked waiting for the remote controller, and I'll be blocked waiting for the sofa. And we will be like that \"until death does us part.\"</p>\n<p>Let's go back to the Nonblocking algorithm. First of all, we need a way to ensure atomicity to our tasks. And it is possible because modern computer processors have special instructions for managing access to shared data. A common approach is the implementation of the compare-and-swap (CAS) instruction. It guarantees us that the access to the value and its update will occur as a single task.</p>\n<p>Java's Concurrent package provides us with some so-called atomic classes. Let's take AtomicInteger as an example, its documentation states that it is \"An int value that may be updated atomically\".</p>\n<p>The following code shows us the same algorithm, but only the last one achieves thread-safe by delegating its thread-safety to an AtomicInteger:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">Counter</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">private</span> <span class=\"token class-name\">Integer</span> count <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">incrementCount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>count <span class=\"token operator\">=</span> count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n\n   <span class=\"token keyword\">public</span> <span class=\"token keyword\">int</span> <span class=\"token function\">getCount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">return</span> count<span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">ThreadSafeCounter</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">private</span> <span class=\"token class-name\">AtomicInteger</span> count <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">AtomicInteger</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">incrementCount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>count<span class=\"token punctuation\">.</span><span class=\"token function\">incrementAndGet</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n\n   <span class=\"token keyword\">public</span> <span class=\"token keyword\">int</span> <span class=\"token function\">getCount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">return</span> count<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>And how does AtomicInteger ensure atomicity? Using the CAS algorithm! Its incrementAndGet method executes a code that could be simplified like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">int</span> value<span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">public</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">int</span> <span class=\"token function\">incrementAndGet</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> expectedValue<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">int</span> oldValue<span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">do</span> <span class=\"token punctuation\">{</span>\n       oldValue <span class=\"token operator\">=</span> value<span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span> <span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token function\">compareAndSetInt</span><span class=\"token punctuation\">(</span>oldValue<span class=\"token punctuation\">,</span> oldValue <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">return</span> oldValue<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>To start, it gets the current value and stores it in a local variable. Then using the compareAndSetInt method it first checks if, at that precise moment, the current value is the same that was earlier fetched. If it is so, it proceeds with the update and then returns True. If the current value was changed by another thread, the compareAndSetInt method returns False and restarts the process.</p>\n<p>It is worth saying that the compareAndSetInt method is a native method, which uses the most efficient instructions provided by the underlying hardware.</p>\n<p>With this new knowledge, what about trying it on our bread? Let's remove the blocking synchronization and create the faster bread with butter that a computer could have (and some with hazelnut cream too, for the sake of my wife's happiness). We can do this using an AtomicReference.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">Knife</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">private</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">AtomicReference</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">></span></span> topping <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">AtomicReference</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token keyword\">public</span> <span class=\"token class-name\">Knife</span> <span class=\"token function\">setTopping</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> topping<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>topping<span class=\"token punctuation\">.</span><span class=\"token function\">compareAndSet</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">null</span><span class=\"token punctuation\">,</span> topping<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n       <span class=\"token keyword\">return</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n\n   <span class=\"token keyword\">public</span> <span class=\"token class-name\">Knife</span> <span class=\"token function\">applyToppingTo</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Bread</span> bread<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token class-name\">String</span> currentTopping<span class=\"token punctuation\">;</span>\n       <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>currentTopping <span class=\"token operator\">=</span> topping<span class=\"token punctuation\">.</span><span class=\"token function\">getAndUpdate</span><span class=\"token punctuation\">(</span>s <span class=\"token operator\">-></span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span>\n           bread<span class=\"token punctuation\">.</span><span class=\"token function\">setTopping</span><span class=\"token punctuation\">(</span>currentTopping<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token keyword\">return</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Of course, we did that after removing the synchronized block from our test. Good, fast, and easy, and without thread blocking! But, please pay close attention to this piece of code. We have some problems there as it is some kind of adaptation of the canonical CAS algorithm.</p>\n<p>The hard part of building nonblocking algorithms is to isolate the shared memory into an atomic single change. But in our baker issue, we have a two-step action: first, we set the topping to the knife, and then we add the topping to the bread. So we have two states to keep track of: the knife and the bread.</p>\n<p>As we said, this code works and does not block the thread, but doesn't give us all the advantages of the CAS algorithm, because we still can have a Livelock issue.</p>\n<p>A Livelock issue can occur even when the thread is not blocked, if it is waiting for an operation that will never succeed. In our code, we used the topping value as a kind of lock. The first thread that moves it from null to another value, it will put all other threads waiting for that value to become null again. It works, but if any thread fails to add the topping to the bread, which moves the topping value back to null, all the other threads will be waiting forever.</p>\n<p>The control mechanism, when more than one thread fights for the knife topping, is done by retrying again immediately, like in the CAS. But the canonical CAS will not fail indefinitely if any other thread fails. It will just finish its job as soon as no other thread touches the shared memory when it is still working.</p>\n<h3>Immutability</h3>\n<p>\"So, what to do!? I'm reading this to find answers, not questions!\" Ok, I'll let you know. The other side of the coin, in the context of thread safety, is Immutability. If we use an immutable object, virtually all problems with atomicity are gone. That's because all problems that we are facing here are based on threads fighting to access the same shared memory. If the memory that they want to access cannot be modified, those risks are gone and thread safety is achieved.</p>\n<p>We can summarise that an Immutable object is one that can't be changed after its creation.</p>\n<p>Java introduced the Record, which is a simple way to create immutable objects. We just need to provide the type and name of the fields. The public constructor, equals, hashCode, and toString methods, along with the private, final fields, are all given for free to us, by the compiler.</p>\n<p>Take a look at the following code:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">record</span> <span class=\"token class-name\">Knife</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> topping<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\n   <span class=\"token keyword\">public</span> <span class=\"token class-name\">Knife</span> <span class=\"token function\">setTopping</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> topping<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Knife</span><span class=\"token punctuation\">(</span>topping<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n   <span class=\"token keyword\">public</span> <span class=\"token class-name\">Knife</span> <span class=\"token function\">applyToppingTo</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Bread</span> bread<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>topping <span class=\"token operator\">!=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span>\n           bread<span class=\"token punctuation\">.</span><span class=\"token function\">setTopping</span><span class=\"token punctuation\">(</span>topping<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token keyword\">return</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Knife</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Some could argue that immutable objects are a waste of resources, but it isn't true in the majority of cases. Dealing with immutable objects offers us performance advantages when it frees us from using synchronization or creating defensive copies, it even reduces the impact on generational garbage collection.</p>\n<p>But talking about defensive copies, is the record really immutable? Look at this test:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Test</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">givenReferenceToRecordThenItShouldBeImmutable</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">record</span> <span class=\"token class-name\">Parent</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">,</span> <span class=\"token class-name\">List</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">></span></span> childrenNames<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> childrenNames <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ArrayList</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span><span class=\"token class-name\">List</span><span class=\"token punctuation\">.</span><span class=\"token function\">of</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Haru\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> parent <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Parent</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Bruno\"</span><span class=\"token punctuation\">,</span> childrenNames<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token keyword\">var</span> parentBeforeNewChild <span class=\"token operator\">=</span> parent<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   childrenNames<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Ayumi\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token function\">assertThat</span><span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">hasToString</span><span class=\"token punctuation\">(</span>parentBeforeNewChild<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>This task will fail with the following log:</p>\n<div class=\"gatsby-highlight\" data-language=\"tex\"><pre class=\"language-tex\"><code class=\"language-tex\">java.lang.AssertionError: \nExpecting actual&#39;s toString() to return:\n  &lt;&quot;Parent[name=Bruno, childrenNames=[Haru]]&quot;&gt;\nbut was:\n  &lt;Parent[name=Bruno, childrenNames=[Haru, Ayumi]]&gt;</code></pre></div>\n<p>We have to keep in mind that in the way that we created the Parent record we have kept a reference to its internals. A record is still unmodifiable, but to achieve immutability you have to avoid exposing its inner state. In our example, we can avoid that by overriding the constructor and coping the list of children's names:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">record</span> <span class=\"token class-name\">Parent</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">,</span> <span class=\"token class-name\">List</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">></span></span> childrenNames<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">public</span> <span class=\"token class-name\">Parent</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">,</span> <span class=\"token class-name\">List</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">></span></span> childrenNames<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>name <span class=\"token operator\">=</span> name<span class=\"token punctuation\">;</span>\n       <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>childrenNames <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ArrayList</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span>childrenNames<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Now the test is successful, but we are still publishing the internal state of the record. The getter method for the property childrenNames is publishing the reference to the record's inner state, allowing it to be modified:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Test</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">givenReferenceToRecordThenItShouldBeImmutable</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">record</span> <span class=\"token class-name\">Parent</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">,</span> <span class=\"token class-name\">List</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">></span></span> childrenNames<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">public</span> <span class=\"token class-name\">Parent</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">,</span> <span class=\"token class-name\">List</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">></span></span> childrenNames<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n           <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>name <span class=\"token operator\">=</span> name<span class=\"token punctuation\">;</span>\n           <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>childrenNames <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ArrayList</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span>childrenNames<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n       <span class=\"token punctuation\">}</span>\n   <span class=\"token punctuation\">}</span>\n   <span class=\"token keyword\">var</span> childrenNames <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ArrayList</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span><span class=\"token class-name\">List</span><span class=\"token punctuation\">.</span><span class=\"token function\">of</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Haru\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> parent <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Parent</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Bruno\"</span><span class=\"token punctuation\">,</span> childrenNames<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token keyword\">var</span> parentBeforeNewChild <span class=\"token operator\">=</span> parent<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   parent<span class=\"token punctuation\">.</span><span class=\"token function\">childrenNames</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Ayumi\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token function\">assertThat</span><span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">hasToString</span><span class=\"token punctuation\">(</span>parentBeforeNewChild<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>This code will fail as well:</p>\n<div class=\"gatsby-highlight\" data-language=\"tex\"><pre class=\"language-tex\"><code class=\"language-tex\">java.lang.AssertionError: \nExpecting actual&#39;s toString() to return:\n  &lt;&quot;Parent[name=Bruno, childrenNames=[Haru]]&quot;&gt;\nbut was:\n  &lt;Parent[name=Bruno, childrenNames=[Haru, Ayumi]]&gt;</code></pre></div>\n<p>To avoid that you have at least two options: override the getter and return a copy of our list, or the one that I prefer: save our internal state as an unmodifiable list:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">record</span> <span class=\"token class-name\">Parent</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">,</span> <span class=\"token class-name\">List</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">></span></span> childrenNames<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">public</span> <span class=\"token class-name\">Parent</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">,</span> <span class=\"token class-name\">List</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">></span></span> childrenNames<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n       <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>name <span class=\"token operator\">=</span> name<span class=\"token punctuation\">;</span>\n       <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>childrenNames <span class=\"token operator\">=</span> <span class=\"token class-name\">List</span><span class=\"token punctuation\">.</span><span class=\"token function\">copyOf</span><span class=\"token punctuation\">(</span>childrenNames<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Like this, every time someone tries to update our inner state, they will get a UnsupportedOperationException, which I believe is what we should expect from trying to modify something supposed to be immutable.</p>\n<h2>Summary so far</h2>\n<p>What we have seen so far?</p>\n<ul>\n<li>\n<p>We learned more about Race Conditions, in real life and in the software, and the main solution tool from Java: the monitor pattern, using the synchronized keyword;</p>\n</li>\n<li>\n<p>After understanding the downside of locking, we were introduced to the compare-and-swap (CAS) nonblocking algorithm, which despite being hard to develop can lead us to better performance and protect us from Deadlock</p>\n</li>\n<li>\n<p>For the cases when we are unable to isolate our shared memory, or even in other scenarios where we just need more protection, we talked about immutability and how immutable objects can grant us thread safety.</p>\n</li>\n<li>\n<p>We then revisited the java Record, which is a fairly easy way to create an immutable object, but that is not immune to bad programming technic. To really achieve immutability in our objects we saw how we should avoid publishing its inner state.</p>\n</li>\n</ul>\n<h2>Conclusion</h2>\n<p>Oh, it was an amazing journey, we started with a brief introduction about threads, how to properly test them, and we met some new friends from Java's Concurrency package. With new algorithms and tools under our belt, we are ready to travel to the multithreaded world riding our thread-safe software. I'll now eat my bread with butter, see you soon!</p>\n<h2>Appendix</h2>\n<p>Baking delicious cakes with AssertJ's Condition entity:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Test</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">testTheCake</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">record</span> <span class=\"token class-name\">Cake</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> name<span class=\"token punctuation\">,</span> <span class=\"token keyword\">boolean</span> hasFruit<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> weightInKg<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token keyword\">var</span> chocolateCake <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Cake</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Chocolate\"</span><span class=\"token punctuation\">,</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> strawberryCake <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Cake</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Strawberry\"</span><span class=\"token punctuation\">,</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span> <span class=\"token number\">3</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token keyword\">var</span> bakery <span class=\"token operator\">=</span> <span class=\"token class-name\">List</span><span class=\"token punctuation\">.</span><span class=\"token function\">of</span><span class=\"token punctuation\">(</span>chocolateCake<span class=\"token punctuation\">,</span> strawberryCake<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token keyword\">var</span> heavyCakes <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Condition</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Cake</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span>cake <span class=\"token operator\">-></span> cake<span class=\"token punctuation\">.</span>weightInKg <span class=\"token operator\">>=</span> <span class=\"token number\">3</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"heavy cake\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">var</span> bigChocolate <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Condition</span><span class=\"token generics\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Cake</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">(</span>cake <span class=\"token operator\">-></span>\n           cake<span class=\"token punctuation\">.</span>name<span class=\"token punctuation\">.</span><span class=\"token function\">contains</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Chocolate\"</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&amp;&amp;</span>\n           cake<span class=\"token punctuation\">.</span>weightInKg <span class=\"token operator\">>=</span> <span class=\"token number\">5</span>\n           <span class=\"token punctuation\">,</span> <span class=\"token string\">\"big chocolate\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n   <span class=\"token function\">assertThat</span><span class=\"token punctuation\">(</span>bakery<span class=\"token punctuation\">)</span>\n           <span class=\"token punctuation\">.</span><span class=\"token function\">haveExactly</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">,</span> heavyCakes<span class=\"token punctuation\">)</span>\n           <span class=\"token punctuation\">.</span><span class=\"token function\">haveExactly</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> bigChocolate<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>","fields":{"slug":"/a-wild-thread-appeared-multithreaded-testing-and-thread-safety/","tags":["Thread-safety","testing","nonblocking_algorithms","immutability"]}}},{"node":{"id":"c228c662-0cfd-54f0-ad54-4e1ef0c854d8","frontmatter":{"category":"Engineering","title":"Enter the End to End Testing of Internal Libraries ","date":"2022-07-18","summary":"End2End testing could help us tackle problems of increasing new code across the whole platform","thumbnail":null,"authorName":"Mikołaj Kłosowski","authorDescription":"Mikołaj is an Senior Software Engineer based in our Szczecin office","authorAvatar":{"relativePath":"pages/e2e-testing-internal-libraries/avatar_Kłosowski.jpg","childImageSharp":{"resolutions":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAMEAgX/xAAXAQADAQAAAAAAAAAAAAAAAAAAAQID/9oADAMBAAIQAxAAAAHPSiqzp4sF/8QAHBAAAgICAwAAAAAAAAAAAAAAAQIAAwQTESIj/9oACAEBAAEFAsYlcVG5r7CKRrrPnsn/xAAWEQEBAQAAAAAAAAAAAAAAAAAAEUH/2gAIAQMBAT8BxH//xAAVEQEBAAAAAAAAAAAAAAAAAAAAEf/aAAgBAgEBPwFH/8QAGhAAAgIDAAAAAAAAAAAAAAAAATEAEBIhYf/aAAgBAQAGPwIntKYncSr/xAAaEAEBAQADAQAAAAAAAAAAAAABEQAhMUGB/9oACAEBAAE/IQode8wvC2YhG/uoApOa9YSQYzv/2gAMAwEAAgADAAAAEI8v/8QAFhEBAQEAAAAAAAAAAAAAAAAAABEx/9oACAEDAQE/EJhT/8QAGBEAAwEBAAAAAAAAAAAAAAAAAAERQVH/2gAIAQIBAT8Qira0rp//xAAbEAEAAgMBAQAAAAAAAAAAAAABACERQVFxgf/aAAgBAQABPxDAIpp0LiTEIqARnq9gI/maHxA+0omb7FWMPxn/2Q==","width":50,"height":50,"src":"/static/08ff7d0f10dc02e43f61b30c3bf69631/d2d31/avatar_K%C5%82osowski.jpg","srcSet":"/static/08ff7d0f10dc02e43f61b30c3bf69631/d2d31/avatar_K%C5%82osowski.jpg 1x,\n/static/08ff7d0f10dc02e43f61b30c3bf69631/0b804/avatar_K%C5%82osowski.jpg 1.5x,\n/static/08ff7d0f10dc02e43f61b30c3bf69631/753c3/avatar_K%C5%82osowski.jpg 2x,\n/static/08ff7d0f10dc02e43f61b30c3bf69631/31ca8/avatar_K%C5%82osowski.jpg 3x"}}},"headerImage":null},"html":"<p>When a software-based company grows, it creates lots of new code, which means multiple engineers may be facing the same problems across the whole platform. They will usually come up with various solutions to fix it. Some of them might be generic and reusable, while others will be tailored to one’s needs. As it usually happens, the solutions will then be bundled together to create libraries. This is very good, up to a certain point, since over the years, engineers will create them by the dozens and this, in turn, will bring about other hurdles such as:</p>\n<ul>\n<li>how to maintain multiple libraries or prevent buggy code from getting in</li>\n<li>how to release one of them or many at the same time</li>\n<li>how to ensure a smooth process for updating libs for service maintainers</li>\n<li>how to ensure cross-compatibility for all of the libs</li>\n</ul>\n<p>This was quite a big pain point for AUTO1 software developers as we have 60+ common libraries that need to work perfectly in 600+ production services across multiple business units and products. One simple mistake, for example, a wrong configuration change leftover after a debug session can end up in disaster.</p>\n<p>Enabling protection against direct commits for main branches will address the first hurdle - only pull requests with double approvals and tested by CI can be merged.</p>\n<p>The next 2 issues are more about ease of usability for the developers, as they might be reluctant to upgrade their service if the process is troublesome. So, in the best-case scenario, our end-user should periodically update only a single property. In addition, our common library developers need to be able to easily publish their changes.</p>\n<p>The solution to it was the release trains, usually known as BOMs or for AUTO1 developers, service-commons-dependencies. After successful implementation, you will just need to trigger CI build to get the newly released version, which in turn can be pasted into a pom/gradle file. So, right now everything looks good, but can we be 100% sure that our changes are going to work? Perhaps there is a very small bug in a messaging lib or we will lose tracing for incidents. That’s unacceptable. So let’s ensure that will never happen by introducing automatic real use case testing.</p>\n<p>In our approach, we thought most of the problems could be revealed by running extensive integration testing. The test harness probably catches all bugs in our codebase and simply fails when needed preventing the release of a buggy version.</p>\n<p>But no matter what you do or how extensive your tests are, you are never going to be able to perfectly mock the production environment.</p>\n<p>Enter the End to End testing of newly released <code class=\"language-text\">service-commons-dependencies</code>, more commonly known in AUTO1 from here on out, “E2E testing”.</p>\n<p>To get it done, we need CI pipelines that will automatically test our new versions of release trains that are triggered either manually or automatically every week. All tests need to be as close to the real-world scenarios as possible. A practical solution is to create a new service that will include all of the most popular use cases of the aforementioned libs. Then we need to deploy it to all of our environments - as previously mentioned there is always something different between local, QA, and production environments, so we need to cover them all. The tests must be the same for all environments. But the trigger may differ - for example, we are using our test environments to prepare new releases for production.</p>\n<p>The following diagram illustrates the basic principle of how it should work:</p>\n<p><img src=\"https://lh6.googleusercontent.com/-K5rLPtggaNeQpml856NbA9UyUU6_scnBUgUE_W-RA7MVORz_dYAzrQ_jg7a9vBfQJHqmdosoCH7Evd0dbTF8-kzH0dlygQPeoqQu47__E5Pky0GmeyhlcJ1UWNuQrC7j5s3MZvQhj_EoSgwBA\"></p>\n<p>In our implementation, we chose to use Jenkins with JobDSL pipelines and Groovy for scripting. The first stage of the E2E process is checking whether a new version of service-commons-dependencies exists by using the maven versions plugin:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">mvn -U versions:update-property -Dproperty='service-commons-dependencies.version'</code></pre></div>\n<p>To check for any changes:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">def hasChanges = sh(returnStatus: true, script: \"git diff --exit-code\")</code></pre></div>\n<p>If nothing new was found let’s just abort the pipeline and wait for another CRON or manual trigger.\nIn case a new release was found, we need to build it, deploy it, and run E2E tests.\nIf there are no failures the pipeline will create a new core-test-service release.\nFor those cases, we are using parameterized jobs, for example, to trigger the E2E tests we can use the following commands:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">build(job: 'java/core-svc/core_test_end_to_end_test', parameters: [booleanParam(name: 'SEND_SLACK_NOTIFICATION', value: \"true\"), string(name: 'RELEASE_TRAIN_VERSION', value: service_commons_dependencies_version)])</code></pre></div>\n<p>The new release will be picked up by the production pipeline by checking the latest tag creation time in our repository:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">String latestTagDateString = sh(returnStdout: true, script: \"git rev-list -1 \\$(git describe --abbrev=0 --tags) --pretty=oneline --format=%ci | awk 'NR%2==0'\")\n\ndef proceedWithE2ETesting = wasTagReleasedRecently(latestTagDateString)\n\n@NonCPS\n\n    def wasTagReleasedRecently(String lastTagDateString) {\n\n    def formatter = DateTimeFormatter.ofPattern(\"yyyy-MM-dd HH:mm:ss Z\")\n\n    def lastTagDateTime = OffsetDateTime.parse(lastTagDateString.trim(), formatter)\n\n    def currentTimeMinus2hours = OffsetDateTime.now().minus(2, ChronoUnit.HOURS)\n\n    return lastTagDateTime.isAfter(currentTimeMinus2hours)\n\n}</code></pre></div>\n<p>If the release of core-test-service was created within the last 2 hours we will deploy it by triggering another pipeline. As the last step, it will run E2E tests. As mentioned above, both testing environments will use a shared codebase for acceptance testing. It can be done by setting up one extra job that will fetch an external repository using this block:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">definition {\n      cpsScm {\n          scm {\n              git {\n                  remote {\n                      github(\"core-e2e-tests\", 'ssh')\n                      credentials(\"token\")\n                      branch(\"master\")\n                  }\n                  extensions {\n                      wipeOutWorkspace()\n                  }\n               }\n       }\n\n       scriptPath(\"jenkins/core_e2e_tests.gvy\")\n  }\n}</code></pre></div>\n<p>We chose Cucumber as our main test framework since it will give us unparalleled leverage compared to other choices. Tests are written using natural language in a way that allows for troubleshooting to be done basically at a glance. For example here is the scenario that tests the libraries responsible for sending messages in our platform exposed via HTTP endpoint:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">Scenario: Should have a working API endpoint for creating a message\n\nGiven an object with generated id and message: This is a test\nWhen making a POST call on messaging endpoint with the body containing the given object in JSON representation\nThen should result in a 201 response status code\nAnd should receive an empty body</code></pre></div>\n<p>The above, combined with this generated report, is a joy to work with.\n<img src=\"https://lh5.googleusercontent.com/qyj0MbKLCEPO9M3Q8kalZoXkgfgcxddnmxk6lYUu0DrbBHhT747lCyy1SFhZDHKZXOGwUqcnsDFDPM2_rWAhnWC5l5m58RVcpsWWrBmwHIZgd3tKxSmhC6aqZHsB016Z7MXAhT0EX7mnT_N3_w\"></p>\n<p>Furthermore, we decided to create a dedicated slack channel to notify us about the new releases and test results.</p>\n<p>So after getting this message</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">Sanity checks for new release train X.Y.Z on env:\n\n    * REST API simple entity integration ✅\n    * REST API dated entity integration ✅\n    * REST API auditable entity integration\n    * Messaging integration ✅\n    * Messaging FIFO integration ✅\n    * Storage integration ✅\n    * Health integration ✅\n    * Metrics integration ✅\n    * Logging integration ✅</code></pre></div>\n<p>We can finally get our much-needed stress-free beauty sleep, not that it will help us much, right? Hopefully, this small article will get you in the mood for some nice automation work in your company. Have fun and enjoy your peaceful nights.</p>","fields":{"slug":"/e2e-testing-internal-libraries/","tags":["auto1","engineering","end2end","testing","internallibraries"]}}},{"node":{"id":"a26825f5-bab1-5ad6-bc95-41f8c672ba4c","frontmatter":{"category":"QA","title":"Efficient Testing - Automate Early","date":"2022-06-01","summary":"Early bird gets the worm - or how preparing in time can reduce the effort needed in manual testing.","thumbnail":null,"authorName":"Joanna Tyka","authorDescription":"Joana is a QA Automation Engineer in our Katowice office.","authorAvatar":{"relativePath":"pages/efficient-testing-2/JoannaT.jpeg","childImageSharp":{"resolutions":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAATABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUCBAH/xAAVAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAABqc+OOWqwSV4DXFH/xAAcEAEAAQQDAAAAAAAAAAAAAAACAwABBCEQETH/2gAIAQEAAQUCSsDHJd8ZS6gie6yaWk/f/8QAFREBAQAAAAAAAAAAAAAAAAAAASD/2gAIAQMBAT8BI//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EAB0QAAEEAgMAAAAAAAAAAAAAAAEAAhARAyFBUXH/2gAIAQEABj8CLjwtgC4I7TGwPVjqP//EABsQAQEBAAIDAAAAAAAAAAAAAAERABAxIVFx/9oACAEBAAE/IeogXCDAUjcuKkWDGQR7X7rlS/fEZ4Kl4P/aAAwDAQACAAMAAAAQ9AjA/8QAFxEBAQEBAAAAAAAAAAAAAAAAARARMf/aAAgBAwEBPxACOw5P/8QAFxEBAQEBAAAAAAAAAAAAAAAAAAERMf/aAAgBAgEBPxC9Yqv/xAAdEAEAAwADAAMAAAAAAAAAAAABABEhMUFhgaHB/9oACAEBAAE/ELDbyryGiEG8eM0myDEXXZjO3Q44B9sdxnK12+IIWkHfEAGuz9Z//9k=","width":50,"height":50,"src":"/static/d453ba1bcdc86e2db725a048eefd13a6/d2d31/JoannaT.jpeg","srcSet":"/static/d453ba1bcdc86e2db725a048eefd13a6/d2d31/JoannaT.jpeg 1x,\n/static/d453ba1bcdc86e2db725a048eefd13a6/0b804/JoannaT.jpeg 1.5x,\n/static/d453ba1bcdc86e2db725a048eefd13a6/753c3/JoannaT.jpeg 2x,\n/static/d453ba1bcdc86e2db725a048eefd13a6/31ca8/JoannaT.jpeg 3x"}}},"headerImage":null},"html":"<h1>Efficient Testing - Automate Early</h1>\n<p>I don't have time for automation - how often do you say that? I said that once and now I feel a bit ashamed thinking about it. To never repeat this mistake I had to find some solution, to not only have enough time for automation but also to be much faster using it. I realized that when I was repeating the same test case manually for the 5th time, it was incredibly boring and each try was taking 15 minutes of my time. Today I would like to share my experience with you on how to make it faster and more pleasant. In the big picture, it is all about being agile, splitting the job between small pieces, done as fast as possible. Before the feature is fully ready for tests we have so many different opportunities to start working on automation.</p>\n<h2>Planning and reconnaissance</h2>\n<p><em>An hour of planning can save you 10 hours of doing - Dale Carnegie</em></p>\n<p>As soon as test scenarios are prepared, you can select candidates for automation and choose which ones should be executed on API level and which on UI. It should be a part of a well-prepared automation strategy (more about test automation strategy here <a href=\"https://auto1.tech/efficient-testing-1/\">https://auto1.tech/efficient-testing-1/</a> ). Check whether all necessary API calls are available for you (maybe you need to ask developers to create new endpoints?), what will be the steps to prepare the environment for the test, explore existing automation infrastructure and recognize how many new methods and classes you will need to prepare. Sometimes our features are settled on some other pages or we need to go through other features or applications to do our tests. As these parts already exist, it is a great time to cover it with automation if nobody hasn't done that before. It is also a great time to consider which tools will be needed and find new libraries that will be more effective.</p>\n<h2>Test data preparation</h2>\n<p>Test data means all that needs to be prepared before your real test will start. When you are sure that you know all the preconditions and steps required to arrange the system before beginning the testing, you can recognize how to prepare it just when the first version of the specification is written. For example, let's take an order in the shop. When developers write their code you can write your own which will prepare test data via API, so following our example the order in specified state. To make it more efficient you can store example of the order in the queue (read more about it here <a href=\"https://auto1.tech/faster-automation-tests/\">https://auto1.tech/faster-automation-tests/</a>). It will be so helpful when you will need to execute the first most basic test and speeds up the whole process significantly. Developers in your team will be also very grateful for the created test data that they can take and quickly test their changes on.</p>\n<h2>Page Object skeletons</h2>\n<p>If you use Page Object Pattern you can create a page objects skeleton just now based on the design. Prepare all classes storing variables with empty locators, write all methods which will use these locators to interact on the page and prepare bigger steps that will do your manual work. When the front end part of the feature will be implemented you can just fill in locators one by one look at the DOM and adjust steps easily. With unique locators added by developers, it will be almost a pure pleasure.</p>\n<p><img src=\"https://i.postimg.cc/tXm79NqD/image.png\"></p>\n<p>Let's take this design of the saved searches page as an example and imagine a test scenario that verifies that saved searches are displayed on the proper page and the user can use a saved search to view the current results of searching. We know that to be able to execute this scenario we need the signed-in user so we can prepare this user just now. Looking at this picture we already know that we have an upper menu that should be already covered with automation (if it isn't covered, the time to do it is just now) and we need to use it to open my account view. We have also a side menu to open the saved searches page from my account context. We know how the saved search will look and which button we will need to click to open search results. Having all this information we can prepare the saved search page class, empty locators for all elements and methods that will interact with the page.</p>\n<h2>Doubts?</h2>\n<p>Many times I saw this approach to automation. I will do everything manually and leave the automation creation at the end or it doesn't make any sense to create automation now, because I will have to change it. Have you seen something similar? But how much time will be needed then to write all automated tests? Two weeks, or more? Who will give this time, when a new urgent feature is upcoming? From my perspective, it is really hard to find that person and it is well-argued. That's why in my humble opinion it is much better to split your time into small sessions before the feature is ready for tests and then have all automation components already done, then just write tests on demand. Isn't it beautiful having valuable tests from the start and be able to use them as regression tests at any time?</p>\n<h2>In real life</h2>\n<p>I will give you my example: I was testing integration between two systems. Requirements were very agile, five teams were engaged in this feature and multiple layers of integration were created, so we had many bugs by the way. I had to repeat every test scenario 10 times on average. Manually test data preparation for each took 10 minutes, the real testing part between 5 and 10 minutes. After the third attempt, I was tired and frustrated. The more tired and frustrated I was - the more mistakes I made. It was a critical point for me to start writing automated tests. Of course, I had to spend a few hours to have it ready, but what a relief I felt when the 15 minutes scenario was done by my automation in 3 minutes. The other big benefit was that automation doesn't make mistakes and I could run my tests how many times I needed so I've stopped caring about the number of repetitions. I was able to share these tests with my colleague that needed them for testing the other part of this integration. My rough calculations show that I saved a few days and so many hairs which I would have ripped out of my head if I had to do all these tests manually to the end. When I was asked about regression I needed only a few minutes of my effort.</p>\n<h2>Conclusion</h2>\n<p>We have so many opportunities to be well prepared for upcoming features and to reduce the effort needed in manual testing. Creating smart automation will develop our coding skills and help to save time and frustration. I am sure that there are many other ways to receive significant benefits by automating early, we just need to use them.</p>","fields":{"slug":"/efficient-testing-2/","tags":["auto1","engineering","qa","testing"]}}},{"node":{"id":"43a222cd-fe2c-5cb5-af76-53e7d4ad29ec","frontmatter":{"category":"QA","title":"The journey of a QA engineer in AUTO1 Tech","date":"2022-03-31","summary":"Check out Dhivya's journey in our QA department & how our stack and team contributed.","thumbnail":null,"authorName":"Dhivya Venugopal","authorDescription":"Dhivya is a Junior QA Engineer in the AUTO1 Berlin office.","authorAvatar":{"relativePath":"pages/qa-engineer-journey/dhivya.jpg","childImageSharp":{"resolutions":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAAMBAAAAAAAAAAAAAAAAAAEEBQP/xAAWAQEBAQAAAAAAAAAAAAAAAAABAAL/2gAMAwEAAhADEAAAAXWvULaZ6pqGyQn/xAAcEAACAQUBAAAAAAAAAAAAAAABAgADBBESIRP/2gAIAQEAAQUCpnisScxMquzerXOJXGkTon//xAAVEQEBAAAAAAAAAAAAAAAAAAARIP/aAAgBAwEBPwFj/8QAGBEAAgMAAAAAAAAAAAAAAAAAAAECECH/2gAIAQIBAT8BUTb/AP/EABwQAAEEAwEAAAAAAAAAAAAAAAAQESFBARIxMv/aAAgBAQAGPwIy/KSTY8EDUn//xAAbEAACAwEBAQAAAAAAAAAAAAABEQAxQSFRgf/aAAgBAQABPyHykFbsz0UKMJmkC9nELAfyNrrluBBEa2WJpCJ//9oADAMBAAIAAwAAABCHMMH/xAAZEQEAAgMAAAAAAAAAAAAAAAABABEQITH/2gAIAQMBAT8QBVM1Hrj/xAAXEQEBAQEAAAAAAAAAAAAAAAABEDFB/9oACAECAQE/EE07BhP/xAAcEAEBAAMAAwEAAAAAAAAAAAABEQAhMVFhcaH/2gAIAQEAAT8QUhkEVKfHjA10KQp0jMUp9wY6EihV16w0n7o+2sU+sPC/mXadbXuBNStjW5gkDgZ//9k=","width":50,"height":50,"src":"/static/d37e68c1bb8fcdb464c251c9a15e7dbe/d2d31/dhivya.jpg","srcSet":"/static/d37e68c1bb8fcdb464c251c9a15e7dbe/d2d31/dhivya.jpg 1x,\n/static/d37e68c1bb8fcdb464c251c9a15e7dbe/0b804/dhivya.jpg 1.5x,\n/static/d37e68c1bb8fcdb464c251c9a15e7dbe/753c3/dhivya.jpg 2x,\n/static/d37e68c1bb8fcdb464c251c9a15e7dbe/31ca8/dhivya.jpg 3x"}}},"headerImage":null},"html":"<p><a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/5403ba9bebd07a50595eb7001d9728b7/a402e/1.jpg\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 590px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 66.8%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAUE/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAce+QSqjk//EABoQAAMAAwEAAAAAAAAAAAAAAAACAwEQERP/2gAIAQEAAQUCmy5FnJjxmd13J//EABcRAAMBAAAAAAAAAAAAAAAAAAABEgL/2gAIAQMBAT8BlE5P/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAERAv/aAAgBAgEBPwGsuj//xAAbEAACAQUAAAAAAAAAAAAAAAAAAQIgISIykf/aAAgBAQAGPwLNcLSRvR//xAAaEAEBAQEAAwAAAAAAAAAAAAABABFhMYGR/9oACAEBAAE/IS8x7BH0tnXwhSoXZ+3/2gAMAwEAAgADAAAAENj/AP/EABcRAQADAAAAAAAAAAAAAAAAAAABUWH/2gAIAQMBAT8Qitg//8QAFxEAAwEAAAAAAAAAAAAAAAAAAAFBYf/aAAgBAgEBPxBzZof/xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhQVGBoeH/2gAIAQEAAT8QNXWifSOykLvR9hsrN5nKlpHqP0k//9k='); background-size: cover; display: block;\"\n    ></span>\n    <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\"\n        alt=\"1\"\n        title=\"\"\n        src=\"/static/5403ba9bebd07a50595eb7001d9728b7/f8fb9/1.jpg\"\n        srcset=\"/static/5403ba9bebd07a50595eb7001d9728b7/e8976/1.jpg 148w,\n/static/5403ba9bebd07a50595eb7001d9728b7/63df2/1.jpg 295w,\n/static/5403ba9bebd07a50595eb7001d9728b7/f8fb9/1.jpg 590w,\n/static/5403ba9bebd07a50595eb7001d9728b7/85e3d/1.jpg 885w,\n/static/5403ba9bebd07a50595eb7001d9728b7/a402e/1.jpg 1000w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n      />\n  </span>\n  </a></p>\n<p>Hi there! My name is Dhivya and I started my career as a Software Engineer in Tech Support and Testing. After a brief sabbatical, in the mid of 2021, I decided to get back into the workforce. I was searching for the right opportunity to kickstart my career and I was very excited to land a job at AUTO1 as a Junior QA Engineer.</p>\n<p><strong>Onboarding experience</strong></p>\n<p>Having previous experience in manual testing, I was greatly looking forward to this opportunity to deep dive into the world of automation testing. Onboarding happened seamlessly thanks to the onboarding handbooks and Confluence resources specially curated for a new joiner in the AUTO1 QA team. It briefed the step-by-step process on how to set up and get ready for the automation testing at AUTO1.</p>\n<p>The CAT (Core Automation Team) people were readily available to guide me in each step, right from setting up the environment, software, and configurations. This was a first-time experience for me, seeing such a dedicated team exclusively being there to support the entire QA team.</p>\n<p><img src=\"/static/2-06a454814194fbad5f8c98269b9fb867.gif\"></p>\n<p><strong>CAT</strong> (Core Automation Team)</p>\n<p>I found myself doing extensive testing of SHIFT, our internal test case management software developed and used by AUTO1. This gave me some in-depth knowledge of the software itself and also the processes and automation structure set in the company.</p>\n<p>In the months that followed, I was excited to take up some solid training from my amazing mentor, who introduced me to the project and the automation tests we had in place. He was very resourceful and immensely patient and carefully introduced me to each element of the role, gradually allowing me to explore the various tasks I would eventually take up. This gave me ample opportunity to get a deep understanding of the project and build a good rapport with my team members and also established a clear goal for me. I was soon writing my first automation test and found the experience thoroughly organic and gratifying.</p>\n<p><strong>Automation Testing at AUTO1</strong></p>\n<p>Firstly, I understood why Automation Testing has become a quintessential part of current testing standards and how it helped our teams achieve great speed, efficiency, and quality. The automation tests and resources were brilliantly abstracted in several repositories and accessed by the various QA teams.</p>\n<p>With 600+ microservices, automation testing is the best way to ensure that the entire platform works efficiently. We use a variety of test automation tools including Selenium and Playwright to drive the automation. The entire framework has been abstracted into a common module in repositories that has helper methods pertaining to our domain. Each team has their dedicated repositories that carry out regular automation test runs, generating regular test reports and this structure helped us keep track of the health and sanity of the systems we worked with.</p>\n<p>The Automation Testing process at AUTO1 looks just like this:</p>\n<p><a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/55fa7b0fddafca9ed49b6c26a2be6326/81d54/3.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 590px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 56.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABP0lEQVQoz61Ry0rEQBCMv+SX+Ame1IMHr7oX/Q1/RLxqEMWFVRQWPIkgPmaTbCabZJ5d9oSJuyysi2iFojrdPTXdTEJECYBT5pDjS9aUNQ26in09KPOC4xFzKwngYIOTd1iBxpd4FCmm9gNrsP9tyLyKScPmjtVprZ0QwlW1dLWWTpnWlaV03vuu3vcxdTy7u2h4HTKxCdZb3IhbEH/LGL1INLprC/0BNpb2VhqWRmKYj2CVRZZlyPMceVHw2C0eXhsUzdww3L/WsFUtpmwAT6hmFSZiAm0MjFLIhICU1a8mJPJEsq2pMDV1/+h2p5m1lNU1eee63E+GaUwqbjDhcZS35uz93jzJNxPGe64qc/4pzMx5Ex+v07BQPLuzaDjG33HQGwZuM4+ZR3zzgHXgoy6zz9O8fsg8YW4m/42w7Rfe9dEFZoPW0AAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    ></span>\n    <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\"\n        alt=\"3\"\n        title=\"\"\n        src=\"/static/55fa7b0fddafca9ed49b6c26a2be6326/40fad/3.png\"\n        srcset=\"/static/55fa7b0fddafca9ed49b6c26a2be6326/707e9/3.png 148w,\n/static/55fa7b0fddafca9ed49b6c26a2be6326/649e0/3.png 295w,\n/static/55fa7b0fddafca9ed49b6c26a2be6326/40fad/3.png 590w,\n/static/55fa7b0fddafca9ed49b6c26a2be6326/b3fef/3.png 885w,\n/static/55fa7b0fddafca9ed49b6c26a2be6326/301c0/3.png 1180w,\n/static/55fa7b0fddafca9ed49b6c26a2be6326/81d54/3.png 1280w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n      />\n  </span>\n  </a></p>\n<p><strong>Test data management using SHIFT</strong></p>\n<p>The test cases, scenarios, and strategies are maintained in SHIFT, our internal (and soon to be open-sourced) test case management system. Our QAs make use of a test data tool which is integrated to SHIFT. The 100+ types of test data required by the teams are generated using automation suites that run in Jenkins. This test data is then queued in SHIFT and as a result increased the productivity of our QA team by reducing the effort for manual test data creation. Our director of QA has briefed this here <a href=\"https://auto1.tech/faster-automation-tests/\">https://auto1.tech/faster-automation-tests/</a>.</p>\n<p><strong>Seamless Integrations</strong></p>\n<p>Our CI system, Jenkins, is wired to run these tests against our various QA environments. The integration of SHIFT with Slack, Jenkins, and Jira has helped the teams immensely. The status of Jenkins jobs/sanity suites is notified in Slack. The time taken to debug the issue is hugely reduced since SHIFT displays a precise list of failed tests including the screenshot reference, which helps me to quickly understand the exact point of failure. Once I have identified the issue, I fix it and test it locally, then push the branch to our repository. The process is set in such a way that merge can be done only after review, which gives me more confidence and validation for the proposed solution. This helps me address the issues faster and get the system up and running. This is indeed why the QA team at AUTO1 is one of the key pillars of the Engineering team.</p>\n<p>My automation testing journey at AUTO1 could not have been this impactful if not for this perfect blend of the best tech stacks and resources, and most importantly, my amazing team. My learning on the job has been very effective and hands-on, and it makes each day filled with new challenges and new learning opportunities that help my work create a real impact.</p>\n<p>From the very many opportunities that came my way and the deep learning curve it has presented me with, I now realize that - <strong>the journey has just begun!</strong></p>","fields":{"slug":"/qa-engineer-journey/","tags":["auto1","engineering","testing","QA","social"]}}},{"node":{"id":"0e79f71e-bac7-5c18-b5ae-ae1cec933364","frontmatter":{"category":"QA","title":"Efficient testing - Test Strategy","date":"2021-10-08","summary":"The first article in a series of articles focusing on efficient testing.","thumbnail":null,"authorName":"Michal Chytroszek","authorDescription":"Michal is the QA lead of the Car Journey associated teams.","authorAvatar":{"relativePath":"pages/efficient-testing-1/Michal.png","childImageSharp":{"resolutions":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAACE4AAAhOAFFljFgAAAEyklEQVQ4yx2Qe0xTdxzFr9Dee3/30dpCRQqsQofyEEQpT8v6ABwgUPoASpUiMigKHeVReZTy0BYEh6TVtohKsbCNqAiFKPhgY3GYqAPMhkaWzEyXbG5z2ZZliX8sY5clJ998//mcnHMgg83Tah28e+2k7Uxb36Uxy/B4w1mP4bSr8WRvtjQ5I57X47R3uYY1avkxfZX+hL5CKXbUZpbLJVVHiiDLN/+euvfDl4/mHj24dnXh4f1Xv0y/+Htw6fehlbfywxWi2OCx5VfO1bfuJ3/VWFy9o580G/WL5ysHLnpu3ZyFWj//o8O7dnv5q/kHS947M3efPn/8+rfTX/w0+PXG8c7+tChu0+BQdfegXG/pu70+v/6yratjskfjmrhxzjUCGRfedCz8emlqbuaze8vfrV9f+VZfU5knTTZYBuptngOJkbWGWm1pcUpyYk2T0dRmqNOVTnRrHOesDVUlkME+1uC62ugY7xy91uWezN2/dxcORTKgZC5Q5OWLBRFFMmleekJq3E5VrrDq6OHGD6tnzpW2dylOlL4HWV9unH650ff9P2d+3miafiiPZjsVPLcywFPo156zI3k3L1McJ0qKEQkiNIdy7cPOZrNJeZinqhRrVRlQ48Wp5pFZ08h0z/iMuX/AKg/3loXNargLWn/PIX62MFp+MEEiTk3dHaKV729oNqoz99QXBLVo4oqyEqDe8VvOqzfdc/cvTM17LjsvHxEURm01p3F0e4haEV99ME2pSpfnC3X52ztNOaOrb0ZbBet96NDxhPJDBdDd1bVnKzf+fHZlbu3FWH+HVxM2URQ6VcQbzd3mLQmpFocnJsY0lPMrlL4HFUzPpOO6VeIyZelbzCp9N9Qy/Wzx4eKPT9w3nzx3zy/OdmtsGQH6ff7mRMZIQYBKEiMWhEglHJmCa+zQdtts5o/sirreYrNDVtsBtc6s9dx5ar+zapl9fGrp9YBzyKMK7s0MtmWSLYWJkXsTynRHjfYLdYOjdbbrOqu73GwvrOss6XTJDFZI//GDdu9y/8K62btSc35SmJ5dKeTqkvzUsUQEf0dQME+Up9G2n6/q81RYhss6HdqWM7Jqk6p9KFdvgeo/Xapz3pDK1Pxd0SwCp/v44BgRzsEJBN6yxRem03GaDxOGRPkardlR3NhXXG/NLm/KMpyVVrRBxomlhP1SGIIQmi8GAIskEASFaHQUhnGAogBlEgSB+PBC+craroJjZpnOlK4+Li5rFhbqoIr+KwH+fjiG4BhKAJRFYAwcENRPXRzdFEBJgHJYzKwSXf7RxpxSvViuFRYcScophuLfVwZu8wOIL0BpBEZn4YBNiYExCUASgEGgGIqQGMLAkLSMvJziDyT56tQDBXHvZUclSaFIsYIbGECgvghCwwHMJgCbRCmxCJRFUjCgYCaOMgEtIipGmJEnSJVEx6cEvhO2LZgHCVJEASyCxGAEoQMU3mQIqie6dfMBJE61RthMwMThwO3bY+NTouME/KgYNjeY5HCg0CD/QDZB4hRJg2E65bIZEv9f1BBg05RNYiwCYbMZEbH7dkbH8sIjWIFBwI8NZWuqOAyEScIYSqPBvgigAwBjGExNCFA6RdLoNCoIi4EyGei7UbFhuyJDQncw/P0o+/8A3meRLxNk0Z4AAAAASUVORK5CYII=","width":50,"height":50,"src":"/static/52659ecfce9ed71e567bddef5d9c1b15/45876/Michal.png","srcSet":"/static/52659ecfce9ed71e567bddef5d9c1b15/45876/Michal.png 1x,\n/static/52659ecfce9ed71e567bddef5d9c1b15/eb85b/Michal.png 1.5x,\n/static/52659ecfce9ed71e567bddef5d9c1b15/4f71c/Michal.png 2x,\n/static/52659ecfce9ed71e567bddef5d9c1b15/9ec3e/Michal.png 3x"}}},"headerImage":null},"html":"<p>Hi everyone! This article is the first in a series of AUTO1 testing-related posts, I hope you’ll find the content interesting enough to return for the rest in the series :) To start off, let’s ask one of the most important questions:</p>\n<h2>What is a Test Strategy?</h2>\n<p>In AUTO1 the test strategy is a high level, short and concise document which defines:</p>\n<ul>\n<li>\n<p>Scope of the testing</p>\n</li>\n<li>\n<p>Risks - areas that potentially can be broken</p>\n</li>\n<li>\n<p>Automation strategy</p>\n</li>\n<li>\n<p>Required test data</p>\n</li>\n<li>\n<p>Security</p>\n</li>\n</ul>\n<h2>Why do we create a Test Strategy?</h2>\n<p>In agile and fast changing environments we usually do not spend that much time on test documentation as in waterfall. However, even in such cases we cannot underestimate the importance of a test strategy. When you are creating a strategy it becomes your guide, a channel for your thoughts - you have a space to stop for a moment to try to understand what should be verified and do it at a very early stage. It is much easier to go back to the feature if you already wrote down your thoughts and you have some kind of summary.</p>\n<h2>How do we create a Test Strategy?</h2>\n<p>Let’s go through our thinking process, step by step.</p>\n<h4>Scope of the testing</h4>\n<p>Start with defining what exactly has to be tested. You can ask yourself a few questions:</p>\n<ul>\n<li>\n<p>Who is going to use the feature?</p>\n</li>\n<li>\n<p>What apps will be changed/created?</p>\n</li>\n<li>\n<p>On what devices will it be used?</p>\n</li>\n<li>\n<p>What types of testing will be needed?</p>\n</li>\n</ul>\n<p>It allows you to better understand the product you are going to test and the environment setup you’ll need.</p>\n<h4>Risks</h4>\n<p>Now think about all the things that can go wrong. Here the questions will be:</p>\n<ul>\n<li>\n<p>What apps/areas can be impacted by our change?</p>\n</li>\n<li>\n<p>Are we modifying dependencies of another system?</p>\n</li>\n<li>\n<p>Is my domain knowledge enough to understand a feature?</p>\n</li>\n<li>\n<p>Are there any missing prerequisites which can block testing?</p>\n</li>\n<li>\n<p>Are changes going to be compatible with existing solutions?</p>\n</li>\n</ul>\n<p>Answering these questions will help us create a plan in order to mitigate all risks. It can be planning an onboarding session with someone who has knowledge we need, investigating regression testing possibilities for apps or areas in danger or setting up a plan on how to get blockers done.</p>\n<h4>Automation strategy</h4>\n<p>Automation is an important part of our testing process. We think about the approach on the test strategy stage. We create our tests on an UI and API level. When we’ll have the technical specifications, which include details of implementation, then it is time to plan what and when will be automated. We ask questions such as:</p>\n<ul>\n<li>\n<p>Where is the specific logic placed? Is it frontend or backend?</p>\n</li>\n<li>\n<p>Do we have existing automation in this area? If yes, do we have to adjust it?</p>\n</li>\n<li>\n<p>Do we have all prerequisites needed to start writing automation?</p>\n</li>\n</ul>\n<h4>Required test data</h4>\n<p>At AUTO1 we have a lot of connections between several areas. It created dependencies which have to be covered in test data preparation. We have to be sure we know the preconditions and steps required to arrange the system before starting testing. Here we can specify if we need additional onboarding or support from other teams.</p>\n<p>Having answers to the above questions means we are prepared to plan more detailed test cases and we can use our strategy as some kind of a cheatsheet. However, do not blindly follow what you’ve planned - requirements can change. Review your strategy from time to time, to ensure that it is not outdated.</p>\n<h2>Summary</h2>\n<p>Test strategy shouldn’t take much time but it is important for the next step - creating a test plan. It can be a great guide which will help you to structure your initial ideas and be prepared for upcoming changes faster.</p>","fields":{"slug":"/efficient-testing-1/","tags":["auto1","engineering","testing","QA"]}}},{"node":{"id":"7efdac28-b97f-53e0-adf8-48d022f3eecc","frontmatter":{"category":"Coding","title":"Integration Test Speedup with Spring","date":"2019-03-11","summary":"Here is what we found on speeding up your integration tests in spring based applications.","thumbnail":null,"authorName":"Boris Faniuk","authorDescription":"Boris is a former member of Engineering of AUTO1 Group.","authorAvatar":{"relativePath":"pages/integration-test-speedup/avatar.png","childImageSharp":{"resolutions":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsSAAALEgHS3X78AAACyElEQVQ4y4VUO2gUURR9mZmN8YcItoKVjeXuzsxu9jOzm92NkBBTqDEmjZAEgtqIpSgI1gp+uhS6kEI7wc7GQsFCLERiISGCaGHhF02yu+M5s/cujyC4cJY379573r3n3XdNvV51xsYiJ4rKbqlUyBj8wjAYyWazp4BVYB3YAraBDeAhMBcE/l76lkrFTLVachuNyCGXEbJMrVbx6ADnaWAtn88nvu8nWBMdQcJ9Auv3wCxjWq2aC9IMSF3DzCyyG1YAs9pSYkL2melmLpfT71tKGkUlz2iZJAuCgA5dEjGAwPoV0AbuAy+tfR7YkZjb5CiXR1OutEw5jWQdCfgCnEiSxNg/7LWAj+KTSiHSzBvrAtascrriPCmnDkP4AYQ0Em3TGPHf8P38ARpP/4PsHQ7aU69Hqdi4OJeI47JXLg9IX1tVbUuWCzSsygcJO+L0goGNRpySoB1colarerhEvcCn4tuxCB/TsC5ZdS3Ct2Ho75uZmRoigWbIbgCxt7Q0O8TLsgg17o2R2+JHzzJcV/1IoBlybel42SLsCcc3I6UqoaZ+lUHFYjjCzJSQa+4J4UVLKiX8ScOGVXJXDN+xd7SfZXFYS65U+n2Wz+cOw+ezHadSkfCRdVJiZdlmMG9ZtHMpgWR3Z0eMSvWExjmrbXoCbZ951dIim7Yk6u1IYtlwavChW51Pp01tXOwf01eC9RHs/Rbbnx2Hf4IUh/Q5zdol8H3KG22Pj9edOK54LF1876pd37TELhqdZ+J4MwxDHUvXgDOFQrB7YqLpjI4WdhG8GLYNbCeBK/1+TWNWRG+Pfy5Hj5Dek3IXzX9+8DkL/AIeLC/PDU1NHXdSQk5altNsDkjPAT+ArzKyFnK5bB2IxbYik4hanmfM5GTL6Q/Y2DUc25y0HLToubR8TI39cL4APJOxr/35AXgOXEJnHKQvepP6eiQj119kDrZjqLo8HAAAAABJRU5ErkJggg==","width":50,"height":50,"src":"/static/26a7a327ccc4b335712e5a7086f2b26d/45876/avatar.png","srcSet":"/static/26a7a327ccc4b335712e5a7086f2b26d/45876/avatar.png 1x,\n/static/26a7a327ccc4b335712e5a7086f2b26d/eb85b/avatar.png 1.5x,\n/static/26a7a327ccc4b335712e5a7086f2b26d/4f71c/avatar.png 2x,\n/static/26a7a327ccc4b335712e5a7086f2b26d/9ec3e/avatar.png 3x"}}},"headerImage":{"relativePath":"pages/integration-test-speedup/header.jpg","childImageSharp":{"resolutions":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAABQABAv/EABYBAQEBAAAAAAAAAAAAAAAAAAIAAf/aAAwDAQACEAMQAAABJ6Uw4FJSv//EABsQAAICAwEAAAAAAAAAAAAAAAECAAMEFCEx/9oACAEBAAEFAl9tuawzH6WUPNYT/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFREBAQAAAAAAAAAAAAAAAAAAARD/2gAIAQIBAT8BJ//EABsQAAEEAwAAAAAAAAAAAAAAAAABEBIhIjFR/9oACAEBAAY/AjJo9SizZ//EABwQAQEAAgIDAAAAAAAAAAAAAAERAHEQMUFR0f/aAAgBAQABPyFMdusqfAgeuBQwbbGHwF1jT4z/2gAMAwEAAgADAAAAELsf/8QAFhEBAQEAAAAAAAAAAAAAAAAAARBB/9oACAEDAQE/EA2f/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAERIf/aAAgBAgEBPxDSpD//xAAbEAEBAQADAQEAAAAAAAAAAAABEQAhMXFBYf/aAAgBAQABPxAMiBZ241OQL4wZbyughIofpPEuZhdFS61EeZ//2Q==","width":1024,"height":768,"src":"/static/9f60dcc74069c89c91db86dc33946167/9f594/header.jpg","srcSet":"/static/9f60dcc74069c89c91db86dc33946167/9f594/header.jpg 1x"}}}},"html":"<h2>Problem statement</h2>\n<p>Over time we realized that our microservices built on top of Spring framework take tons of time on the integration test step. Every single PR runs all tests and this takes 10-20 minutes for some services. To decrease PR build time we decided to research why this happens.\nOne of the problems that this research highlighted is ramping up heavy spring context several times during execution of all module’s tests.</p>\n<p>As a proof of concept we have taken 3 modules and cleaned up their tests to achieve better integration test performance.</p>\n<p>The results are pretty much self-explanatory: </p>\n<ol>\n<li>Module A now takes 3 minutes to test versus 11 before</li>\n<li>Module B now takes 3 minutes to test versus 8 before</li>\n<li>Module C now takes 4 minutes to test versus 12 before</li>\n</ol>\n<p>Below I list all factors that produce many spring contexts and how we managed to overcome them.</p>\n<h2>Spring features to be avoided</h2>\n<h3><code class=\"language-text\">@ActiveProfiles</code> and <code class=\"language-text\">@ContextConfiguration</code> with different attributes</h3>\n<p>Our spring-based microservices actively use spring profiles and configuration classes.\nMany components from common libraries are hidden under profiles and configuration classes to not be active for every single module / environment without need. So, integration test authors define profiles and configuration classes that should be activated for their tests using these annotations:</p>\n<ol>\n<li><code class=\"language-text\">@ActiveProfiles({\"integration-test\", \"pg-test\", \"mongo-test-two-nodes\"})</code></li>\n<li><code class=\"language-text\">@ContextConfiguration(classes = {Application.class, AwsTestConfiguration.class})</code></li>\n</ol>\n<p>Here <em>mongo-test-two-nodes</em> activates special mode for mongo based services to operate with two separate mongo instances. As not all tests need this, the profile is turned off by default and only those tests that need this behaviour would explicitly turn it on. But this, unfortunately, leads to multiple spring contexts being created.</p>\n<p>The same happens with <em>AwsTestConfiguration</em> that deploys special test-component to mock AWS calls.</p>\n<p>The solution was to make all tests use the same set of active profiles and context configuration classes for every single integration test.\nThe drawback is that some components are deployed, even for the tests that do not need it. But deploying single component takes O(1) time comparing with the whole spring context.</p>\n<p>Another point to keep in mind is that order of profiles (configuration classes) matters.\n<code class=\"language-text\">@ActiveProfiles({\"integration-test\", \"pg-test\"})</code>\n<code class=\"language-text\">@ActiveProfiles({\"pg-test\", \"integration-test\"})</code></p>\n<p>Two settings mentioned above result in 2 different spring contexts.</p>\n<h3><code class=\"language-text\">@SpyBean</code> and <code class=\"language-text\">@MockBean</code></h3>\n<p>One interesting feature in spring-boot-test is mocking / spying real spring beans.\nThis was mostly used when we don’t care what some method does in test but we need to check that it was called by parent components.\nUnfortunately this also makes test to create separate spring context.\nWhat we’ve done here is replacing <code class=\"language-text\">@SpyBean</code> annotation with configuration class that wraps real spring bean into <code class=\"language-text\">Mockito.spy(..)</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">@Configuration\npublic class SomeComponentSpyFactory {\n\t@Autowired\n\tprivate SomeComponent someComponent;\n\n\t@Bean\n\t@Primary\n\tpublic SomeComponent someComponentSpy() {\n    \t\treturn Mockito.spy(someComponent);\n\t}\n}</code></pre></div>\n<p>Another option is to use the combination of <code class=\"language-text\">@Autowired</code> and <code class=\"language-text\">@Spy</code> annotations.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">\t@InjectMocks\n\t@Autowired\n\tprivate ParentComponent parentComponent;\n\n\t@Spy\n\t@Autowired\n\tprivate ChildComponent childComponent;</code></pre></div>\n<p>However, the drawback of the last solution is that, <em>parentComponent</em> needs to have a setter for <em>childComponent</em> which is not good in terms of encapsulation. But if you don’t use autowiring on constructor level it is fine. Anyway, one can choose whatever fits the situation better.</p>\n<h3><code class=\"language-text\">@DirtiesContext</code></h3>\n<p>One of the services used this annotation to clear the caches between different tests.\nClearing a cache is really a problem (see section below), but this solution comes to separate spring context per test class or even test method (depending on annotation parameters). Context per method was actually the case for a few test classes. Instead in this modules we added methods to clear the caches programmatically without deploying the whole new context.\nOne can use java reflection API instead of adding special production-level methods, again whatever fits you better.</p>\n<h2>Challenge: test execution order and cleaning collections (caches)</h2>\n<p>After all this “multiple context” factors are gone one may face (and we did) a challenge to fix or re-organize some tests. Before above enhancements were done all tests were running in separate spring contexts, therefore used separate instances of every component and therefore those problems could be hidden.</p>\n<p>As an example some tests in mongo-based service were testing <code class=\"language-text\">getAll()</code>-like operations. Those tests were running functions that fetched all records from some collections. This was not a problem as embedded mongo DB was different instance. After all tests started to exploit the same spring context some of them started to fail intermittently. The failures were intermittent because test execution order is different. One service may break another, but not vice versa.\nSo, to overcome this, we added missing <code class=\"language-text\">@Before</code> operations that cleaned those collections.</p>\n<p>The rule that I would suggest here is that every test should clean up whatever it needs to be clean and not rely on fairness of other tests. That was a problem in our case. Some tests had <code class=\"language-text\">@After</code> operations that cleaned up, but not everything produced by the test was cleaned up. This caused intermittent failures of other tests.</p>\n<h2>Tools we created to reduce test execution time</h2>\n<p>So, now after we know all this, we created two tools (and may create more in future) that help to identify those problems.</p>\n<h3>Jenkins PR pipeline step</h3>\n<p>After every PR commit we run one additional step that analyzes test execution log.\nIf more than one spring context is created this leaves some traces and a notification is sent to the author of the commit via slack</p>\n<p>As an enhancement, the jenkins jobs could be modified to fail the build if the number of spring contexts is greater than a certain threshold. The threshold could start with a high number and can gradually be reduced as the team cleans up the existing tests by adopting the aforementioned practices/fixes</p>\n<h3>IntelliJ IDEA plugin</h3>\n<p>We wrote an IntelliJ plugin to identify and solve the aforementioned problems. There will be a separate blog post about this plugin coming very soon.</p>","fields":{"slug":"/integration-test-speedup/","tags":["auto1","engineering","spring","java","testing"]}}},{"node":{"id":"458b814a-9266-529b-a538-b64d05af8cc6","frontmatter":{"category":"QA","title":"How to O(1) your test preparation","date":"2019-01-29","summary":"Are you sure your tests are fast enough?","thumbnail":null,"authorName":"Alexander Gyulai","authorDescription":"Head of Quality Assurance at AUTO1 Group","authorAvatar":{"relativePath":"pages/faster-automation-tests/avatar.png","childImageSharp":{"resolutions":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsSAAALEgHS3X78AAACyElEQVQ4y4VUO2gUURR9mZmN8YcItoKVjeXuzsxu9jOzm92NkBBTqDEmjZAEgtqIpSgI1gp+uhS6kEI7wc7GQsFCLERiISGCaGHhF02yu+M5s/cujyC4cJY379573r3n3XdNvV51xsYiJ4rKbqlUyBj8wjAYyWazp4BVYB3YAraBDeAhMBcE/l76lkrFTLVachuNyCGXEbJMrVbx6ADnaWAtn88nvu8nWBMdQcJ9Auv3wCxjWq2aC9IMSF3DzCyyG1YAs9pSYkL2melmLpfT71tKGkUlz2iZJAuCgA5dEjGAwPoV0AbuAy+tfR7YkZjb5CiXR1OutEw5jWQdCfgCnEiSxNg/7LWAj+KTSiHSzBvrAtascrriPCmnDkP4AYQ0Em3TGPHf8P38ARpP/4PsHQ7aU69Hqdi4OJeI47JXLg9IX1tVbUuWCzSsygcJO+L0goGNRpySoB1colarerhEvcCn4tuxCB/TsC5ZdS3Ct2Ho75uZmRoigWbIbgCxt7Q0O8TLsgg17o2R2+JHzzJcV/1IoBlybel42SLsCcc3I6UqoaZ+lUHFYjjCzJSQa+4J4UVLKiX8ScOGVXJXDN+xd7SfZXFYS65U+n2Wz+cOw+ezHadSkfCRdVJiZdlmMG9ZtHMpgWR3Z0eMSvWExjmrbXoCbZ951dIim7Yk6u1IYtlwavChW51Pp01tXOwf01eC9RHs/Rbbnx2Hf4IUh/Q5zdol8H3KG22Pj9edOK54LF1876pd37TELhqdZ+J4MwxDHUvXgDOFQrB7YqLpjI4WdhG8GLYNbCeBK/1+TWNWRG+Pfy5Hj5Dek3IXzX9+8DkL/AIeLC/PDU1NHXdSQk5altNsDkjPAT+ArzKyFnK5bB2IxbYik4hanmfM5GTL6Q/Y2DUc25y0HLToubR8TI39cL4APJOxr/35AXgOXEJnHKQvepP6eiQj119kDrZjqLo8HAAAAABJRU5ErkJggg==","width":50,"height":50,"src":"/static/26a7a327ccc4b335712e5a7086f2b26d/45876/avatar.png","srcSet":"/static/26a7a327ccc4b335712e5a7086f2b26d/45876/avatar.png 1x,\n/static/26a7a327ccc4b335712e5a7086f2b26d/eb85b/avatar.png 1.5x,\n/static/26a7a327ccc4b335712e5a7086f2b26d/4f71c/avatar.png 2x,\n/static/26a7a327ccc4b335712e5a7086f2b26d/9ec3e/avatar.png 3x"}}},"headerImage":{"relativePath":"pages/faster-automation-tests/header.png","childImageSharp":{"resolutions":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsSAAALEgHS3X78AAABtklEQVQY0wGrAVT+AAACBAAEBwAECAQECA0ECRoECCwFCEEFCVYECGsECHkECYYECZUGDKIKEKEMEaMLEqcQHK4aJKo5PjghPwBTAwdiAgRvAQOBAQONAAORAQWOAweFBAmCCA18Cw9zDhFlEhRMEhI4ERdGHC5XOlZyXHx9hqiGosqfkLcAXQEEUwIFSgkNNgsQJA0SHxMWGBMVERUVCBMSARAPAA8SAQ0VAAsjHy1Rd36i0NTk9Pv//f3+/8zj14CnAAcSFgUTFgcQEAoQDgsODAYICAUGCQUFCwQIEwQIGwIJLBAbRz9Md5CevNje7f/q8PvT4c6Yu21CexENPgAIBQEHAwMBAAUAAAgABBQCCRkDDB0CDB8LEy8tN1xub465qb/uwdb3r8zdi7i4cKZ5VYsgJlkABSkBAhYAAAIQAAUTAwobBxAgBA4ZCBAfISY4WFtznZau0rTI76rD5YGoxlaSkzyAVS9xGiRcABM+AQklBQkXAQQLAAYOGAsVHw4ZIBUaJ0dDWJGOoM3Azty0xtGIqbZXiaA7fY0qdUwkZREbUgAQPQAGJAMEFQMGEgACBwAAAMagbU9WOO54AAAAAElFTkSuQmCC","width":1280,"height":445,"src":"/static/34ed0cae6856ac71c7fea1ac46b6a5a9/26421/header.png","srcSet":"/static/34ed0cae6856ac71c7fea1ac46b6a5a9/26421/header.png 1x"}}}},"html":"<p><em>(*) If your career as a QA - like the author’s - started without a computer science degree, you will hopefully love\nto hear and learn about the different theories and notations of runtime analysis.\nCheck wikipedia’s page about O-notation</em> <a href=\"https://en.wikipedia.org/wiki/Big_O_notation\">here</a></p>\n<p>Speed… Did you ever think how you can make your tests faster and more reliable? If you're anything like me or my colleagues at AUTO1,\nyou face this challenge all the time. Here at AUTO1 we are constantly looking for new ways to improve our tools and\nto make testing fast and efficient. In this article, I’m going to take test suite that takes ~70 min and reduce the execution time to 1 min!!!\nInteresting, right? :)</p>\n<h2>Intro</h2>\n<p>Let’s imagine we are testing some Web Shop Scenario. We need to test that users can do some actions with items they purchased\n(submit feedback, return, submit claim, etc.). And imagine that in this case we have exactly 20 scenarios that go like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">Steps:\n- Create item, put item in certain state\n- Create user\n- Create user delivery address\n- Create user billing address\n- Create user payment details\n- Sell item to user\n- User does something with an item</code></pre></div>\n<h2>Back in times…</h2>\n<p>Let’s look at the timeline of our test</p>\n<p><a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/53febc88a158cff2aeae3979e1d5f8c6/dfeb3/scenario-v1.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 590px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 28.77164056059357%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsSAAALEgHS3X78AAABDUlEQVQY04WQWU/CQBSF+6/d8AG3P+ECcemLPrglmvgAsS7RB5cIWIwJUKzGmCiVYkvbmc8ZsAkYiZPcnHPuPXcycww/SEgSicb3doyUEq+TqIoRQvLmxYSR6PHXVkQUC9rK2/L7c72jtd7TZfDPkSP4qGNM5qpk8g/Mmo8Kq2g9bypcLjGdrzC3cc/4Uonsmk12tcKE4jPrNplcmamVMgumzdjindqxCboJxlaxzt6pQ+HK7eHR5ROHF002CzWOr122rQY7Vh3rxkV7D84disq7e9JQPof9s6bq17BuX/pffv4QdLrDzw5j8AJQcal8wP+Zfyr+FQ17/RDEQBaGvlWnk4aa6t812P/Lm+pvrbW8il8UgXMAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    ></span>\n    <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\"\n        alt=\"ScenarioV1\"\n        title=\"ScenarioV1\"\n        src=\"/static/53febc88a158cff2aeae3979e1d5f8c6/40fad/scenario-v1.png\"\n        srcset=\"/static/53febc88a158cff2aeae3979e1d5f8c6/707e9/scenario-v1.png 148w,\n/static/53febc88a158cff2aeae3979e1d5f8c6/649e0/scenario-v1.png 295w,\n/static/53febc88a158cff2aeae3979e1d5f8c6/40fad/scenario-v1.png 590w,\n/static/53febc88a158cff2aeae3979e1d5f8c6/b3fef/scenario-v1.png 885w,\n/static/53febc88a158cff2aeae3979e1d5f8c6/301c0/scenario-v1.png 1180w,\n/static/53febc88a158cff2aeae3979e1d5f8c6/dfeb3/scenario-v1.png 1213w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n      />\n  </span>\n  </a></p>\n<p>In this case, if you have twenty tests and you run them sequentially, it will take ~73 min.</p>\n<h2>Time to Improve!</h2>\n<p>What we can improve here? Of course everybody will say “Pffff, let’s run in parallel!”.\nThis is everyone’s first call, but for parallel execution you must always consider multiple aspects:</p>\n<ul>\n<li>Your test should neither rely nor be affected by tests running in parallel. It should be completely isolated.</li>\n<li>You must consider the application under tests. Is it capable of handling parallel execution? Do you have any external\ndependencies that can prevent you from this? Will your application behave in the same way if you run 20 tests concurrently?\nYou can run 20, 50 or 1000 parallel tests on your application, nevertheless under some circumstances you might want to\nreduce number of parallel threads.</li>\n</ul>\n<p>Let’s imagine we would like to keep ten threads for start. </p>\n<p><a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/d2f1d79c60cd7407462532ce51d3d964/df03a/suite-v1.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 590px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 62.589928057553955%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAABHklEQVQ4y61U20rDQBDNXyso+C9F9Au0+u5zqiiCFQULNsYHY7Dd7sxejrOXYDF9SrNwmJPsZDhnZkhhrYVzDt47QBD4UHjvUQQilUDGYaUTDxdDUQjiea4Y17cqcuvyywGnYDZR1dO7xmW5ipyN3cdyUjNfMqazdVJo97Dssudg+Wo2hmUzsuXtoYyi0Mgeph4SpmXqobG7FVjbx7a6qDAV9KlgHoox/WJh6UNeH/8sd1LnS4OLMlne5XjDwMOCcZ9x95aior+cWJBIMj3jtVK4efwRTlirDbTWICKJBG8Zi1rh5PwTR6c1DicVDiYfOD6r8SLfecfQRLmHMuUAK3Biv21bNE0TY3fXQSpLHqH9/oJhnZ8NwqaEf0IQ8Qu8S/jkKbPmpwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    ></span>\n    <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\"\n        alt=\"SuiteV1\"\n        title=\"SuiteV1\"\n        src=\"/static/d2f1d79c60cd7407462532ce51d3d964/40fad/suite-v1.png\"\n        srcset=\"/static/d2f1d79c60cd7407462532ce51d3d964/707e9/suite-v1.png 148w,\n/static/d2f1d79c60cd7407462532ce51d3d964/649e0/suite-v1.png 295w,\n/static/d2f1d79c60cd7407462532ce51d3d964/40fad/suite-v1.png 590w,\n/static/d2f1d79c60cd7407462532ce51d3d964/b3fef/suite-v1.png 885w,\n/static/d2f1d79c60cd7407462532ce51d3d964/df03a/suite-v1.png 1112w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n      />\n  </span>\n  </a></p>\n<p>We significantly increased the speed. From ~73 to ~8 minutes. This already looks like a game changer! But can we do more? Spoiler: Yes we can!</p>\n<h2>Removing dependencies</h2>\n<p>If we check our test scenario again, we can clearly see that the actual validation of our test scenario happens only\nafter the third minute! And everything we have up until then it’s just creating preconditions.\nWhat we actually want to test is: <em><strong>“User can do certain action with item purchased on our platform”</strong>.</em>\nWe should not care <strong>HOW</strong> we got this item, we should have another test, testing that user should be able to purchase.\nThis just creates dependency for us that makes our tests:</p>\n<ol>\n<li>Slower</li>\n<li>Less stable. It becomes less stable because we have to go through multiple steps (in some cases maybe through multiple\napplications) with creating item, creating user, adding user info and so on. If something will fail in the middle (which can happen easily)\nit doesn’t really mean that user couldn't leave a feedback on the item.</li>\n</ol>\n<p>   <em>P.S. While writing this article I tried to re-create all these conditions and I didn’t have any successful build.\nAnd it was always something related to other dependencies.</em> </p>\n<p><strong>Solution?</strong> There are many possible answers, the one I chose for this example is to move all logic with test data preparation to the API layer.\nLet’s try this and review our timeline again</p>\n<p> <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/df680a4cadba8a015fb5727b6e47a554/68371/scenario-v2.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 590px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 31.275385865150284%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsSAAALEgHS3X78AAAA9ElEQVQY061QTU/CQBDtX8cU9UDgR2gR5CN4UtBAkAtcvNOybYFoNJ6Mabttd/c5uysETlzY5GXevHkz2RlHKYU0lyiERF5IZMSFtFpeSpSkJ1xACAV+UM+IF6XNU10nTc9ycObnhJ8pLluhQa0bw20yVDXvrHBxuzTxquXD9XzDXW9JeYDrdoAK1Rt9Znz1HjMbOB/fCZrPDP1pjOFii940wuN8g84kwv04xBPxmyGjuMbgNcbdC8NosTH8YRZhMFvDG60weXu3Kydc4etHIRfHX+clkBEU8V9uNToZ0uLYp/vk4cp6qm2zR91hp+1xwif/8z8Hu78KDjTTEgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    ></span>\n    <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\"\n        alt=\"ScenarioV2\"\n        title=\"ScenarioV2\"\n        src=\"/static/df680a4cadba8a015fb5727b6e47a554/40fad/scenario-v2.png\"\n        srcset=\"/static/df680a4cadba8a015fb5727b6e47a554/707e9/scenario-v2.png 148w,\n/static/df680a4cadba8a015fb5727b6e47a554/649e0/scenario-v2.png 295w,\n/static/df680a4cadba8a015fb5727b6e47a554/40fad/scenario-v2.png 590w,\n/static/df680a4cadba8a015fb5727b6e47a554/b3fef/scenario-v2.png 885w,\n/static/df680a4cadba8a015fb5727b6e47a554/301c0/scenario-v2.png 1180w,\n/static/df680a4cadba8a015fb5727b6e47a554/68371/scenario-v2.png 1231w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n      />\n  </span>\n  </a></p>\n<p> Amazing, this is how our test looks now! two minutes just gone.</p>\n<p> And this is how our suite looks now comparing to other runs.\n<a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/85c2500e17e9f80939393028938cff4d/a7e37/suite-v2.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 590px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 54.833040421792624%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABB0lEQVQoz62TTU7DMBCFe3WQuAtCHINuaBddsaFlU7Gomjauyzi2Y8/DM+4fC4qUMtJL4rH15nM8HuWcEWNEZgaQwZwhuSHi4jGShwwkNvuEmMSYdXKI1DClavj67mFd/R5sKHQhRDWZzrtimJTwxi1zNVx47P+D0IegJhMhpBsJKw3OhF0lvAyZP+qvuCBkJdxRr+1zqqodcNaxreQgT/rtH07mHl/+J4Y0gKGMnWN9p3wdUw37Pmn12YdDaz36GA4nn7FcB9w/Nbh7XOHhudExOJW1hPGbxUvRZ+M1J5SHPkx6W0LZujFGRUSlUMmVvOs8NtsW5DpdJzKWsFq3aFqr83rbiuE3AelfXfVuxx0AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    ></span>\n    <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\"\n        alt=\"SuiteV2\"\n        title=\"SuiteV2\"\n        src=\"/static/85c2500e17e9f80939393028938cff4d/40fad/suite-v2.png\"\n        srcset=\"/static/85c2500e17e9f80939393028938cff4d/707e9/suite-v2.png 148w,\n/static/85c2500e17e9f80939393028938cff4d/649e0/suite-v2.png 295w,\n/static/85c2500e17e9f80939393028938cff4d/40fad/suite-v2.png 590w,\n/static/85c2500e17e9f80939393028938cff4d/b3fef/suite-v2.png 885w,\n/static/85c2500e17e9f80939393028938cff4d/a7e37/suite-v2.png 1138w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n      />\n  </span>\n  </a></p>\n<p> Again we manage to halve the test execution time! Considering that it was already pretty fast, it's a great improvement.\nSo at this point you might think we are done here, it’s time to go to bar, grab a beer and celebrate.\nBut then you come back the next day and think \"there must be more\"...</p>\n<p>Having test preparation using API is a great step here, but does it scale from 20 tests to 1000 without having side-effects?\nAt the end, your test data preparation might look like this:</p>\n<p><img src=\"/static/machingun-f6e9bbc355090a0e8c6db2e891dfb64a.gif\" alt=\"machingun\" title=\"Suitemachingun\"></p>\n<p>Assuming you have around 40 calls with a reasonable fan-out for every scenario and you usually run tests in multiple threads,\nyou might involuntary start a load test there. Aaaaand it’s time to look for a solution again!</p>\n<h2>Introducing Q-Service</h2>\n<p>What if we have our test data waiting for us somewhere? Wouldn’t be amazing?!\nOur solution for this problem was to create a Web Service that would keep the data in a queue for us.\nIt provides couple of huge benefits for us:</p>\n<ol>\n<li>Instead of doing all these calls in runtime, we do 1 single call to our API to get test data. And instead of 1 min in test preparation we got &#x3C;1 sec!</li>\n<li>We don’t overload the system while executing tests. Which also means for us we can run more tests in parallel!</li>\n<li>Tests are way more stable. Now we just need to take our test data and check that user can do certain action with that item.</li>\n</ol>\n<p>Let’s look at our timeline again. This is how our test scenario changed:</p>\n<p><a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/7756153b5c3b401f4d48add89a0b22f0/e1bf1/scenario-v3.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 590px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 44.48160535117057%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA/klEQVQoz61STUvDQBDNn7OgHnvqyZ+hNKdePPQPVPyoF6GXtpoexJ8QQTdFz/4BD2LFNDHZ2efOLkm2aQgU+uCx82aGt8zOetBQSqEAx4V28y7qebffK0SaEZI/2jBtoySF34RATo5RGrLZTyyRGlPFrrapRtvPhoTvOMc6ldVFbGiL1QhSk7AbpKpG9zhY6ZtOhkt0zkIc9p/RHbygdy6MPtKac3we+/r0rS7I+uA0xPJjZUc246YZ7h7fMJq+4nIuMHl6N7y+FxgHkeGVjrl+MRO4eYjK/DgQuF1E+PyKN99wHyhHNluTZJg3Mbc1Isumnq0tq9r623TbP/0H4QWmFav5swkAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    ></span>\n    <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\"\n        alt=\"ScenarioV3\"\n        title=\"ScenarioV3\"\n        src=\"/static/7756153b5c3b401f4d48add89a0b22f0/40fad/scenario-v3.png\"\n        srcset=\"/static/7756153b5c3b401f4d48add89a0b22f0/707e9/scenario-v3.png 148w,\n/static/7756153b5c3b401f4d48add89a0b22f0/649e0/scenario-v3.png 295w,\n/static/7756153b5c3b401f4d48add89a0b22f0/40fad/scenario-v3.png 590w,\n/static/7756153b5c3b401f4d48add89a0b22f0/b3fef/scenario-v3.png 885w,\n/static/7756153b5c3b401f4d48add89a0b22f0/301c0/scenario-v3.png 1180w,\n/static/7756153b5c3b401f4d48add89a0b22f0/e1bf1/scenario-v3.png 1196w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n      />\n  </span>\n  </a></p>\n<p> And our test suite looks like this right now:</p>\n<p><a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/74d130f14924155f9097ed923d184939/6f904/suite-v3.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 590px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 55.95854922279793%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABAElEQVQoz62SUU7DMBBEc3KuwDE4AP8coh8IUSpUELSB2I7jxIntXQ+2MfCDhEhraSTvrjR6O9qGmeGcA2JMYuR6rWLyaGIxinAhwsyMVJTBWjWcDcEQhrA9eOTHfIphRuUAmQwfDq4QEp20coGCHBm7Yyj/r96a1xQa8mXlMxF+4uSVd8eaYTxDhsKEPwlzPxB/z6nqV0KVM2xrhjWPelH4T6T1Dgnv/YLti020HhQ8Ou1wed3h4uoNNxuDkHq3+wmbxwmvYkbwHr1ZoJIm69I8/BASEZxPp6M0tNaw1sIHwnM74v5JQo8ei/Plf7dXaMWIYRjQySRlIGSPZZkL4QfC8mBOKQFpMgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    ></span>\n    <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;box-shadow:inset 0px 0px 0px 400px white;\"\n        alt=\"SuiteV3\"\n        title=\"SuiteV3\"\n        src=\"/static/74d130f14924155f9097ed923d184939/40fad/suite-v3.png\"\n        srcset=\"/static/74d130f14924155f9097ed923d184939/707e9/suite-v3.png 148w,\n/static/74d130f14924155f9097ed923d184939/649e0/suite-v3.png 295w,\n/static/74d130f14924155f9097ed923d184939/40fad/suite-v3.png 590w,\n/static/74d130f14924155f9097ed923d184939/b3fef/suite-v3.png 885w,\n/static/74d130f14924155f9097ed923d184939/6f904/suite-v3.png 1158w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n      />\n  </span>\n  </a></p>\n<p>We barely can see it on our timeline :)</p>\n<ul>\n<li>1 test now takes ~30s to run (instead of 3m 40s). And it’s “slow” and “unstable”(as it’s usually called) UI end-to-end test. </li>\n<li>Entire suite takes ~1m</li>\n<li>We can easily double the number, if we need, since these tests are producing a very little amount of our resources</li>\n</ul>\n<h2>How does it work?</h2>\n<p>Stay tuned! We will open-source it soon!</p>\n<h2>Summary</h2>\n<p>In AUTO1 Group, every day we are looking for smarter ways to do software development and testing.\nAnd the main point in this article is that you should never stop innovating and looking for new solutions to existing problems.\nSomething that works for us, is not necessarily going to work for you,\nbut maybe you will ask yourself: <em><strong>“Where is our next level? Can we do something better?”</strong></em></p>","fields":{"slug":"/faster-automation-tests/","tags":["testing","automation"]}}}]}},"pageContext":{"slug":"/tags/testing","tag":"testing","categories":["Architecture","Coding","DevOps","Engineering","ProjectManagement","QA","Social","TechRadar"]}}