<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title>Chemaclass - refactoring</title><subtitle>Tech Lead sharing practical insights on software craftsmanship, TDD, leadership, Bitcoin, and AI. Blog posts, book summaries, and conference talks.</subtitle><link rel="self" type="application/atom+xml" href="https://chemaclass.com/tags/refactoring/atom.xml"/><link rel="alternate" type="text/html" href="https://chemaclass.com"/><generator uri="https://www.getzola.org/">Zola</generator><updated>2022-07-11T00:00:00+00:00</updated><id>https://chemaclass.com/tags/refactoring/atom.xml</id><entry xml:lang="en"><title>Clean Craftsmanship</title><subtitle>Disciplines, Standards, and Ethics</subtitle><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="xp" scheme="https://chemaclass.com/tags/xp/" label="Xp"/><published>2022-07-11T00:00:00+00:00</published><updated>2022-07-11T00:00:00+00:00</updated><author><name>
Robert C. Martin</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/clean-craftsmanship/"/><id>https://chemaclass.com/readings/clean-craftsmanship/</id><summary type="html">Uncle Bob on the three pillars of craftsmanship: TDD disciplines with examples, standards for teams, and a programmer's ethics.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>
&lt;p>The book is divided into three parts: the disciplines, the standards, and the ethics.&lt;/p>
&lt;p>The 1st part is the most technical one. It guides you with &lt;a href="/blog/test-driven-development/">TDD&lt;/a> examples, showing how &lt;a href="/blog/the-art-of-testing/">testing&lt;/a> can help you to design your code.&lt;/p>
&lt;p>The 2nd part is about productivity, quality, and courage.&lt;/p>
&lt;p>The 3rd part is about how did we get here in terms of people who develop software, and our responsibility within
our ethics about do no harm, integrity, and teamwork.&lt;/p>
&lt;hr />
&lt;p>One of my favourite parts from the book:&lt;/p>
&lt;blockquote>
&lt;p>Our software industry is wildly dynamic and changing; therefore, we must all be continuously aggressive learners.&lt;/p>
&lt;p>How and when do you do this learning? If your employer provides you the time and space to do this kind of learning, then
take as much advantage of it as you can. If your employer is not helpful, then you’ll have to learn on your own time.&lt;/p>
&lt;p>Be prepared to spend several hours per month on it. Make sure you have the personal time set aside for it.&lt;/p>
&lt;p>Yes, I know you have family obligations, bills to pay, planes to catch, and you’ve got a life. Okay, but you also have a
profession. And professions need care and maintenance. I expect us all to be continuous aggressive learners.&lt;/p>
&lt;p>&lt;code>Chapter 11. Courage - Continuous Aggressive Learning&lt;/code>&lt;/p>
&lt;/blockquote>
&lt;hr />
&lt;h2 id="index">Index
&lt;a class="heading-anchor" href="#index" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="part-i-the-disciplines">Part I: The Disciplines
&lt;a class="heading-anchor" href="#part-i-the-disciplines" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;h4 id="chapter-1-craftsmanship">Chapter 1. Craftsmanship
&lt;a class="heading-anchor" href="#chapter-1-craftsmanship" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>&lt;a href="/blog/update-your-team-to-be-more-extreme/">Extreme Programming&lt;/a>&lt;/li>
&lt;li>Test-Driven Development&lt;/li>
&lt;li>&lt;a href="/blog/the-art-of-refactoring/">Refactoring&lt;/a>&lt;/li>
&lt;li>Simple Design&lt;/li>
&lt;li>Collaborative Programming&lt;/li>
&lt;li>Acceptance Tests&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-2-test-driven-development">Chapter 2. Test-Driven Development
&lt;a class="heading-anchor" href="#chapter-2-test-driven-development" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Overview&lt;/li>
&lt;li>The Basics&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-3-advanced-tdd">Chapter 3. Advanced TDD
&lt;a class="heading-anchor" href="#chapter-3-advanced-tdd" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Getting Stuck&lt;/li>
&lt;li>Arrange, Act, Assert&lt;/li>
&lt;li>Test Doubles&lt;/li>
&lt;li>Architecture&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-4-test-design">Chapter 4. Test Design
&lt;a class="heading-anchor" href="#chapter-4-test-design" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Testing Databases&lt;/li>
&lt;li>Testing GUIs&lt;/li>
&lt;li>Test Patterns&lt;/li>
&lt;li>Test-Specific Subclass&lt;/li>
&lt;li>Humble Object&lt;/li>
&lt;li>Test Design&lt;/li>
&lt;li>Breaking the Correspondence&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-5-refactoring">Chapter 5. Refactoring
&lt;a class="heading-anchor" href="#chapter-5-refactoring" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>What Is Refactoring?&lt;/li>
&lt;li>The Basic Toolkit&lt;/li>
&lt;li>Extract Method&lt;/li>
&lt;li>The Disciplines&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-6-simple-design">Chapter 6. Simple Design
&lt;a class="heading-anchor" href="#chapter-6-simple-design" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>YAGNI&lt;/li>
&lt;li>Covered by Tests&lt;/li>
&lt;li>Coverage&lt;/li>
&lt;li>Design?&lt;/li>
&lt;li>Maximize Expression&lt;/li>
&lt;li>The Underlying Abstraction&lt;/li>
&lt;li>Minimize Duplication&lt;/li>
&lt;li>Minimize Size&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-7-collaborative-programming">Chapter 7. Collaborative Programming
&lt;a class="heading-anchor" href="#chapter-7-collaborative-programming" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;h4 id="chapter-8-acceptance-tests">Chapter 8. Acceptance Tests
&lt;a class="heading-anchor" href="#chapter-8-acceptance-tests" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>The Discipline&lt;/li>
&lt;li>The Continuous Build&lt;/li>
&lt;/ul>
&lt;h3 id="part-ii-the-standards">Part II: The Standards
&lt;a class="heading-anchor" href="#part-ii-the-standards" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;h4 id="chapter-9-productivity">Chapter 9. Productivity
&lt;a class="heading-anchor" href="#chapter-9-productivity" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>We Will Never Ship S**T&lt;/li>
&lt;li>Inexpensive Adaptability&lt;/li>
&lt;li>We Will Always Be Ready&lt;/li>
&lt;li>Stable Productivity&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-10-quality">Chapter 10. Quality
&lt;a class="heading-anchor" href="#chapter-10-quality" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Continuous Improvement&lt;/li>
&lt;li>Fearless Competence&lt;/li>
&lt;li>Extreme Quality&lt;/li>
&lt;li>We Will Not Dump on QA&lt;/li>
&lt;li>QA Will Find Nothing&lt;/li>
&lt;li>Test Automation&lt;/li>
&lt;li>Automated Testing and User Interfaces&lt;/li>
&lt;li>Testing the User Interface&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-11-courage">Chapter 11. Courage
&lt;a class="heading-anchor" href="#chapter-11-courage" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>We Cover for Each Other&lt;/li>
&lt;li>Honest Estimates&lt;/li>
&lt;li>You Must Say NO&lt;/li>
&lt;li>Continuous Aggressive Learning&lt;/li>
&lt;li>Mentoring&lt;/li>
&lt;/ul>
&lt;h3 id="part-iii-the-ethics">Part III: The Ethics
&lt;a class="heading-anchor" href="#part-iii-the-ethics" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>The First Programmer&lt;/li>
&lt;li>Seventy-Five Years&lt;/li>
&lt;li>Nerds and Saviors&lt;/li>
&lt;li>Role Models and Villains&lt;/li>
&lt;li>We Rule the World&lt;/li>
&lt;li>Catastrophes&lt;/li>
&lt;li>The Oath&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-12-harm">Chapter 12. Harm
&lt;a class="heading-anchor" href="#chapter-12-harm" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>First, Do No Harm&lt;/li>
&lt;li>Best Work&lt;/li>
&lt;li>Repeatable Proof&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-13-integrity">Chapter 13. Integrity
&lt;a class="heading-anchor" href="#chapter-13-integrity" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Small Cycles&lt;/li>
&lt;li>Relentless Improvement&lt;/li>
&lt;li>Maintain High Productivity&lt;/li>
&lt;/ul>
&lt;h4 id="chapter-14-teamwork">Chapter 14. Teamwork
&lt;a class="heading-anchor" href="#chapter-14-teamwork" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Work as a Team&lt;/li>
&lt;li>Estimate Honestly and Fairly&lt;/li>
&lt;li>Respect&lt;/li>
&lt;li>Never Stop Learning&lt;/li>
&lt;/ul>
&lt;hr />
&lt;p>I found this chat in YouTube where Uncle Bob talks about most of the topics form his book &lt;strong>Clean Craftsmanship&lt;/strong>.&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/sPXk11hrWTM"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="plain">&lt;span class="giallo-l">&lt;span>Listen out for:&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Quote &amp;amp; Intro - [00:00:00]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Career Journey - [00:07:29]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Clean Craftsmanship - [00:10:53]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Programmer as a Profession - [00:15:31]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Craftsmanship - [00:18:45]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Disciplines - [00:22:45]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Disciplines: Test-Driven Development - [00:28:49]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Disciplines: Refactoring - [00:34:31]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Code Coverage - [00:39:02]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Standard: Never Ship S**t - [00:42:35]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Standard: Always Be Ready - [00:47:15]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Ethics: Do No Harm - [00:50:00]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Ethics: Estimate Honestly - [00:53:56]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* 2 Tech Lead Wisdom - [00:57:50]&lt;/span>&lt;/span>&lt;/code>&lt;/pre></content></entry><entry xml:lang="en"><title>London vs Chicago</title><subtitle>It's an integration, not a choice</subtitle><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><published>2021-11-20T00:00:00+00:00</published><updated>2021-11-20T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/london-vs-chicago/"/><id>https://chemaclass.com/blog/london-vs-chicago/</id><summary type="html">There are two known schools in TDD: the mockist school (aka Outside-in) and the classicist school (aka Inside-out).</summary><content type="html">&lt;p>There are two known schools in TDD: the mockist school (aka Outside-in) and the classicist school (aka Inside-out).&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h3 id="why-london-and-chicago">Why London and Chicago?
&lt;a class="heading-anchor" href="#why-london-and-chicago" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Two companies, one from London and another from Chicago, claimed to do TDD, but they were focused on different aspects.
The London company was building software from outside-in, while the Chicago company from inside-out. Let’s see them in more detail.&lt;/p>
&lt;h2 id="outside-in-london-school">Outside-in: London School
&lt;a class="heading-anchor" href="#outside-in-london-school" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>It provides a behavior-driven approach to TDD. Starting from the outside of the application and working inwards to
lower layers. For example, starting from the API/Controllers down to the application or domain layers.&lt;/p>
&lt;h3 id="pros">PROS
&lt;a class="heading-anchor" href="#pros" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Behavioral Focused&lt;/strong>: this requires a lot of test doubles because you will test a lot of abstractions that don’t exist
yet as you are creating a high level of logic first. You aren’t going to write dead-code but it will be easy to create
tests highly coupled to the logic and therefore making &lt;a href="/blog/the-art-of-refactoring/">refactoring&lt;/a> a difficult task.&lt;/li>
&lt;li>&lt;strong>Command-Query separation&lt;/strong>: is a discipline for managing side effects. Either you perform an action (command) or you ask
for a value (query).&lt;/li>
&lt;/ul>
&lt;h3 id="cons">CONS
&lt;a class="heading-anchor" href="#cons" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Fragile Tests&lt;/strong>: it tends to create tests that break easily because they are usually too coupled to the production code.&lt;/li>
&lt;li>&lt;strong>Difficult Refactoring&lt;/strong>: for the same reason as “Fragile Tests”, having tests coupled to production code make continuous
refactoring very difficult and time-consuming.&lt;/li>
&lt;/ul>
&lt;h2 id="inside-out-chicago-school">Inside-out: Chicago School
&lt;a class="heading-anchor" href="#inside-out-chicago-school" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>It’s an informal, exploratory, state-based approach of TDD. Starting from the inside of the application (usually the
domain) and working out towards the APIs.&lt;/p>
&lt;h3 id="pros-1">PROS
&lt;a class="heading-anchor" href="#pros-1" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Strong Safety Net&lt;/strong>: it tends to produce tests that are decoupled from the implementation. Enabling you to adopt a more
experimental style of changing software without fear of breaking it. This is desired for continuous refactoring.&lt;/li>
&lt;li>&lt;strong>High Cohesion&lt;/strong>: as tests become more general, the production code becomes more specific. This promotes high cohesion,
and with high cohesion comes loose coupling. Something that promotes high code quality: extensibility,
maintainability, and testability.&lt;/li>
&lt;li>&lt;strong>Minimizes Test Doubles&lt;/strong>: building from the inside out requires fewer test doubles since you are building on top of the
previously written tests. This helps to develop less fragile tests.&lt;/li>
&lt;/ul>
&lt;h3 id="cons-1">CONS
&lt;a class="heading-anchor" href="#cons-1" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>YAGNI&lt;/strong>: it’s often over-engineering solutions, with code that is not really needed (or even used!) in the end.&lt;/li>
&lt;/ul>
&lt;h2 id="london-and-chicago-work-better-together">London and Chicago work better together
&lt;a class="heading-anchor" href="#london-and-chicago-work-better-together" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>It’s not about choosing one over the other. It’s about understanding your context and driving optimization towards those
qualities that need to be optimized. London and Chicago each have their pros and cons. The best approach to TDD is an
integrated adoption of these two schools.&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/rbSDGr-_UwY"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;hr />
&lt;h3 id="references">References
&lt;a class="heading-anchor" href="#references" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="/blog/test-driven-development/">Test-Driven (Development)&lt;/a>&lt;/li>
&lt;li>&lt;a href="/blog/tdd-vs-bdd/">TDD vs BDD&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://gist.github.com/xpepper/2e3519d2cb8568a0b13739d9ae497f21">Notes about “London vs Chicago TDD styles”&lt;/a>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="en"><title>Test-Driven (Development)</title><subtitle>What is challenging about it?</subtitle><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><published>2021-08-01T00:00:00+00:00</published><updated>2021-08-01T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/test-driven-development/"/><id>https://chemaclass.com/blog/test-driven-development/</id><summary type="html">TDD is a design practice, not just a testing technique. Writing tests first changes how you think about code and shape its structure.</summary><content type="html">&lt;p>The complexity here is not about writing tests itself, but the &lt;a href="/readings/atomic-habits/">habits&lt;/a> that we have to change to create software that is
easy to be tested.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="the-root-of-the-problem">The root of the problem
&lt;a class="heading-anchor" href="#the-root-of-the-problem" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Without (a solid) experience in testing, developers can have a hard time while trying to apply testing in general as
part of their daily job. It’s not simply because of the topic’s complexity, but &lt;strong>because they are used to writing
code that is hard to test.&lt;/strong>&lt;/p>
&lt;p>Writing tests for already working software (mainly when it was done without considering testing at all) translates as
something boring, next to useless, usually accompanied by a lack of motivation, blaming the wrong subject in this
context: “the tests itself are reducing my speed”.&lt;/p>
&lt;blockquote>
&lt;p>In a domain context, if a piece of software logic is hard to be tested, the problem is not the test, but the code which wasn’t well written.&lt;/p>
&lt;/blockquote>
&lt;p>There are already hundreds of tutorials, books, and documentation about testing, but I can share my experience and how I
do apply this great (and mandatory) philosophy in my daily work.&lt;/p>
&lt;h3 id="test-driven-is-based-on-this-simple-rule">Test-Driven is based on this simple rule
&lt;a class="heading-anchor" href="#test-driven-is-based-on-this-simple-rule" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Instead of: design code -&amp;gt; develop code -&amp;gt; write tests.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="/images/blog/2021-08-01/non-tdd-style.webp" alt="non-tdd-style" />&lt;/p>
&lt;ul>
&lt;li>It’s about: write failing automated test -&amp;gt; run failing test -&amp;gt; develop code to make test pass -&amp;gt; run test -&amp;gt; repeat.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="/images/blog/2021-08-01/tdd-style.webp" alt="tdd-style" />&lt;/p>
&lt;p>The idea of driving your code by testing can be understood depending on the abstraction level of what you’re writing at
the moment. You don’t want to create a wrong coupling between the tests and the code being tested. You want to test the
behavior of your logic.&lt;/p>
&lt;p>TDD is based on a loop of baby steps that helps you find &lt;strong>patterns&lt;/strong> and guide your software design every little iteration
with &lt;strong>constant refactorings&lt;/strong>. It’s the best choice if you want to ensure the expected behavior of all possible paths of
your logic.&lt;/p>
&lt;p>The beauty of this is that you don’t need to know the full algorithm from the very beginning. Instead, you are
&lt;strong>discovering&lt;/strong> how your logic should be by expressing the desired implementation, step by step, on automated tests.&lt;/p>
&lt;p>Considering writing tests for your software at the same time you’re writing it, will &lt;strong>irremediably force you to write
better software&lt;/strong>. Because you want to write software which has to be easy to be tested, and therefore it will end up with
higher quality.&lt;/p>
&lt;blockquote>
&lt;p>I already wrote another post about the relation between software &lt;strong>quality and testing&lt;/strong>: &lt;a href="/blog/the-art-of-testing/">The Art of Testing: where design meets quality&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;h2 id="improve-your-test-driven-skills">Improve your Test-Driven skills
&lt;a class="heading-anchor" href="#improve-your-test-driven-skills" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>&lt;img src="/images/blog/2021-08-01/tdd-style-with-git.webp" alt="tdd-style" />&lt;/p>
&lt;p>The best way to learn Test-Driven is doing software katas. Try them alone and with others. Both are equally important.&lt;/p>
&lt;ul>
&lt;li>Alone: to challenge your inner self without any distraction but yourself.&lt;/li>
&lt;li>With others: pair-programming is essential in our job. Katas are the best tools to train our communication skills and
learn together from each other.&lt;/li>
&lt;/ul>
&lt;h3 id="what-s-a-code-kata">What’s a Code Kata?
&lt;a class="heading-anchor" href="#what-s-a-code-kata" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Software developers don’t practice enough. Most of our learning takes place on the job, which means that most of our
mistakes get made there as well.&lt;/p>
&lt;p>Other creative professions practice: musicians play technical pieces, poets constantly rewrite works. In karate, most of
a student’s time is spent learning and refining basic moves. These are katas.&lt;/p>
&lt;h3 id="what-is-the-goal-of-a-kata-what-should-we-have-at-the-end">What is the goal of a kata? What should we have at the end?
&lt;a class="heading-anchor" href="#what-is-the-goal-of-a-kata-what-should-we-have-at-the-end" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Katas exist to help developers get the same benefits as practicing in any other profession. There are simple, artificial
exercises that let you experiment and learn without the pressure of a production environment.&lt;/p>
&lt;blockquote>
&lt;p>There are no right or wrong answers in any software kata: the benefit comes from the process, not from the result.&lt;/p>
&lt;/blockquote>
&lt;h3 id="tips">Tips
&lt;a class="heading-anchor" href="#tips" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Once you have resolved a kata, try it again in a few weeks or months.&lt;/li>
&lt;li>Try to explore new solutions. Be creative in the process and do not rush.&lt;/li>
&lt;li>When doing them in groups, they are not a competition to see who will accomplish more of the exercise.&lt;/li>
&lt;li>The focus should be on the process, never on the result.&lt;/li>
&lt;li>The true valuable outcome of any kata is the learnings that you (and your team) will get after talking about it and
sharing your experiences.&lt;/li>
&lt;/ul>
&lt;p>You can find a lot of katas on the Internet. For example:&lt;/p>
&lt;ul>
&lt;li>&lt;a rel="external" href="http://codekata.com">http://codekata.com&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://codingdojo.org/kata">https://codingdojo.org/kata&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://github.com/gamontal/awesome-katas">https://github.com/gamontal/awesome-katas&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr />
&lt;h3 id="tdd-is-more-as-a-workflow-than-a-design">TDD is more as a workflow than a design
&lt;a class="heading-anchor" href="#tdd-is-more-as-a-workflow-than-a-design" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;blockquote>
&lt;p>“TDD is a design tool.” That’s what Sandro has said for years. But not anymore. After working with different teams and in different organisations, and also carefully inspecting how he works, Sandro changed his mind about the role of TDD in software design.&lt;/p>
&lt;/blockquote>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/KyFVA4Spcgg"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;p>TDD in a nutshell; it’s about the rhythm.&lt;/p>
&lt;ol>
&lt;li>Specify what you want.&lt;/li>
&lt;li>Make it work.&lt;/li>
&lt;li>Make it better.&lt;/li>
&lt;/ol>
&lt;hr />
&lt;h2 id="kent-beck">Kent Beck
&lt;a class="heading-anchor" href="#kent-beck" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;blockquote class="twitter-tweet">&lt;p lang="en" dir="ltr">1. Change the code as usual&lt;br>2. Write a test that only passes after the change&lt;br>3. Revert to before 1&lt;br>4. Type the test again (copy/paste is cheating &amp;amp; invalidates the warranty of the exercise)&lt;br>5. Make it compile by changing the code&lt;br>6. See it fail&lt;br>7. Change the code to make it pass&lt;/p>&amp;mdash; [Kent Beck](/readings/extreme-programming-explained/) 🌻 (@KentBeck) &lt;a href="https://twitter.com/KentBeck/status/1421257650113634304?ref_src=twsrc%5Etfw">July 30, 2021&lt;/a>&lt;/blockquote> &lt;script async src="https://platform.twitter.com/widgets.js" charset="utf-8">&lt;/script>
&lt;hr />
&lt;p>Images original by &lt;a rel="external" href="https://x.com/evrtrabajo">Emmanuel Valverde Ramos&lt;/a>.&lt;/p></content></entry><entry xml:lang="en"><title>Never Use array_merge in a Loop</title><subtitle>The spread operator to the rescue</subtitle><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><published>2020-11-10T00:00:00+00:00</published><updated>2020-11-10T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/array-merge-in-loop/"/><id>https://chemaclass.com/blog/array-merge-in-loop/</id><summary type="html">Using array_merge inside a loop is a performance killer. The spread operator will help you to improve this by flatting the array.</summary><content type="html">&lt;p>Using array_merge inside a loop is a performance killer.
The &lt;a href="/blog/typed-arrays-php/">spread operator&lt;/a> will help you to improve this by flatting the array.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="flattening-a-one-level-array">Flattening a one-level array
&lt;a class="heading-anchor" href="#flattening-a-one-level-array" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>I have seen people using the array_merge function in a loop like:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">5&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">foreach&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> as&lt;/span>&lt;span> $&lt;/span>&lt;span>list&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> $&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span>,&lt;/span>&lt;span> $&lt;/span>&lt;span>list&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> $merged === [1, 2, 3, 4, 5, 6];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>This is a very bad practice because it’s a (memory) performance killer!
Instead, you should use the spread operator (in PHP since 5.6!):&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">5&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">...&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> === [1, 2, 3, 4, 5, 6];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h2 id="unpacking-an-assoc-array">Unpacking an assoc-array
&lt;a class="heading-anchor" href="#unpacking-an-assoc-array" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>What if you had an assoc-array instead like this one?&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-1&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-2&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-3&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">5&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>In that case, you will need to unpack its values:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">...&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">array_values&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> === [1, 2, 3, 4, 5, 6];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>In Functional Programming, this is known as flatting a list.
No loops &amp;amp; no more performance problem.&lt;/p>
&lt;h2 id="flatting-a-multilevel-array">Flatting a multilevel array
&lt;a class="heading-anchor" href="#flatting-a-multilevel-array" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>What if you wanted to flat a multilevel array like this one?&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 5&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">6&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 7&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 8&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Or like this one, even with key-values?&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-1&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 1&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-2&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 3&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-3&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">4&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 5&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-4&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">7&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 8&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>In these cases, you might want to use the internal standard library:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> iterator_to_array&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> RecursiveIteratorIterator&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> RecursiveArrayIterator&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> $&lt;/span>&lt;span>use_keys&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> false&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> $merged === [1, 2, 3, 4, 5, 6, 7, 8];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h2 id="which-flattening-approach-to-reach-for">Which flattening approach to reach for
&lt;a class="heading-anchor" href="#which-flattening-approach-to-reach-for" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Usually, being aware of how to flat a “2 level” array might be sufficient:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>flattenList&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">...&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">array_values&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Otherwise, the internal standard library will help you deal with it.&lt;/p>
&lt;hr />
&lt;h3 id="references">References
&lt;a class="heading-anchor" href="#references" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://wiki.php.net/rfc/spread_operator_for_array">Spread_operator_for_array - Wikipedia&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://rosettacode.org/wiki/Flatten_a_list">Flatten_a_list - Rosettacode&lt;/a>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="en"><title>Testing Effectively Legacy Code</title><subtitle>How to write proper tests to already written code</subtitle><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><published>2020-08-17T00:00:00+00:00</published><updated>2020-08-17T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/testing-effectively-legacy-code/"/><id>https://chemaclass.com/blog/testing-effectively-legacy-code/</id><summary type="html">How to write characterization tests for legacy code to safely refactor without breaking existing behavior.</summary><content type="html">&lt;p>These tests are also known as Characterization tests.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;blockquote>
&lt;p>A characterization test describes the actual behavior of an existing piece of software, and therefore protects existing
behavior of legacy code against unintended changes via automated testing. This term was coined by &lt;a href="/readings/working-effectively-with-legacy-code/">Michael Feathers&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;p>They enable and provide a safety net for extending and &lt;a href="/blog/the-art-of-refactoring/">refactoring&lt;/a> code that does not have adequate tests. A test can be
written that asserts that the output of the legacy code matches the observed result for the given inputs.&lt;/p>
&lt;h2 id="how-to-start">How to start?
&lt;a class="heading-anchor" href="#how-to-start" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>These are my learnings one year after
reading &lt;a href="/readings/working-effectively-with-legacy-code/">Working Effectively with Legacy Code&lt;/a> and applying it to the
different projects I’ve been working on since then.&lt;/p>
&lt;h3 id="1-what-do-you-want-to-test">1. What do you want to test?
&lt;a class="heading-anchor" href="#1-what-do-you-want-to-test" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Find out the assertions. Create a test file for your class, and a testing method for the function that you want to test.
Hint:&lt;/p>
&lt;ul>
&lt;li>If you have the following method &lt;code>applySomeLogic(): ReturnType&lt;/code>,&lt;/li>
&lt;li>the test you could write is &lt;code>test_apply_some_logic(): void&lt;/code>.&lt;/li>
&lt;/ul>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogic&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> private&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> DependencyInterface&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> dependencyInterface&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> private&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> concrete&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> __construct&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> DependencyInterface dependencyInterface&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ConcreteDependency concrete&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">dependencyInterface&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> dependencyInterface&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">concrete&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> concrete&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span>Input input&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ReturnType&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> black box responsible to create a ReturnType&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> based on the given Input&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogicTest&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> extends&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> TestCase&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> test_apply_some_logic&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> I want to assert that &amp;quot;applying some logic&amp;quot;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> from MyBusinessLogic with the given Input&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> I will receive a concrete ReturnType with a &lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> certain value as its property. Something like:&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> &lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> assertEquals&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expected&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">getProperty&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="2-instantiate-the-concrete-final-class-that-you-want-to-test">2. Instantiate the concrete/final class that you want to test.
&lt;a class="heading-anchor" href="#2-instantiate-the-concrete-final-class-that-you-want-to-test" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Do not mock your concrete classes. Especially your business domain. Mock only interfaces. Otherwise, you can be hiding
bugs unintentionally (with green/passing tests!). Treat your &lt;a href="/blog/final-classes">business domain classes as final&lt;/a>.&lt;/p>
&lt;p>Either mock the interface or instantiate an anonymous class if you want to create a Stub:&lt;/p>
&lt;blockquote>
&lt;p>Stubs provide answers to calls made during the test, usually not responding to anything outside what’s programmed in for the test.&lt;/p>
&lt;/blockquote>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogicTest&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> extends&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> TestCase&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> test_apply_some_logic&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> MyBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createMock&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">DependencyInterface&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">class&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> OR&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> MyBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> FakeDependency&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ...&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;blockquote>
&lt;p>Where &lt;code>FakeDependency&lt;/code> is a concrete implementation of &lt;code>DependencyInterface&lt;/code> with already “fake data/implementation” that it’s useful only for testing purposes.&lt;/p>
&lt;/blockquote>
&lt;h3 id="3-call-the-method-from-that-class-providing-the-desired-input">3. Call the method from that class providing the desired input.
&lt;a class="heading-anchor" href="#3-call-the-method-from-that-class-providing-the-desired-input" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>The output will be determined by the initial state of the business logic class that we want to test PLUS the input
arguments that we are using.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Input&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="4-assert-the-output-with-the-expected-value">4. Assert the output with the expected value.
&lt;a class="heading-anchor" href="#4-assert-the-output-with-the-expected-value" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>From step-1 you need to know what you want. Apply the assertion(s) now.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogicTest&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> extends&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> TestCase&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> test_apply_some_logic&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> MyBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createMock&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">DependencyInterface&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">::&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">class&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> input&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Input&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> assertEquals&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expected&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">getProperty&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="5-you-might-want-to-assert-different-expected-values">5. You might want to assert different expected values.
&lt;a class="heading-anchor" href="#5-you-might-want-to-assert-different-expected-values" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>You can easily provide different arguments to your business logic either via the logic construction or different given
arguments. To do so, use the @dataProvider annotation. The “dataProvider” method must be public and return any iterable.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogicTest&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> extends&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> TestCase&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> /**&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> @dataProvider providerApplySomeLogic &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> test_apply_some_logic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> array concreteMapping&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> string argInput&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> string expectedValue&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> MyBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createMock&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">DependencyInterface&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">class&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">concreteMapping&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> /*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> input&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Input&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">argInput&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> /*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> actual&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> assertEquals&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>expectedValue&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> actual&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">getProperty&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> providerApplySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Generator&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> yield&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">concreteMapping&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">value&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">argInput&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">something&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expectedValue&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expected-value-A&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> yield&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">concreteMapping&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key2&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">value2&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">argInput&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">something-else&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expectedValue&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expected-value-B&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="lastly-clean-what-you-did">Lastly: clean what you did.
&lt;a class="heading-anchor" href="#lastly-clean-what-you-did" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Yes, clean the tests. They deserve to be as clean as your production code. Otherwise, they will rot as time passes by and
remain dirty for your colleagues and your future self!&lt;/p>
&lt;p>For example, you can apply extract method refactoring to move out the implementation details (of the creation of the
different objects) and keep the same abstraction level while reading the test code.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">concreteMapping&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInput&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">argInput&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">actual&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">assertEquals&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">expectedValue&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> actual&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">getProperty&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Of course, everything depends on the context. Does it really make sense to extract into a private method the
createBusinessLogic() or even createInput()? Well, that’s up to you. It depends on the number of lines and, most
importantly, the abstraction level that belongs to that context.&lt;/p>
&lt;blockquote>
&lt;p>Just remember: keep your methods small.&lt;/p>
&lt;/blockquote>
&lt;p>Now you can refactor the production code that you covered with tests without that fear of breaking it.&lt;/p>
&lt;hr />
&lt;h3 id="all-together">All together
&lt;a class="heading-anchor" href="#all-together" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;script src="https://gist.github.com/Chemaclass&amp;#x2F;07704606fcb337dbb0881c94197c329e.js">&lt;/script>
&lt;script src="https://gist.github.com/Chemaclass&amp;#x2F;9f7f96242153b696b3f8da5c7fa80461.js">&lt;/script>
&lt;hr />
&lt;h2 id="legacy-code-is-code-without-tests">Legacy Code is code without tests
&lt;a class="heading-anchor" href="#legacy-code-is-code-without-tests" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>&lt;img src="/images/blog/2020-08-17/footer.webp" alt="legacy code is code without tests" />&lt;/p>
&lt;p>Of course, there is way more to learn
about &lt;a href="/readings/working-effectively-with-legacy-code/">testing and working with legacy code&lt;/a>. In fact, especially when
dealing with legacy code, you will encounter situations where the code is coupled somehow that you might want to mock
your concrete classes because there is no interface (yet) for it.&lt;/p>
&lt;p>This book presents to you a lot of techniques about when, why, where, and how you can apply these changes.&lt;/p>
&lt;blockquote>
&lt;p>When working with code you need &lt;strong>feedback&lt;/strong>. Automated feedback is the best. Thus, this is the first thing you need to do: write the tests.&lt;/p>
&lt;/blockquote>
&lt;h3 id="first-add-tests-then-do-your-changes">First, add tests, then do your changes.
&lt;a class="heading-anchor" href="#first-add-tests-then-do-your-changes" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;h4 id="change-as-little-code-as-possible-to-get-tests-in-place-with-the-recipe">Change as little code as possible to get tests in place with the recipe:
&lt;a class="heading-anchor" href="#change-as-little-code-as-possible-to-get-tests-in-place-with-the-recipe" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ol>
&lt;li>Identify “change points” to break your code dependencies.&lt;/li>
&lt;li>Break dependencies.&lt;/li>
&lt;li>Write the tests.&lt;/li>
&lt;li>Make your changes.&lt;/li>
&lt;li>Refactor.&lt;/li>
&lt;/ol>
&lt;hr />
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/wRtJRkRIa2s"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div></content></entry><entry xml:lang="en"><title>Advanced Web Application Architecture</title><subtitle>The best guide that brings your coding skills a level up.</subtitle><category term="architecture" scheme="https://chemaclass.com/tags/architecture/" label="Architecture"/><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><published>2020-08-16T00:00:00+00:00</published><updated>2020-08-16T00:00:00+00:00</updated><author><name>
Matthias Noback</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/advance-web-application-architecture/"/><id>https://chemaclass.com/readings/advance-web-application-architecture/</id><summary type="html">Matthias Noback on levelling up your coding and architecture: modern PHP features with a genuinely modular design.</summary><content type="html">&lt;p>This book helps you get your web applications back in shape. It contains many techniques for decoupling from
infrastructure (like the framework or the database).&lt;/p>
&lt;p>“The best guide that brings your coding and architecture skills a level up. All the modern PHP features combined with the elegance of a well-designed modular design.”&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>In Part 1 we unlock a collection of design patterns which help you establish a clean separation between core and
infrastructure code. Part 2 shows how these design patterns resonate at a higher level with architectural concepts like
layers, ports and adapters (a.k.a. &lt;a href="/readings/clean-architecture/">Hexagonal architecture&lt;/a>). The book finishes with a discussion of &lt;a href="/blog/the-art-of-testing/">testing&lt;/a> strategies and design trade-offs.&lt;/p>
&lt;h3 id="what-you-ll-learn">What you’ll learn
&lt;a class="heading-anchor" href="#what-you-ll-learn" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Separating mixed code into core and infrastructure code by &lt;a href="/blog/the-art-of-refactoring/">refactoring&lt;/a> into patterns.&lt;/li>
&lt;li>Dividing your code into layers, and making a clear distinction between an application’s ports and adapters.&lt;/li>
&lt;li>Testing decoupled applications.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Buy the book: &lt;a rel="external" href="https://leanpub.com/web-application-architecture">https://leanpub.com/web-application-architecture&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;hr />
&lt;h3 id="design-patterns-for-modernizing-legacy-code-bases">Design patterns for modernizing legacy code bases
&lt;a class="heading-anchor" href="#design-patterns-for-modernizing-legacy-code-bases" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/WI1QY6OMglE"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div></content></entry><entry xml:lang="en"><title>The Art of Refactoring</title><subtitle>When, how, and why</subtitle><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><published>2020-06-28T00:00:00+00:00</published><updated>2020-06-28T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/the-art-of-refactoring/"/><id>https://chemaclass.com/blog/the-art-of-refactoring/</id><summary type="html">If you see something, in the scope of your current task, that can be easily improved, improve it. And if you have any questions about it, ask.</summary><content type="html">&lt;p>If you see something, in the scope of your current task, that can be easily improved, improve it. And if you have any questions about it, ask.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="what-is-refactoring">What is refactoring?
&lt;a class="heading-anchor" href="#what-is-refactoring" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Refactoring means improving your code. It can go from making a variable name more readable, extract some lines of code into a private method, or separate the responsibilities of a class into subclasses, for example.&lt;/p>
&lt;p>Refactoring is the action of showing that you care about what you do as a professional. It can be a controversial topic; it is indeed one of the major controversial topics since a long time ago. But we shouldn’t stop trying our best in order to improve the quality of the system just because of that controversiality.&lt;/p>
&lt;h2 id="when-and-how-should-we-refactor">When and how should we refactor?
&lt;a class="heading-anchor" href="#when-and-how-should-we-refactor" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Always. In the scope of your current task unless it is an already planned task, something like “architecture refactoring” or similar, where the scope of the task is actually to do refactoring.&lt;/p>
&lt;blockquote>
&lt;p>Refactoring should be part of our daily job, not a separate task by default.&lt;/p>
&lt;/blockquote>
&lt;p>We do not need to ask permission to refactor. Or do we ask our managers for permission to do our best job?&lt;/p>
&lt;p>In order to do proper refactoring, the intention of such refactoring needs to be clear. What is intended to achieve and how? &lt;a href="/blog/effective-pair-programming/">Pair programming&lt;/a> (or even pair thinking!) certainly helps in this topic because it syncs two brains on the same topic and that encourages team building and a better understanding of them.&lt;/p>
&lt;p>Applying refactoring in a collaborative way, in a “bidirectional channel”, is fundamental when working within a team. Refactoring shouldn’t be a taboo topic, on the contrary: it will be helpful in order to unify the goals and the direction of the team code quality.&lt;/p>
&lt;h3 id="some-personal-advice-about-the-how">Some personal advice about the “how”
&lt;a class="heading-anchor" href="#some-personal-advice-about-the-how" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Continuous improvement is what we’re looking for within this topic, but…&lt;/p>
&lt;ul>
&lt;li>If you realize your changes are generating more noise than help, stop immediately and think again if your changes are worth it in the current system status.&lt;/li>
&lt;/ul>
&lt;p>Maybe it’s not the right moment for that refactoring.&lt;/p>
&lt;p>Maybe you are polluting your current diff with out-scoped changes.&lt;/p>
&lt;p>Or, maybe, your refactoring idea is too big to be applied in your current task. In such a case, a follow-up task (in order to apply the refactoring) would be a better idea.&lt;/p>
&lt;ul>
&lt;li>If you see that refactoring is perhaps needed even before starting your current task, do the refactoring first.&lt;/li>
&lt;/ul>
&lt;p>We usually refactor in order to increase our productivity, making the code more readable and therefore easier to understand.&lt;/p>
&lt;h3 id="testing">Testing
&lt;a class="heading-anchor" href="#testing" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Be aware that you should have a pretty good suite of tests covering the logic that you might have changed. Without tests, refactoring can be really risky. Usually, the easier something is to be tested, the easier it is to be replaced or removed.&lt;/p>
&lt;p>You can read more about how &lt;a href="/blog/the-art-of-testing/">testing&lt;/a> is related to quality here.&lt;/p>
&lt;h2 id="why-should-we-do-it">Why should we do it?
&lt;a class="heading-anchor" href="#why-should-we-do-it" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Wouldn’t you want to have a better system as time goes by?&lt;/p>
&lt;p>Software isn’t like wine: it doesn’t get better as time passes by. Therefore, if you want to have a better system you must work for it.&lt;/p>
&lt;p>&lt;img src="/images/blog/2020-06-28/footer.webp" alt="refactoring as continuous improvement" />&lt;/p></content></entry><entry xml:lang="en"><title>Working Effectively with Legacy Code</title><subtitle>Start-to-finish strategies for working with large, untested legacy code bases</subtitle><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><published>2019-07-01T00:00:00+00:00</published><updated>2019-07-01T00:00:00+00:00</updated><author><name>
Michael Feathers</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/working-effectively-with-legacy-code/"/><id>https://chemaclass.com/readings/working-effectively-with-legacy-code/</id><summary type="html">Michael Feathers on adding tests to untested code, breaking dependencies, and refactoring legacy systems safely.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>&lt;h2 id="what-is-legacy-code">What is legacy code?
&lt;a class="heading-anchor" href="#what-is-legacy-code" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;blockquote>
&lt;p>Legacy code is simply code without tests.&lt;/p>
&lt;/blockquote>
&lt;h3 id="benefits-of-tests">Benefits of tests
&lt;a class="heading-anchor" href="#benefits-of-tests" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Behavior is central to understanding the benefits of &lt;a href="/blog/the-art-of-testing/">testing&lt;/a>:&lt;/p>
&lt;blockquote>
&lt;p>Behavior is the most important thing about software. It is what users depend on. Users like it when we add behavior (provided it is what they really wanted), but if we change or remove behavior they depend on (introduce bugs), they stop trusting us.&lt;/p>
&lt;/blockquote>
&lt;h3 id="how-to-get-tests-in-place-in-legacy-codebases">How to get tests in place in legacy codebases
&lt;a class="heading-anchor" href="#how-to-get-tests-in-place-in-legacy-codebases" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>When we change code, we should have tests in place. To put the tests in place, we often have to change code.&lt;/p>
&lt;p>The suggested approach:&lt;/p>
&lt;ol>
&lt;li>Identify change points.&lt;/li>
&lt;li>Find test points.&lt;/li>
&lt;li>Break dependencies.&lt;/li>
&lt;li>Write tests.&lt;/li>
&lt;li>Make changes and refactor.&lt;/li>
&lt;/ol>
&lt;p>Another useful term is a “&lt;strong>seam&lt;/strong>.” A seam, in this context, is “&lt;strong>a place where you can alter behavior in your program
without editing in that place&lt;/strong>”. The analogy is to a seam in clothing, the place where two parts are stitched together.
In software, &lt;strong>these places are generally places where there are well-defined interfaces&lt;/strong>. This can be leveraged to change
the implementation using techniques such as dependency injection or &lt;a href="/blog/to-mock-or-not-to-mock/">mocking&lt;/a> interfaces in the case of writing tests.&lt;/p>
&lt;hr />
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/wRtJRkRIa2s"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div></content></entry><entry xml:lang="en"><title>The Pragmatic Programmer</title><subtitle>The journey to mastery</subtitle><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><category term="career" scheme="https://chemaclass.com/tags/career/" label="Career"/><published>2016-10-01T00:00:00+00:00</published><updated>2016-10-01T00:00:00+00:00</updated><author><name>
Andrew Hunt</name></author><author><name>
David Thomas</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/the-pragmatic-programmer/"/><id>https://chemaclass.com/readings/the-pragmatic-programmer/</id><summary type="html">Key takeaways from Hunt and Thomas: DRY, the pragmatic mindset, and how to choose and master the tools of the trade.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>&lt;h3 id="takeaways">Takeaways
&lt;a class="heading-anchor" href="#takeaways" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Don’t Repeat Yourself.&lt;/li>
&lt;li>&lt;a href="/readings/atomic-habits/">Mindset&lt;/a> is as important as knowledge.&lt;/li>
&lt;li>Good code is easier to change than bad design.&lt;/li>
&lt;li>Choose great tools and become fluent with them.&lt;/li>
&lt;/ul>
&lt;hr />
&lt;h4 id="don-t-repeat-yourself-dry">Don’t Repeat Yourself (DRY)
&lt;a class="heading-anchor" href="#don-t-repeat-yourself-dry" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.&lt;/li>
&lt;li>&lt;a href="/readings/clean-code/">DRY&lt;/a> is about the duplication of knowledge, of intent. It’s about expressing the same thing in two different places,
possibly in two totally different ways.&lt;/li>
&lt;/ul>
&lt;h4 id="mindset-is-as-important-as-knowledge">Mindset is as important as knowledge
&lt;a class="heading-anchor" href="#mindset-is-as-important-as-knowledge" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;p>Some important aspects of this mindset include:&lt;/p>
&lt;ul>
&lt;li>Taking responsibility for your work by not making excuses or passing blame when things go wrong.&lt;/li>
&lt;li>Writing software that’s good enough. This means not wasting time on things that are better than they need to be to
make the product successful.&lt;/li>
&lt;li>Not ignoring technical debt. The authors use the analogy of broken windows:&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Don’t leave “broken windows” (bad designs, wrong decisions, or poor code) unrepaired.
Fix each one as soon as it is discovered. If there is insufficient time to fix it properly, then board it up.
Perhaps you can comment out the offending code, or display a “Not Implemented” message, or substitute dummy data instead.&lt;/p>
&lt;/blockquote></content></entry><entry xml:lang="en"><title>Clean Code</title><subtitle>A Handbook of Agile Software Craftsmanship</subtitle><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><published>2016-05-01T00:00:00+00:00</published><updated>2016-05-01T00:00:00+00:00</updated><author><name>
Robert C. Martin</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/clean-code/"/><id>https://chemaclass.com/readings/clean-code/</id><summary type="html">Bad code works, but it drags a whole organization down. Uncle Bob on what clean code is and how to keep it that way.</summary><content type="html">&lt;p>Even bad code can function. But if code isn’t clean, it can bring a development organization to its knees. Every year,
countless hours and significant resources are lost because of poorly written code. But it doesn’t have to be that way.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;hr />
&lt;h2 id="summary">Summary
&lt;a class="heading-anchor" href="#summary" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="chapter-1-what-is-clean-code">Chapter 1: What Is Clean Code?
&lt;a class="heading-anchor" href="#chapter-1-what-is-clean-code" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>The code can be measured with either “good” or “bad” in the &lt;a href="/blog/pull-request-vs-pair-prog/">code review&lt;/a> or by how many minutes it takes you to talk
about it.&lt;/li>
&lt;li>A clean code should be elegant, efficient, readable, simple, without duplications, and well-written.&lt;/li>
&lt;li>You should add value to the business with your code.&lt;/li>
&lt;li>Clean code offers quality and understanding when we open the source file.&lt;/li>
&lt;li>It is necessary that your code is clean and readable for anyone to find and easily understand. Avoid wasting others’
time.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-2-meaningful-names">Chapter 2: Meaningful Names
&lt;a class="heading-anchor" href="#chapter-2-meaningful-names" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Names of the classes, variables, and methods must be meaningful and clearly indicate what a method does or what an
attribute is.&lt;/li>
&lt;li>Create pronounceable names to facilitate communication.&lt;/li>
&lt;li>Avoid acronyms and avoid confusing names, which may bring anyone who reads the code to the wrong conclusions.&lt;/li>
&lt;li>Use names that reflect the system domain, the context, and the problems that must be solved.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-3-functions">Chapter 3: Functions
&lt;a class="heading-anchor" href="#chapter-3-functions" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Methods should be easy to read and understand.&lt;/li>
&lt;li>Methods should convey its intention.&lt;/li>
&lt;li>Methods should be small.&lt;/li>
&lt;li>They must have up to 20 lines.&lt;/li>
&lt;li>Methods should only do one thing.&lt;/li>
&lt;li>You should use names with words that say what it really does.&lt;/li>
&lt;li>The optimal number of parameters of a method is zero, after one and two.&lt;/li>
&lt;li>Three should be avoided, but if you think it should be used, have a justification.&lt;/li>
&lt;li>&lt;code>Boolean&lt;/code> type as a parameter already states that it does more than one thing.&lt;/li>
&lt;li>Avoid duplication.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-4-comments">Chapter 4: Comments
&lt;a class="heading-anchor" href="#chapter-4-comments" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>One of the common reasons for comments is because the code is bad.&lt;/li>
&lt;li>If you’re thinking about writing a comment, then the code should be refactored.&lt;/li>
&lt;li>Comments do not save a bad code.&lt;/li>
&lt;li>Try to explain what the code causes happening.&lt;/li>
&lt;li>Comments can be useful when placed in certain places.&lt;/li>
&lt;li>Don’t explain your code with comments. Use informative vars/method names.&lt;/li>
&lt;li>Comments can be used to express the importance of certain points.&lt;/li>
&lt;li>Do not write comments with redundant, useless, or false information.&lt;/li>
&lt;li>They shouldn’t be used to indicate who changed or why, use versioning.&lt;/li>
&lt;li>Don’t comment code that will not be used. Remove it instead.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-5-formatting">Chapter 5: Formatting
&lt;a class="heading-anchor" href="#chapter-5-formatting" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Formatting should indicate things of importance since it is a developer of communication form.&lt;/li>
&lt;li>A messy code is hard to read.&lt;/li>
&lt;li>The readability of the code will take effect on all the changes that will be made.&lt;/li>
&lt;li>Smaller classes are easier to understand.&lt;/li>
&lt;li>Set a limit of characters per line of code. For example 120.&lt;/li>
&lt;li>Try to keep more next related concepts vertically to create a code stream.&lt;/li>
&lt;li>Use spaces between operators, parameters, and commas.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-6-objects-and-data-structure">Chapter 6: Objects and Data Structure
&lt;a class="heading-anchor" href="#chapter-6-objects-and-data-structure" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Follow the &lt;a rel="external" href="https://en.wikipedia.org/wiki/Law_of_Demeter">Law of Demeter&lt;/a>:
&lt;ul>
&lt;li>Each unit should have only limited knowledge about other units: only units “closely” related to the current unit.&lt;/li>
&lt;li>Each unit should only talk to its friends; don’t talk to strangers.&lt;/li>
&lt;li>Only talk to your immediate friends.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Do not make dumb objects.&lt;/li>
&lt;li>Objects hide the data abstraction and expose methods that operate the data.&lt;/li>
&lt;li>Data structures expose your data and do not have significant methods.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-7-error-handling">Chapter 7: Error Handling
&lt;a class="heading-anchor" href="#chapter-7-error-handling" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Error handling should be planned carefully by all programmers.&lt;/li>
&lt;li>When wrong things occur, we have to get it to do the right things.&lt;/li>
&lt;li>Give preference to launching an exception than treating it just to hide.&lt;/li>
&lt;li>Create messages with information about the error.&lt;/li>
&lt;li>Mention that it failed. Where was this failure? If possible, mention why it failed.&lt;/li>
&lt;li>Look at separate business rules for errors and error handling.&lt;/li>
&lt;li>Avoid returning a &lt;code>NULL&lt;/code> in methods, preferably to return an empty object.&lt;/li>
&lt;li>Avoid passing &lt;code>NULL&lt;/code> to the methods; this can generate &lt;code>NullPointerExceptions&lt;/code>.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-8-boundary">Chapter 8: Boundary
&lt;a class="heading-anchor" href="#chapter-8-boundary" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>In third-party code, to avoid passing objects, APIs look forward in order to keep things in the same class.&lt;/li>
&lt;li>Perform tests on the API’s third party.&lt;/li>
&lt;li>Study the documentation and test the third API before you start using it.&lt;/li>
&lt;li>Check well the features you will use.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-9-unit-tests">Chapter 9: Unit Tests
&lt;a class="heading-anchor" href="#chapter-9-unit-tests" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Make sure each piece of code is doing what you expect it to do.&lt;/li>
&lt;li>Follow the &lt;a rel="external" href="https://en.wikipedia.org/wiki/Test-driven_development">TDDs law&lt;/a>:
&lt;ul>
&lt;li>Don’t create code before you have a failing test.&lt;/li>
&lt;li>Don’t create more tests than necessary to fail.&lt;/li>
&lt;li>You cannot write more code than enough to pass the test that is failing.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Keep your test clean.&lt;/li>
&lt;li>The tests must undergo changes in the same way that the code.&lt;/li>
&lt;li>The dirtier the code, the more difficult test will be to maintain.&lt;/li>
&lt;li>Use the F.I.R.S.T rule for &lt;a href="/blog/the-art-of-testing/">testing&lt;/a>:
&lt;ul>
&lt;li>The test is fast-running.&lt;/li>
&lt;li>The tests are independent of others.&lt;/li>
&lt;li>The test is repeatable in various environments.&lt;/li>
&lt;li>The test is self-validating.&lt;/li>
&lt;li>The test is timely.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>The test is as important as the production code.&lt;/li>
&lt;/ul>
&lt;h3 id="chapter-10-classes">Chapter 10: Classes
&lt;a class="heading-anchor" href="#chapter-10-classes" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>By default, classes should start with the variables:
&lt;ul>
&lt;li>Static and constants public.&lt;/li>
&lt;li>Static and variable private.&lt;/li>
&lt;li>Instances and variables privates.&lt;/li>
&lt;li>Soon after comes the functions.&lt;/li>
&lt;li>The class name should represent its responsibility.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>The class must have only &lt;a rel="external" href="https://en.wikipedia.org/wiki/Single-responsibility_principle">one responsibility&lt;/a>: one reason to change.&lt;/li>
&lt;li>You should try to make a brief description of the class.&lt;/li>
&lt;li>The methods should be small and one responsibility.&lt;/li>
&lt;/ul>
&lt;hr />
&lt;p>This interview is based on Uncle Bob’s book “Clean Code”. They cover some existing guides that can help you become a
better programmer and explore how books and current trends are shaping the software landscape.&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/QnmRpHFoYLk"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div></content></entry></feed>