<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title>Chemaclass - testing</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/testing/atom.xml"/><link rel="alternate" type="text/html" href="https://chemaclass.com"/><generator uri="https://www.getzola.org/">Zola</generator><updated>2024-10-30T00:00:00+00:00</updated><id>https://chemaclass.com/tags/testing/atom.xml</id><entry xml:lang="en"><title>bashunit</title><subtitle>Turning frustrations into tools for better development</subtitle><category term="bashunit" scheme="https://chemaclass.com/tags/bashunit/" label="Bashunit"/><category term="bash" scheme="https://chemaclass.com/tags/bash/" label="Bash"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="open-source" scheme="https://chemaclass.com/tags/open-source/" label="Open Source"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><published>2024-10-30T00:00:00+00:00</published><updated>2024-10-30T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/bashunit/"/><id>https://chemaclass.com/blog/bashunit/</id><summary type="html">bashunit is a lightweight, easy-to-use testing framework for Bash, packed with handy features like parallel and snapshot testing, test doubles, data providers, and tons of built-in assertions. Backed by clear docs and an active community, it's become a favorite for reliable Bash testing. What started as a simple dev frustration has grown into an open-source tool that makes testing in Bash a lot easier and fun.</summary><content type="html">&lt;p>bashunit is a lightweight, easy-to-use testing framework for Bash. Features like parallel and snapshot testing, test doubles, data providers, and tons of built-in assertions.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>Backed by clear docs and an active community, it’s become a favorite for reliable Bash testing. What started as a simple dev frustration has grown into an open-source tool that makes testing in Bash a lot easier and fun.&lt;/p>
&lt;ol>
&lt;li>The story behind bashunit&lt;/li>
&lt;li>Why create another testing library?&lt;/li>
&lt;li>How is it nowadays?&lt;/li>
&lt;li>Core features&lt;/li>
&lt;li>Lightning tech talk&lt;/li>
&lt;/ol>
&lt;h2 id="the-story-behind-bashunit">The story behind bashunit
&lt;a class="heading-anchor" href="#the-story-behind-bashunit" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>The journey to create bashunit started from a simple frustration: I worked with a team where each commit had to start with the ticket name. Since I like working in small steps with quick, iterative commits, adding the ticket key and number to every single commit became a major hurdle, slowing down my development flow with unnecessary friction.&lt;/p>
&lt;p>After a few days of this, I decided to automate it. Git has a helpful hook, &lt;code>prepare-commit-msg&lt;/code>, which allows you to alter commit messages before they’re finalized. I created a Bash (&lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/blob/main/git-hooks/prepare-commit-msg.sh">script&lt;/a>) that automatically fetches the ticket key and number from the branch name and inserts it into the commit message, making my process smoother and more efficient.&lt;/p>
&lt;p>As someone who values continuous improvement, I began adding more features to this script. However, it became clear that maintaining and testing these changes manually was taking too long and was prone to error. To make development safer and more efficient, I created an &lt;code>assert&lt;/code>(&lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/blob/705489a3487a4607183090d5574827bf6fedabda/git-hooks/prepare-commit-msg_test.sh">link&lt;/a>) function, enabling automated tests that verified the expected behavior based on script output.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/bashunit-original-assert.jpg" alt="bashunit-original-assert.jpg" />&lt;/p>
&lt;p>The &lt;code>assert&lt;/code> function allowed me to define multiple assertions in a separate file, making it easy to validate that any refactoring of the original hook maintained the expected behavior. If a change inadvertently broke existing functionality, it would instantly flag the issue, letting me know right away that something needed fixing. This setup provided immediate feedback and helped ensure that any updates to the script didn’t disrupt its intended logic. For example:&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/conventional-commits-original-tests.jpg" alt="conventional-commits-original-tests.jpg" />&lt;/p>
&lt;p>In the example above, you’ll notice that I execute the actual “&lt;code>SCRIPT&lt;/code>” as the second argument in the assert function, comparing its output to the expected value provided as the first argument. Here, we have two test cases, each exporting &lt;code>TEST_BRANCH&lt;/code> to simulate how the commit message would vary based on the branch name. This setup emulates real behavior, allowing us to test how different branch names affect the commit message formatting. More examples &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/blob/27aeebe4e76afe0a2e91cba85537399eab112eb4/test/prepare-commit-msg_test.sh">here&lt;/a>.&lt;/p>
&lt;p>I decided to separate the &lt;code>assert&lt;/code> function from the test cases, as shown &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/commit/5458e5728296bb94b1e8e6b25eeccde6cc700589">here&lt;/a>, to keep things modular and reusable. Then, I created a &lt;code>runner&lt;/code> to execute each test case independently, reducing test interference and improving reliability. You can see that setup &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/commit/92a5880d7f26b3422de6b91b51c04f9ff7b961fd">here&lt;/a>. This structure made automated testing easier and refactoring safer.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/conventional-commits-call_test_functions.jpg" alt="conventional-commits-call_test_functions.jpg" />&lt;/p>
&lt;p>This was a great improvement because it made it easier to separate &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/blob/4c7dae8d44d425ff06fbb48654388f90c2beb3c4/tests/prepare-commit-msg_test.sh">test cases&lt;/a> from the logic of the test runner itself. This clear structure has simplified both creating and managing tests.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/conventional-commits-refactor-test-cases.webp" alt="conventional-commits-refactor-test-cases.jpg" />&lt;/p>
&lt;p>Now the tests were organized and I got an &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/commit/f459f43cecc271becb1e5eb6ca95d24c97e87830">idea&lt;/a>:&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/bashunit-idea.jpg" alt="bashunit idea note" />&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="markdown">&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);font-weight: bold;">##&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);font-weight: bold;"> Follow-up idea&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>Separate the testing logic into another repo, &lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>so it could be reused anywhere.&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>And so it &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/commit/27269c21c8d0b03bcb3f2000767f4a27b8bf08a1">began&lt;/a>. At the time, I didn’t know much about Bash or the best ways to use a Bash project as a dependency. But I knew I could start by using a Git submodule, even though I’m not a huge fan of them.&lt;/p>
&lt;p>On September 4, 2023, I launched version &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/commit/fc9aac40eb8e5ad4483f08d79eb678a3650dcf78">0.1&lt;/a>, which featured a working runner and a single assertion function: &lt;code>assertEquals&lt;/code>. Later, version &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/releases/tag/0.2.0">0.2&lt;/a> was released, allowing &lt;code>./bashunit&lt;/code> to be a standalone executable, runnable from any folder. Here’s how it looked back then:&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/bashunit-02-demo.jpg" alt="bashunit-02-demo.jpg" />&lt;/p>
&lt;p>I shared the project with a few friends who quickly jumped in to help with documentation, the website, additional assertions, snapshot testing, and key decisions. To emphasize its open-source spirit and community ownership, I moved it to an organization we created specifically for sharing OSS projects, making it a truly collaborative project rather than an individual one.&lt;/p>
&lt;h2 id="why-create-another-testing-library">Why create another testing library?
&lt;a class="heading-anchor" href="#why-create-another-testing-library" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>I know now that other Bash testing libraries exist. But when I started with bashunit, I wasn’t aware of them, and frankly, I’m still no Bash expert. By the time I learned about these alternatives, it was already too late, bashunit had gained enough momentum and excitement to keep going strong.&lt;/p>
&lt;p>While those other libraries may serve specific use cases, use modern Bash, or be developed by more seasoned Bash developers, bashunit aims to set itself apart by offering a great developer experience, shaped by years of working with various testing frameworks.&lt;/p>
&lt;p>I was asked about the differences on September 7, 2023, and here’s my response:
&lt;a rel="external" href="https://github.com/TypedDevs/bashunit/issues/8">Question: Difference to pgrange/bash_unit&lt;/a>.&lt;/p>
&lt;h2 id="how-is-it-nowadays">How is it nowadays?
&lt;a class="heading-anchor" href="#how-is-it-nowadays" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Today, you can &lt;a rel="external" href="https://bashunit.typeddevs.com/installation">install&lt;/a> bashunit via curl, Homebrew, MacPorts, by downloading the latest GitHub &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/releases">release from GitHub&lt;/a>, or even by &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/blob/main/build.sh">building it yourself&lt;/a> from source. Completely open-source.&lt;/p>
&lt;p>The project is written in Bash 3.2 (from 2007) since that’s the default version on macOS, even now, in 2024. This compatibility means bashunit runs smoothly on that version, and I plan to maintain support for it.&lt;/p>
&lt;p>To ensure quality, we test each feature with unit, functional, and acceptance tests, making bashunit its own “first user” of every new feature. We also have several CI workflows using &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/actions/workflows/tests.yml">GitHub actions&lt;/a> that run tests on different platforms to check compatibility and confirm everything works as promised.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/bashunit-ci.jpg" alt="bashunit-ci.jpg" />&lt;/p>
&lt;p>In June 2024, bashunit was &lt;a rel="external" href="https://bashunit.typeddevs.com/blog/2024-06-21-phpstan-integration">integrated in PHPStan&lt;/a> for their end-to-end tests, enabling the use of bashunit’s assertions independently of its runner. This flexibility turned out to be very useful.&lt;/p>
&lt;p>Last summer, I was invited to speak about bashunit at the &lt;a href="/talks/#may">International PHP Conference&lt;/a> in Berlin, alongside &lt;a rel="external" href="https://emmanuelvalverde.dev/">Manu&lt;/a>, another contributor. This project has opened doors and led to a lot of gratitude from users who appreciate the work we’ve put into it.&lt;/p>
&lt;h2 id="core-features">Core features
&lt;a class="heading-anchor" href="#core-features" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>bashunit includes classic lifecycle functions like &lt;code>set_up&lt;/code>, &lt;code>tear_down&lt;/code>, &lt;code>set_up_before_script&lt;/code>, and &lt;code>tear_down_after_script&lt;/code>.&lt;/p>
&lt;p>It also supports a wide range of &lt;a rel="external" href="https://bashunit.typeddevs.com/command-line">command-line parameters&lt;/a>
and &lt;a rel="external" href="https://bashunit.typeddevs.com/configuration">configuration values&lt;/a>. Some of my favorites include:&lt;/p>
&lt;ul>
&lt;li>&lt;code>--parallel&lt;/code>&lt;/li>
&lt;li>&lt;code>--filter&lt;/code>&lt;/li>
&lt;li>&lt;code>--stop-on-failure&lt;/code>&lt;/li>
&lt;li>&lt;code>--verbose&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>We also provide &lt;a rel="external" href="https://bashunit.typeddevs.com/data-providers">data providers&lt;/a> for running the same test cases with different inputs.&lt;/p>
&lt;p>For &lt;a rel="external" href="https://bashunit.typeddevs.com/test-doubles">test doubles&lt;/a>, bashunit offers mocks and spies. These work within the same process as the test, but currently, they don’t work across processes, an area for improvement.&lt;/p>
&lt;p>Powerful &lt;a rel="external" href="https://bashunit.typeddevs.com/snapshots">snapshot testing&lt;/a> is included, making it easy to verify command or script outputs over time.&lt;/p>
&lt;p>bashunit offers a large set of native &lt;a rel="external" href="https://bashunit.typeddevs.com/assertions">assertions&lt;/a> for test cases, including:&lt;/p>
&lt;ul>
&lt;li>&lt;code>assert_same&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_equals&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_contains&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_matches&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_string_starts_with&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_array_contains&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_successful_code&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_general_error&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_file_exists&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_file_contains&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_match_snapshot&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>You can even create your own &lt;a rel="external" href="https://bashunit.typeddevs.com/custom-asserts">custom asserts&lt;/a> to extend bashunit’s capabilities.&lt;/p>
&lt;p>With over &lt;strong>25&lt;/strong> contributors and more than &lt;strong>325&lt;/strong> stars on GitHub within just a year of spare-time development, I’m genuinely proud of what this project has become.&lt;/p>
&lt;h2 id="lightning-tech-talk">Lightning tech talk
&lt;a class="heading-anchor" href="#lightning-tech-talk" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Recently, I presented a lightning tech talk at a hackers’ meetup, demoing bashunit to an audience of over 100 people. It was an incredible experience to share this tool with such an engaged crowd!&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/SX7iNHaSsF0"
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;p>bashunit original logo designed by &lt;a rel="external" href="https://antonio.gg/">Antonio&lt;/a>.&lt;/p></content></entry><entry xml:lang="en"><title>How to Test Private Methods?</title><subtitle>Testing private methods. When and how?</subtitle><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"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><published>2023-10-20T00:00:00+00:00</published><updated>2023-10-20T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/how-to-test-private-methods/"/><id>https://chemaclass.com/blog/how-to-test-private-methods/</id><summary type="html">From time to time I have had to face this question: how to test private methods? I have put together in an article the techniques that I usually use.</summary><content type="html">&lt;p>This is a question that I have encountered with some frequency for a long time. So I thought I would put together my thoughts on the subject here.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="short-answer">Short answer
&lt;a class="heading-anchor" href="#short-answer" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Never.&lt;/p>
&lt;h2 id="long-answer">Long answer
&lt;a class="heading-anchor" href="#long-answer" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Never ever.&lt;/p>
&lt;hr />
&lt;h2 id="what-if">What if…?
&lt;a class="heading-anchor" href="#what-if" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>If you really want to test a private method, consider extracting that private method logic into a separate class, and write a unit test for that class’ behavior.&lt;/p>
&lt;blockquote>
&lt;p>For this one, I was inspired by Fran Iglesias’ &lt;a rel="external" href="https://franiglesias.github.io/test-private-methods/">original post&lt;/a>.&lt;/p>
&lt;/blockquote></content></entry><entry xml:lang="en"><title>Dedicated QA Teams in Software?</title><subtitle>How does it fit a dedicated QA person in your agile team?</subtitle><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="agile" scheme="https://chemaclass.com/tags/agile/" label="Agile"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><published>2023-05-17T00:00:00+00:00</published><updated>2023-05-17T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/dedicated-qa-teams/"/><id>https://chemaclass.com/blog/dedicated-qa-teams/</id><summary type="html">This will be controversial, but let's talk about the QA position. The hidden truth behind the lack of software quality and why this should concern you if you write software.</summary><content type="html">&lt;p>This will be controversial, but let’s talk about the QA position. The hidden truth behind the lack of software quality and why this should concern you if you write software.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="qa-is-a-role-not-a-position">QA is a role, not a position
&lt;a class="heading-anchor" href="#qa-is-a-role-not-a-position" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>As a software developer, when you write software, you are responsible for the quality of whatever you’re writing. A third person acting like QA could find that your solution doesn’t work like expected, but how come? You might argue they might catch edge cases, but how could that be possible if the software was already tested previously?&lt;/p>
&lt;p>A software team’s final goal is to make the QA position useless because they should find nothing but well-working software. But how do you get to that point? How can we ensure that the software we write is working as expected and there is no need for a QA person in our team?&lt;/p>
&lt;h2 id="the-hidden-truth-behind-the-lack-of-software-quality">The hidden truth behind the lack of software quality
&lt;a class="heading-anchor" href="#the-hidden-truth-behind-the-lack-of-software-quality" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Unfortunately, in our software industry, the demand for “fast, quick and dirty” projects ended up in poorly developed MVPs by simply applying patches and code over code with just manual testing checking happy paths, sometimes even ignoring edge cases.&lt;/p>
&lt;blockquote>
&lt;p>“The deadline is in one week, so you better finish it on time!”&lt;/p>
&lt;/blockquote>
&lt;p>We don’t learn the importance of what automated testing can bring to our daily job, so we don’t take it seriously, and therefore, we don’t practice it enough. And, for that exact reason, because we don’t practice it, we don’t know how to perform it properly. Yes, I am talking about writing automated tests that prove the behavior of your software!&lt;/p>
&lt;p>Our inability to write testable code results in software that is hard to test, and thus we delegate testing to other third parties shifting the responsibility for the overall end quality of the product or service we write.&lt;/p>
&lt;h2 id="practice-makes-the-master">Practice makes the master
&lt;a class="heading-anchor" href="#practice-makes-the-master" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>You must learn and apply proper testing techniques when they make sense. How and when effectively use test doubles, prepare solitary or sociable tests, which compromises and reasons backup your mind when choosing one or other paths toward your testing strategies?&lt;/p>
&lt;p>You are the latest and main responsible person in charge of your knowledge, so you better invest in yourself because no one else will do it for you.&lt;/p>
&lt;p>Look at everything you do as an opportunity for learning. Practice and get better by default at everything you do.&lt;/p>
&lt;p>If you don’t know how to start, here is my favourite tip: you can always practice and improve your testing skills using code-katas. Read more about this topic &lt;a href="/blog/test-driven-development/">here&lt;/a>.&lt;/p>
&lt;h2 id="nice-theory-but-why-bother">Nice theory, but… why bother?
&lt;a class="heading-anchor" href="#nice-theory-but-why-bother" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Manual testing is, of course, necessary. It is another testing strategy that I am not blaming or attacking. We might still need a dedicated person in charge of discovering what new features we want to build to satisfy our clients. But this blog-post is not about that position.&lt;/p>
&lt;p>It is all about shortening the feedback loop. If you can write software to work in specific ways, can’t you write automated tests to prove that the software you wrote behaves the way you expect?&lt;/p>
&lt;p>If you have covered with automated tests the behavior of your software at any level that makes sense, what’s left for a dedicated QA person?&lt;/p>
&lt;p>Next time you think about “We need a QA person to test this,” try the exercise of thinking instead, “How can I write an automated test that verifies what I would expect if a QA person were checking this?”&lt;/p>
&lt;p>And that’s how you change the “full-time QA position” into a “role mentality for everyone that writes software.”&lt;/p>
&lt;p>Code never lies and never forgets; once it’s written and automated in your pipeline, you can run it anytime at zero cost.&lt;/p>
&lt;p>&lt;img src="/images/blog/2023-05-17/footer.webp" alt="blog-footer" />&lt;/p></content></entry><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">Robert C. Martin covers the three pillars of software craftsmanship: TDD disciplines with practical examples, professional standards for teams, and the ethical responsibilities of programmers.</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 TDD examples, showing how testing 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>Extreme Programming&lt;/li>
&lt;li>Test-Driven Development&lt;/li>
&lt;li>Refactoring&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>Modern Software Engineering</title><subtitle>Doing What Works to Build Better Software Faster</subtitle><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="architecture" scheme="https://chemaclass.com/tags/architecture/" label="Architecture"/><category term="agile" scheme="https://chemaclass.com/tags/agile/" label="Agile"/><published>2022-06-29T00:00:00+00:00</published><updated>2022-06-29T00:00:00+00:00</updated><author><name>
David Farley</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/readings/modern-software-engineering/"/><id>https://chemaclass.com/readings/modern-software-engineering/</id><summary type="html">This book presents software development as an engineering practice at every level. To master software engineering, we must become experts at learning and managing complexity.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>
&lt;p>This book presents software development as an engineering practice at every level.
To master software engineering, we must become experts at learning and managing complexity.&lt;/p>
&lt;h3 id="optimize-for-learning">Optimize for learning
&lt;a class="heading-anchor" href="#optimize-for-learning" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>To optimize for learning, the book presents five behaviors to consider:&lt;/p>
&lt;ul>
&lt;li>Working iteratively&lt;/li>
&lt;li>Feedback&lt;/li>
&lt;li>Incrementalism&lt;/li>
&lt;li>Empiricism&lt;/li>
&lt;li>Being Experimental&lt;/li>
&lt;/ul>
&lt;p>The main idea is to work on small steps, collect feedback, and adjust.&lt;/p>
&lt;h3 id="optimize-for-managing-complexity">Optimize for managing complexity
&lt;a class="heading-anchor" href="#optimize-for-managing-complexity" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>The book presents other five ideas to manage complexity:&lt;/p>
&lt;ul>
&lt;li>Modularity&lt;/li>
&lt;li>Cohesion&lt;/li>
&lt;li>Separation of Concerns&lt;/li>
&lt;li>Information Hiding and Abstraction&lt;/li>
&lt;li>Managing Coupling&lt;/li>
&lt;/ul>
&lt;p>We need to manage the complexity of our systems.&lt;/p>
&lt;h3 id="tools-to-support-engineering-in-software">Tools to support engineering in software
&lt;a class="heading-anchor" href="#tools-to-support-engineering-in-software" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Going deeper into some ideas that were already discussed in the book, like:&lt;/p>
&lt;ul>
&lt;li>Testability&lt;/li>
&lt;li>Deployability&lt;/li>
&lt;li>Controlling the variables&lt;/li>
&lt;li>Continuous Delivery&lt;/li>
&lt;/ul>
&lt;hr />
&lt;p>A great video explaining the core ideas behind this book by his author:&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/TRqYQnCfgH8"
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>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 refactoring 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>TDD vs BDD</title><subtitle>Design or Workflow?</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"/><published>2021-09-25T00:00:00+00:00</published><updated>2021-09-25T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/tdd-vs-bdd/"/><id>https://chemaclass.com/blog/tdd-vs-bdd/</id><summary type="html">These are two different techniques. The key to each of them is about the mindset and context of what you want to achieve.</summary><content type="html">&lt;p>These are two different techniques. The key to each of them is about the mindset and context of what you want to achieve.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="bdd-is-a-test-driven-feature">BDD is a “test-driven feature”
&lt;a class="heading-anchor" href="#bdd-is-a-test-driven-feature" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Basically, it’s a test-first driven development, where the main focus is ensuring the expected final behavior, and
therefore the result of the software logic that you want to have at the end.&lt;/p>
&lt;p>In BDD the main focus is the behavior of your domain logic that doesn’t exist yet. It is, from an abstract point of
view, about the whole functionality and domain requirements.&lt;/p>
&lt;h2 id="tdd-is-about-the-rhythm">TDD is about the rhythm
&lt;a class="heading-anchor" href="#tdd-is-about-the-rhythm" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&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;p>TDD is not just about the already known “red-green-refactor” mentality, but mostly about the workflow that helps you
understand the constant design decisions you are doing every time for every logic you are designing.&lt;/p>
&lt;blockquote>
&lt;p>TDD is about constant feedback about your decisions.&lt;/p>
&lt;/blockquote>
&lt;p>In the context of OOP (to make the examples clearer), there are always tons of different ways to design your class:&lt;/p>
&lt;ul>
&lt;li>What’s the name of this method’s class?&lt;/li>
&lt;li>What are the dependencies or collaborators for this class?&lt;/li>
&lt;li>How will this class behave when I use this other class inside it?&lt;/li>
&lt;li>What’s the expected outcome of this method when I give these arguments?&lt;/li>
&lt;li>etc, etc…&lt;/li>
&lt;/ul>
&lt;p>We ask these questions (and many more) every time, and we do give them an answer as well, but usually without any
rational thinking or feedback about it. We just do what we think is “the best” at that particular time focusing on
making something work, but is it enough to make it work?&lt;/p>
&lt;h2 id="the-constant-feedback-loop">The constant feedback loop
&lt;a class="heading-anchor" href="#the-constant-feedback-loop" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Testing is not just a great tool because it gives you some safety-net so you can refactor with confidence, but also
because it helps design a better system. &lt;strong>How is that?&lt;/strong> Because before going for any solution, it makes you think about
the decisions that you need to do. You are challenging yourself to understand the arguments of your decisions, and why A
and not B is a better solution in a particular context.&lt;/p>
&lt;p>BDD and TDD aren’t mutually exclusive, in fact, they can and should coexist. It depends mostly on the context of what
you want to build and test.&lt;/p>
&lt;p>&lt;img src="/images/blog/2021-09-25/bdd-and-tdd.webp" alt="blog-bdd-and-tdd" />&lt;/p>
&lt;p>BDD is about Test-First feature development. The goal is not how but what. The feedback loop is long because you will
get “green” feedback once the feature is implemented and working as expected.&lt;/p>
&lt;p>TDD is also another Test-First driven but, unlike BDD, it is about a shorter and quicker feedback loop.&lt;/p>
&lt;ol>
&lt;li>First, you &lt;strong>specify what you want&lt;/strong>. You think about the design of your class or method. Its name or signature. Its
dependencies. But all of this by baby steps, one at a time.&lt;/li>
&lt;li>Second, you &lt;strong>make that little thing work&lt;/strong> in the simplest possible way.&lt;/li>
&lt;li>Finally, you &lt;strong>make it better&lt;/strong>. Because software is hard and complicated enough to make it right on the first try, so
refactoring is a must to keep a system healthy. At this point, with a “green running test”, you can refactor and
improve your logic safely.&lt;/li>
&lt;/ol>
&lt;p>The above is basically TDD, right, but… what’s so special about it? The constant &lt;strong>feedback loop&lt;/strong> and &lt;strong>design
decisions&lt;/strong> that you need to make before you are actually writing the solution. This is the power of TDD.&lt;/p>
&lt;h3 id="why-so-small-steps-in-tdd">Why so small steps in TDD?
&lt;a class="heading-anchor" href="#why-so-small-steps-in-tdd" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Theoretically you “must” write little steps for every iteration, but why? &lt;strong>It’s all about the feedback loop&lt;/strong>. This is
up to you, your expectations, and your experience with testing.&lt;/p>
&lt;p>&lt;img src="/images/blog/2021-09-25/footer.jpg" alt="small steps in the tdd feedback loop" />&lt;/p>
&lt;hr />
&lt;h3 id="resources">Resources
&lt;a class="heading-anchor" href="#resources" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://chemaclass.com/blog/test-driven-development/">https://chemaclass.com/blog/test-driven-development/&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://blog.testlodge.com/tdd-vs-bdd/">https://blog.testlodge.com/tdd-vs-bdd/&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 habits 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.png" 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.png" 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.png" 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 🌻 (@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>To Mock or Not to Mock</title><subtitle>How to escape the mocking hell</subtitle><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"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><published>2021-01-11T00:00:00+00:00</published><updated>2021-01-11T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/to-mock-or-not-to-mock/"/><id>https://chemaclass.com/blog/to-mock-or-not-to-mock/</id><summary type="html">Mocking is useful, but 'what to mock' usually turns out to be a more complicated than expected if you don't treat this carefully.</summary><content type="html">&lt;p>Mocking is useful, but “what to mock” usually turns out to be more complicated than expected if you don’t treat
this carefully.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h4 id="how-to-escape-the-mocking-hell">How to escape the mocking hell
&lt;a class="heading-anchor" href="#how-to-escape-the-mocking-hell" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;p>What is actually happening when we create a mock? Which types of mocks are there? Is mocking good or bad? Well, as
always, everything depends on the context. And here we will consider some of the main situations about when to mock and
when not to mock, but especially why.&lt;/p>
&lt;h2 id="what-happens-when-you-mock-something">What happens when you mock something?
&lt;a class="heading-anchor" href="#what-happens-when-you-mock-something" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>First, we should define what is a mock:&lt;/p>
&lt;blockquote>
&lt;p>In a unit test, mock objects can simulate the behavior of complex, real objects and are therefore useful when it is impractical or impossible to incorporate a real object into a unit test.&lt;/p>
&lt;/blockquote>
&lt;p>Mocking makes sense in a &lt;em>unit testing&lt;/em> context. An integration test should go through the real implementation checking
the integration between multiple units, which are even allowed to talk to the DB or File IO: infrastructure code.
Therefore we should agree that &lt;em>a unit test is a fast and deterministic test that doesn’t rely on external dependencies
and doesn’t require any special context to run&lt;/em>.&lt;/p>
&lt;p>Mock objects meet the &lt;em>interface&lt;/em> requirements. In consequence, they allow us to write and unit-test functionality
without calling complex underlying or collaborating classes.&lt;/p>
&lt;p>A mock is a test double that stands in for real implementation code during the unit testing process. It is also capable
of producing assertions about how it was manipulated by the test subject during the test run.&lt;/p>
&lt;blockquote>
&lt;p>I strongly recommend you to read this post if you want to get into the details of why &lt;a rel="external" href="https://medium.com/javascript-scene/mocking-is-a-code-smell-944a70c90a6a">Mocking is a code smell&lt;/a> (Topics like these: What is a mock? What is a unit test? What is test coverage? What is tight coupling? What causes tight coupling? What does composition have to do with mocking? How do we remove coupling? and more!)&lt;/p>
&lt;/blockquote>
&lt;h2 id="the-problem-with-mocking">The problem with mocking
&lt;a class="heading-anchor" href="#the-problem-with-mocking" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>When you mock you are overriding the logic of the mocked class. The real logic is getting hidden behind the scenes and
there is actually where bugs love to live. Consider that:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>The mock may have attributes, methods, or arguments that the real object doesn’t.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The mock’s &lt;em>return values may differ from the real objects’ return values&lt;/em>. For example, it may return a different
type of object that has different attributes.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The mock’s &lt;em>side effects and behavior may differ from the real objects’ ones&lt;/em>. For example, maybe the mock fails to
raise an exception when the real object would raise it.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="alternatives-to-mocking">Alternatives to mocking
&lt;a class="heading-anchor" href="#alternatives-to-mocking" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>“Are you saying that mocking is bad and we shouldn’t mock?!” No.&lt;/p>
&lt;p>It depends on what you are “overriding”.&lt;/p>
&lt;ul>
&lt;li>Is your business domain logic what you are mocking? Then it’s wrong.&lt;/li>
&lt;li>Is the connection to the DB what you are mocking? Then it’s right.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>It depends on the context of the logic and where that logic belongs.&lt;/p>
&lt;/blockquote>
&lt;p>Is it part of your business domain logic? Then you shouldn’t mock it but instantiate it.&lt;/p>
&lt;p>Is it part of any infrastructure dependency like DB connection, IO file system, Network, or any external service that
has nothing to do directly with your business domain? Then &lt;em>mock it using abstractions/interfaces&lt;/em>.&lt;/p>
&lt;p>The interface should be the &lt;em>contract between your business domain logic and its external infrastructure dependencies&lt;/em>.
Imagine how easy it would be to unit test your domain logic by instantiating it and calling their methods with different
arguments expecting different inputs under your entire control.&lt;/p>
&lt;h2 id="some-tricks">Some tricks
&lt;a class="heading-anchor" href="#some-tricks" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>When you are writing a unit test:&lt;/p>
&lt;ul>
&lt;li>Try to instantiate your classes first.&lt;/li>
&lt;li>Avoid mocking concrete classes. I wrote an article exclusively about this:
encouraging &lt;a rel="external" href="https://medium.com/swlh/final-classes-in-php-9174e3e2747e">final classes&lt;/a> and interfaces.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Mock interfaces. Instantiate concrete classes.&lt;/p>
&lt;/blockquote>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/RbSqXFUfRMU"
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>“Excessive use of mocks leads to legacy code.” - Philippe Boargau&lt;/p>
&lt;h3 id="how-can-we-avoid-excessive-mocking">How can we avoid excessive mocking?
&lt;a class="heading-anchor" href="#how-can-we-avoid-excessive-mocking" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Favor immutable state over a mutable state.&lt;/li>
&lt;li>Make dependencies explicit.&lt;/li>
&lt;li>Program to an interface, not to an implementation.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="/images/blog/2021-01-11/footer.webp" alt="mock interfaces, instantiate concrete classes" />&lt;/p>
&lt;hr />
&lt;h4 id="references">References
&lt;a class="heading-anchor" href="#references" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://medium.com/javascript-scene/mocking-is-a-code-smell-944a70c90a6a">Mocking is a code smell&lt;/a> - Eric Elliott&lt;/li>
&lt;li>&lt;a rel="external" href="https://blog.cleancoder.com/uncle-bob/2014/05/10/WhenToMock.html">When to mock&lt;/a> &amp;amp; &lt;a rel="external" href="https://blog.cleancoder.com/uncle-bob/2017/05/05/TestDefinitions.html">Test Definitions&lt;/a> - Uncle Bob&lt;/li>
&lt;li>&lt;a rel="external" href="https://matthiasnoback.nl/2018/09/final-classes-by-default-why/">Final classes by default&lt;/a> - Matthias Noback&lt;/li>
&lt;li>&lt;a rel="external" href="https://www.seanh.cc/2017/03/17/the-problem-with-mocks/">The problem with mocks&lt;/a> - Sean Hammond&lt;/li>
&lt;li>&lt;a rel="external" href="https://www.artima.com/weblogs/viewpost.jsp?thread=126923">A Set of Unit Testing Rules&lt;/a> - Michael Feathers&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 refactoring 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.jpg" 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>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? Pair programming (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 testing 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>Final Classes in PHP | Java | Any</title><subtitle>Final, or not final, that's the question</subtitle><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="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><published>2020-06-06T00:00:00+00:00</published><updated>2020-06-06T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/final-classes/"/><id>https://chemaclass.com/blog/final-classes/</id><summary type="html">Clear contracts, isolated side effects, testability, low complexity and cognitive load, code fluidity, and confidence in yourself.</summary><content type="html">&lt;p>Clear contracts, isolated side effects, testability, low complexity and cognitive load, code fluidity, and confidence in yourself.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="motivation">Motivation
&lt;a class="heading-anchor" href="#motivation" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="reduce-the-scope-visibility-to-the-minimum">Reduce the scope visibility to the minimum
&lt;a class="heading-anchor" href="#reduce-the-scope-visibility-to-the-minimum" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>When you see a class prefixed with final you will prevent a particular class to be extended by any other, which not only makes it more readable but also makes you be sure that the scope of the logic where you are is limited to that particular class.&lt;/p>
&lt;h3 id="encourage-composition-over-inheritance-mentality">Encourage “composition over inheritance” mentality
&lt;a class="heading-anchor" href="#encourage-composition-over-inheritance-mentality" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>The Open-Close Principle states: open for extension but closed for modification.&lt;/p>
&lt;p>If for any reason, a good one you should be completely aware of, you decide to create an inheritance there, well, then just drop the final keyword and you are good to go.&lt;/p>
&lt;p>When you “by default” can’t extend from a class (because it’s final), you will help yourself by thinking about using composition instead of inheritance.&lt;/p>
&lt;h2 id="why-isn-t-this-class-final">Why isn’t this class final?
&lt;a class="heading-anchor" href="#why-isn-t-this-class-final" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>If we aim for composition over inheritance, then we should try to avoid inheritance as much as possible, and use it only when it’s really necessary. Inheritance is often misused in OOP.&lt;/p>
&lt;h3 id="misconception">Misconception
&lt;a class="heading-anchor" href="#misconception" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>When we first taught OOP, we usually introduced the classic inheritance example.&lt;/p>
&lt;p>Nonetheless, when Alan Kay created Smalltalk, the inheritance was never the main concept of it. The main concept was messaging, which is that you can send messages to objects and they encapsulate the data and logic in it, and you can change their behavior by using different objects, which is actually composition. But the concept of inheritance is so popular that it eventually overshadows composition.&lt;/p>
&lt;h3 id="benefits">Benefits
&lt;a class="heading-anchor" href="#benefits" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Clear contracts. Using interfaces will force you to think in terms of communication between objects.&lt;/li>
&lt;li>Isolated, side effect free code units. Injecting interfaces only as dependencies will remove every nasty side effect around the code you are working on.&lt;/li>
&lt;li>Testability. Mocking dependencies is extremely easy when they are interfaces.&lt;/li>
&lt;li>Low, manageable complexity. Since everything is isolated, you won’t need to worry about rippling changes. This dramatically decreases the complexity of your code.&lt;/li>
&lt;li>Low cognitive load. With decreased complexity, your brain will be free to focus on what matters.&lt;/li>
&lt;li>Code fluidity. By removing any unnecessary coupling, you will be able to move things around way more easily than before.&lt;/li>
&lt;li>Confidence in yourself. Being able to test your code in isolation so well will give you a wonderful sense of confidence in changing it.&lt;/li>
&lt;/ul>
&lt;h2 id="composition-over-inheritance">Composition over inheritance
&lt;a class="heading-anchor" href="#composition-over-inheritance" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>If you feel the need to reconfigure an object, to change parts of an algorithm, or to rewrite part of the implementation, consider creating a new class instead of overriding an existing class.
If you need to represent a hierarchy of classes, where subclasses are proper substitutes for their parent classes. This would be the classic situation where you may still consider inheritance. However, the result may even be better if you don’t inherit from concrete parent classes but from abstract interfaces.&lt;/p>
&lt;h3 id="what-you-should-start-doing-instead">What you should start doing instead
&lt;a class="heading-anchor" href="#what-you-should-start-doing-instead" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Use interfaces to define the contracts between your classes.&lt;/li>
&lt;li>Use final classes to implement behavior for those interfaces.&lt;/li>
&lt;li>Use composition (using dependency injection through constructor) to put things together and prevent complexity.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Interfaces -&amp;gt; Final classes -&amp;gt; Composition&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="/images/blog/2020-06-06/footer.webp" alt="interfaces, final classes and composition" />&lt;/p></content></entry><entry xml:lang="en"><title>The Art of Testing: Where Design Meets Quality</title><subtitle>From a software developer's point of view</subtitle><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="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-04-07T00:00:00+00:00</published><updated>2020-04-07T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/the-art-of-testing/"/><id>https://chemaclass.com/blog/the-art-of-testing/</id><summary type="html">Why you should consider testing as part of your daily development habit and how it's directly linked to the software quality.</summary><content type="html">&lt;p>Why you should consider testing as part of your daily development habit and how it’s directly linked to the software
quality.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>This post intends not to explain the different testing techniques that we can use. I’m not going to tell you the differences between unit, integration, feature, or end-to-end testing.&lt;/p>
&lt;p>I’m still amazed by the lack of experience with testing in software in general. Common ignorance in this world about
best testing practices for us as developers. Inexperience that you can easily see if you have already worked on
different projects and teams.&lt;/p>
&lt;h3 id="software-testing">Software testing
&lt;a class="heading-anchor" href="#software-testing" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Some horrible patterns I’ve seen (and done):&lt;/p>
&lt;ul>
&lt;li>Testing for the sake of testing: testing every single file, sometimes wrongly considered a unit.&lt;/li>
&lt;li>Mocking every class we intend to test, overriding the actual implementation, and creating a fake behavior,
providing a false coverage perception.&lt;/li>
&lt;li>Coupling production code with tests everywhere, so it’s impossible to change anything without breaking some tests,
even if the feature itself it’s working as intended.&lt;/li>
&lt;li>Not testing at all because “why should we even test anything if the feature is done, and it works? Why should we
spend more time on this if it’s done?.”&lt;/li>
&lt;/ul>
&lt;p>One of the main reasons for software testing is actually verifying a suite of proofs for the expected behavior of the
final software piece. However, testing can (and should) be more than that.&lt;/p>
&lt;h3 id="software-design">Software design
&lt;a class="heading-anchor" href="#software-design" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Software design goes from algorithm to architecture design. Even when I believe these two levels of components have
different needs and requirements, they still share some common patterns. For example, testing, and this is what we are
going to talk about right now:&lt;/p>
&lt;blockquote>
&lt;p>If it’s easy to test, it will likely be because of good design.&lt;/p>
&lt;/blockquote>
&lt;h3 id="software-quality">Software quality
&lt;a class="heading-anchor" href="#software-quality" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Is quality hard to measure out? Indeed. There are different measurement keys that we should take while considering
quality for any piece of software. Still, I’m sure we could agree on this:&lt;/p>
&lt;blockquote>
&lt;p>If you aim for quality in your software, you better seek a good design.&lt;/p>
&lt;/blockquote>
&lt;p>Testing by itself means “proving,” as we all know. That said… how difficult it sometimes turns to prove some logic
that we finally give up because of its complexity itself?&lt;/p>
&lt;p>The art of testing is about using testing itself to help and contribute to the final result. To encourage good design,
suppose we’re able to use testing (of any kind) in our favor, depending on the context of what we want to prove. In that
case, it will undoubtedly help us increase the product’s end quality.&lt;/p>
&lt;p>Therefore, testing should be used not only to prove the behavior of our software but also to guide our software to a better design.&lt;/p>
&lt;p>Should we test everything? Well, that’s the million-dollar question. In my opinion, everything depends on the context. We
might encounter situations where tests might not be beneficial. Even in those situations, we should write our code as if
it could be tested anyway.&lt;/p>
&lt;p>&lt;img src="/images/blog/2020-04-07/footer.webp" alt="testable code and good design" />&lt;/p>
&lt;blockquote>
&lt;p>Testable code tends to better design and, therefore, better quality.&lt;/p>
&lt;/blockquote></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 presents practical techniques for adding tests to untested code, breaking dependencies, and safely refactoring large legacy systems without introducing bugs.</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 testing:&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 mocking 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>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">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.</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 code review 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 testing:
&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>