<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nicolas Villavicencio</title>
    <description>The latest articles on DEV Community by Nicolas Villavicencio (@nicolasvillavicencio).</description>
    <link>https://dev.to/nicolasvillavicencio</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1138564%2Fddfa0c79-cf1c-470f-a410-c75b6da77c36.jpg</url>
      <title>DEV Community: Nicolas Villavicencio</title>
      <link>https://dev.to/nicolasvillavicencio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nicolasvillavicencio"/>
    <language>en</language>
    <item>
      <title>The Reliable Power of the FIRST Principle: A Comprehensive Guide</title>
      <dc:creator>Nicolas Villavicencio</dc:creator>
      <pubDate>Mon, 31 Jul 2023 13:02:15 +0000</pubDate>
      <link>https://dev.to/nicolasvillavicencio/the-reliable-power-of-the-first-principle-a-comprehensive-guide-4c6o</link>
      <guid>https://dev.to/nicolasvillavicencio/the-reliable-power-of-the-first-principle-a-comprehensive-guide-4c6o</guid>
      <description>&lt;p&gt;Writing unit tests correctly is as important as coding features. To achieve this, certain principles help ensure that unit tests are easy to use and modify when adding new test cases. The FIRST principle, which stands for Fast, Independent, Repeatable, Self-validating, and Timely, is a guide for us in this endeavor&lt;/p&gt;

&lt;h2&gt;
  
  
  (F)ast
&lt;/h2&gt;

&lt;p&gt;Unit tests should execute quickly to verify that the system behaves as expected during fixes, refactoring, or when new features are added. If running tests for a project takes a substantial amount of time, developers will tend to use them less frequently. Waiting 30 minutes to check if adding a few lines of code breaks something is not ideal.&lt;/p&gt;

&lt;p&gt;Therefore, it’s crucial to focus on creating fast-running tests. This can be achieved by configuring tests to run in parallel or ensuring that the context setup process is not overly time-consuming.&lt;/p&gt;

&lt;h2&gt;
  
  
  (I)ndependent
&lt;/h2&gt;

&lt;p&gt;Independence among tests is crucial because modifying one test should not break others. If a test’s modification causes failures, it becomes less reliable and harder to maintain. To ensure independence, it is essential to verify that tests are executed randomly, which is generally the case. Additionally, leveraging mock tools to isolate the code under test provides the determinism needed for thorough testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  (R)epeatable
&lt;/h2&gt;

&lt;p&gt;A unit test is repeatable if executing it multiple times produces the same result consistently. Using mock tools should make the untested code behave consistently, regardless of when or in what order it is executed. A typical example of failure to achieve repeatability is observing a project that relies on system objects to represent dates, causing test failures on January 1st each year.&lt;/p&gt;

&lt;h2&gt;
  
  
  (S)elf-validating
&lt;/h2&gt;

&lt;p&gt;A self-validating test is one that doesn’t rely on manual checks to determine success or failure, reducing the risk of human errors. Additionally, a self-validating test prepares its own context before execution, avoiding the need for manual tasks that could impact the test results.&lt;/p&gt;

&lt;h2&gt;
  
  
  (T)imely or Thorough
&lt;/h2&gt;

&lt;p&gt;“Timely” means writing tests for code in the same timeframe as the code itself. Tests help quickly identify issues and ensure that everything functions correctly, allowing dynamic changes and improvements throughout the feature development process.&lt;/p&gt;

&lt;p&gt;On the other hand, “Thorough” reminds us not only to test the happy path but also to cover potential error scenarios when executing the code. For example, if a function takes a parameter, we should test not only valid values but also null values (if the language allows) and other boundary cases.&lt;/p&gt;

&lt;p&gt;Both “Timely” and “Thorough” principles are not mutually exclusive; they should be applied together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Apart from the first principles there are other aspects to remember include.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simplicity: Simple code is easier to read and modify. &lt;/li&gt;
&lt;li&gt;The “Single Responsibility” principle of &lt;a href="https://samurai-developer.com/follow-principles-solid/"&gt;S.O.L.I.D&lt;/a&gt; also applies to tests. When designing tests, consider that each test should focus on verifying one specific thing, making it easier to identify what is functioning correctly or not in the source code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lastly, regarding unit test coverage, while it is often necessary for development processes to reach a certain percentage of test coverage before deploying a feature, developers must understand that coverage does not guarantee the correct functioning of the entire system. It merely indicates that tests have executed in specific parts of the code. Tests may not necessarily aim to validate those specific functionalities. Consequently, test coverage should be accompanied by a comprehensive understanding and complemented by other quality metrics for tests.&lt;/p&gt;

&lt;p&gt;For more information, see &lt;a href="https://en.wikipedia.org/wiki/Mutation_testing"&gt;Mutation Testing&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9tlBaSNm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/samurai-developer.com/wp-content/uploads/2023/05/cropped-katana-1.png%3Ffit%3D32%252C32%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9tlBaSNm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/samurai-developer.com/wp-content/uploads/2023/05/cropped-katana-1.png%3Ffit%3D32%252C32%26ssl%3D1" alt="Samurai Developer Icon" width="32" height="32"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://samurai-developer.com/unit-tests-first-principle/"&gt;The Reliable Power of the FIRST Principle: A Comprehensive Guide&lt;/a&gt; first appeared on &lt;a href="https://samurai-developer.com"&gt;Samurai Developer&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>cleancode</category>
      <category>testing</category>
      <category>unittest</category>
    </item>
    <item>
      <title>Testing Pyramid a Simple Way to Ensure Code Quality</title>
      <dc:creator>Nicolas Villavicencio</dc:creator>
      <pubDate>Sun, 16 Jul 2023 22:43:51 +0000</pubDate>
      <link>https://dev.to/nicolasvillavicencio/testing-pyramid-a-simple-way-to-ensure-code-quality-3fei</link>
      <guid>https://dev.to/nicolasvillavicencio/testing-pyramid-a-simple-way-to-ensure-code-quality-3fei</guid>
      <description>&lt;p&gt;Mike Cohn introduced the concept of Testing Pyramid in his book “Succeeding with Agile.” It is a visual metaphor used to categorize tests into different layers, each with specific characteristics.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i0.wp.com/samurai-developer.com/wp-content/uploads/2023/07/piramid-test-1.jpg?ssl=1"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8oEKz51S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/samurai-developer.com/wp-content/uploads/2023/07/piramid-test-1.jpg%3Fresize%3D1024%252C576%26ssl%3D1" alt="Testing Pyramid by levels" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 1 : Unit Tests
&lt;/h2&gt;

&lt;p&gt;Located at the base of the Testing Pyramid. The fundamental characteristic of &lt;a href="https://samurai-developer.com/unit-tests-first-principle/"&gt;unit tests&lt;/a&gt; is that they focus on verifying that each unit of code functions correctly in isolation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What is a unit&lt;/strong&gt; : A unit is considered the smallest unit of functionality. For example, in the case of a shopping cart, it can calculate taxes, apply discounts, and calculate the total amount to be paid.&lt;/p&gt;

&lt;p&gt;Vladimir Khorikov summarizes it well in &lt;a href="https://a.co/d/6Fh6tyi"&gt;his book&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;“A test should tell a story about the problem your code helps to solve, and this story should be cohesive and meaningful to a non-programmer.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The main objective of unit tests is to verify that each unit of code functions correctly in isolation.&lt;/p&gt;

&lt;p&gt;To achieve this, we need to test all possible inputs of the unit, considering boundary cases and potential errors.&lt;/p&gt;

&lt;p&gt;These tests are called &lt;strong&gt;open-box tests&lt;/strong&gt; because we are familiar with the tested algorithm, allowing us to choose inputs that push the unit to boundary conditions and error cases.&lt;/p&gt;

&lt;p&gt;Unit tests focus on identifying and correcting component-level errors before they are integrated into the complete system.&lt;/p&gt;

&lt;p&gt;As a characteristic within the Testing Pyramid, unit tests are the tests that we develop the most in a project. They should be fast to execute as they accompany us throughout the development of new features and &lt;a href="https://samurai-developer.com/refactor-hats-and-workflows/"&gt;refactors&lt;/a&gt; to ensure that the system continues to function as expected at the unit level.&lt;/p&gt;

&lt;p&gt;If we have a set of unit tests that take too long to complete, programmers will tend to run them less frequently, making it more challenging to catch bugs. Moreover, it can lead to their decreasing usage as it adds more time to the development cycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 2 : Integration Tests
&lt;/h2&gt;

&lt;p&gt;Integration tests aim to verify the correct functioning between our systems and third-party systems.&lt;/p&gt;

&lt;p&gt;To identify when we need integration tests, we can use the rule that &lt;em&gt;whenever we need to serialize and deserialize data, we will need to perform some integration tests&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This happens in some of the following cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calls made to our REST API services.&lt;/li&gt;
&lt;li&gt;Readings and writings to databases.&lt;/li&gt;
&lt;li&gt;Calls to APIs of other applications.&lt;/li&gt;
&lt;li&gt;Reading or writing to message queues.&lt;/li&gt;
&lt;li&gt;Reading or writing to a file system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can divide integration tests into two categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Broad: It aims to bring up all external services interacted with, requiring significant configuration and maintenance of the testing environment.&lt;/li&gt;
&lt;li&gt;Narrow: It focuses on interacting with a particular external service, while the other dependencies are mocked.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When we refer to Broad Integration Tests, we are talking about a type of &lt;strong&gt;closed-box testing&lt;/strong&gt; where we don’t know how the algorithm is implemented, and we focus more on testing to verify that we get the expected response for certain inputs.&lt;/p&gt;

&lt;p&gt;Narrow integration tests focus on testing different interactions between our service and a single third-party service, using mocks based on a predefined and well-documented definition.&lt;/p&gt;

&lt;p&gt;These tests assume that the communication contract between modules is correct and aim to find faults in our system with one of the predefined responses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 3 : End-to-End Testing
&lt;/h2&gt;

&lt;p&gt;End-to-End (E2E) tests are aimed at verifying the functioning and performance of a flow in the application from start to finish, simulating real-use scenarios.&lt;/p&gt;

&lt;p&gt;In other words, they check scenarios that users will encounter when using the application as if it were in production.&lt;/p&gt;

&lt;p&gt;The objective of End-to-End tests is to ensure that the performance is within an acceptable range. They serve to verify that the application continues to function as expected, and our changes have not broken any critical flows in the application.&lt;/p&gt;

&lt;p&gt;On the other hand, this type of test is one of the most challenging to develop, as it requires a significant amount of effort and development time due to involving multiple applications at once.&lt;/p&gt;

&lt;p&gt;That is why these types of tests are reserved for essential flows in our application that must not fail or degrade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Although the concept of the Testing Pyramid has been around for many years, it remains relevant today as it helps us define the types of tests we perform, their objectives, and their characteristics, regardless of the language or programming paradigm used.&lt;/p&gt;

&lt;p&gt;It is essential to have a good understanding of these concepts and ensure that everyone in the development team shares the same understanding when discussing each type of test will we need.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9tlBaSNm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/samurai-developer.com/wp-content/uploads/2023/05/cropped-katana-1.png%3Ffit%3D32%252C32%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9tlBaSNm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/samurai-developer.com/wp-content/uploads/2023/05/cropped-katana-1.png%3Ffit%3D32%252C32%26ssl%3D1" alt="Samurai Developer Icon" width="32" height="32"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://samurai-developer.com/testing-pyramid/"&gt;Testing Pyramid a Simple Way to Ensure Code Quality&lt;/a&gt; first appeared on &lt;a href="https://samurai-developer.com"&gt;Samurai Developer&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>e2e</category>
      <category>integrationtest</category>
      <category>testing</category>
    </item>
    <item>
      <title>From Chaos to Order: Refactoring Fundamentals for Better Results</title>
      <dc:creator>Nicolas Villavicencio</dc:creator>
      <pubDate>Sun, 11 Jun 2023 03:07:49 +0000</pubDate>
      <link>https://dev.to/nicolasvillavicencio/from-chaos-to-order-refactoring-fundamentals-for-better-results-35ca</link>
      <guid>https://dev.to/nicolasvillavicencio/from-chaos-to-order-refactoring-fundamentals-for-better-results-35ca</guid>
      <description>&lt;p&gt;One of the skills a samurai developer must develop is knowing how to apply refactoring in their day-to-day work. When starting the software development journey, one tends to follow the axiom “If it works, don’t touch it, or it might break.” This fear naturally arises from inexperience and the context in which one works. However, I believe that as professionals, we must pursue the ideal of continuous improvement, and to achieve that, we must overcome that fear. It’s good to have a protocol on how and when to act to produce better code.&lt;/p&gt;

&lt;p&gt;This is what Richard Fowler talks about in his refactoring talks. I will now summarize the compilation of ideas he promotes, hoping it serves as a guide for you as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Red and Green Circle
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TqLualBV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/samurai-developer.com/wp-content/uploads/2023/06/Diagrama-sin-titulo-2037723162-e1686277620318.jpg%3Fresize%3D623%252C445%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TqLualBV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/samurai-developer.com/wp-content/uploads/2023/06/Diagrama-sin-titulo-2037723162-e1686277620318.jpg%3Fresize%3D623%252C445%26ssl%3D1" alt="refactoring hats" width="623" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The common practice in TDD is to write the test first and then the functionality, which abstracts us from the implementation. Then one proceeds to develop the functionality and make the test go from failure (red) to success (green).&lt;/p&gt;

&lt;p&gt;It is common that as we progress in the development process, we encounter code that is ugly. This may be because it is old or because it was not coded clearly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Two Hats Come into Play
&lt;/h2&gt;

&lt;p&gt;Richard Fowler talks about two work styles when sitting down to develop: the construction hat, which one wears when adding new functionality to the system, and the improvement hat, which is used when performing a refactoring task.&lt;/p&gt;

&lt;p&gt;So, you found code that is ugly, hard to read, or too complex. The question is, do you ignore it or do something to change it? The answer would be to strive for improvement and change it (as long as it meets certain characteristics that I will describe later).&lt;/p&gt;

&lt;p&gt;Richard Fowler talks about two work styles when sitting down to develop: the construction hat, which one wears when adding new functionality to the system, and the improvement hat, which is used when performing a refactoring task. During development, we will be forced to switch hats depending on what we want to do. The important thing is not to do both things at the same time because it can lead us to make changes without being sure that we can run a battery of tests to ensure that the system is functioning correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workflows of Refactoring
&lt;/h2&gt;

&lt;p&gt;Changes that do not alter functionality or have a small impact should be made immediately. Such as renaming methods, variables, and functions to make them clearer, and extracting methods to better encapsulate their behavior. Fowler refers to this practice as “The Boy Scout Rule,” based on the principle of “Always leave the campsite cleaner than you found it.” This refactoring method is called Litter-Pickup Refactoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Preparing Refactor
&lt;/h2&gt;

&lt;p&gt;This type of refactor often occurs when we want to add a new feature, but we realize that the current code does not easily allow for adding this feature. However, by making some changes, it may be easier to implement the new feature. This type of refactor is &lt;a href="https://samurai-developer.com/clean-code/"&gt;essential to keep the code clean&lt;/a&gt; and promote easier addition of future features, reducing development time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Planned Refactor and Long-Term Refactor
&lt;/h2&gt;

&lt;p&gt;So far, we have talked about refactors that are done during our day-to-day work and do not require meticulous planning and organization. However, there is a type of refactor that does require these measures: planned refactors. These are refactors that are planned, estimated, and have a medium to large size or a significant impact on the system’s architecture and functionality, requiring careful attention during their execution. Fowler warns that these types of refactors are “bad” in the sense that a well-designed system should not need this type of refactor, and medium to large refactors can be carried out by breaking them into smaller tasks and iterating to accomplish them. This type of refactor is called &lt;strong&gt;long-term refactor&lt;/strong&gt;. However, it is not wrong for an occasional refactor of this kind to arise.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should I apply refactoring?
&lt;/h2&gt;

&lt;p&gt;Up to this point, one might think that my idea of refactoring is to be a kind of bulldozer that cleans up everything in its path. Well, yes and no. To decide when to apply a non-simple and quick refactor, one must consider a series of things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How much time will it take?&lt;/li&gt;
&lt;li&gt;How often will I encounter this “bad smell” code in my day-to-day work?&lt;/li&gt;
&lt;li&gt;Am I in a moment where I can carry it out?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, if we are dealing with a problem in production, with alarms going off and messages coming through all communication channels, clearly we are not going to start doing refactors that take more time to generate a solution. Here we don’t change hats; the goal is to create the fix.&lt;/p&gt;

&lt;p&gt;As for how often I will come across the code, that is the metric I pay the most attention to because the modules that change the most should be the clearest and cleanest ones, as they facilitate my task of understanding what they do and being able to modify or add more features to them. Code that doesn’t have much impact and is unlikely to be encountered again doesn’t require the effort; after all, time is a resource and must be managed in the best possible way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Justifying the Refactoring
&lt;/h2&gt;

&lt;p&gt;Fowler also talks about how to explain to our bosses or leaders the need for refactoring to be part of development, just like testing. It is true that we can cite reasons such as readability or speed, but these justifications are purely technical and tend to dilute as they go up the ladder of management. However, there is one justification that always prevails: money.&lt;/p&gt;

&lt;p&gt;Instead of presenting a technical diatribe of justifications, it is easier to reach people with things they are more familiar with, for example:&lt;/p&gt;

&lt;p&gt;“I need to refactor X because it will make it faster to add functionality Y, and if we want to add Z tomorrow, it will be easier too.”&lt;/p&gt;

&lt;p&gt;“This refactor reduces our expenses on the database, CPU, hosts, etc., by minimizing resource usage.”&lt;/p&gt;

&lt;p&gt;The moment we keep going back and forth about performing refactorings is the moment we lose the battle.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9tlBaSNm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/samurai-developer.com/wp-content/uploads/2023/05/cropped-katana-1.png%3Ffit%3D32%252C32%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9tlBaSNm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/samurai-developer.com/wp-content/uploads/2023/05/cropped-katana-1.png%3Ffit%3D32%252C32%26ssl%3D1" alt="Samurai Developer Icon" width="32" height="32"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://samurai-developer.com/refactoring-hats-and-workflows/"&gt;From Chaos to Order: Refactoring Fundamentals for Better Results&lt;/a&gt; first appeared on &lt;a href="https://samurai-developer.com"&gt;Samurai Developer&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>refactoring</category>
    </item>
  </channel>
</rss>
