<?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: Jaap Groeneveld</title>
    <description>The latest articles on DEV Community by Jaap Groeneveld (@jgroeneveld).</description>
    <link>https://dev.to/jgroeneveld</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%2F694357%2Ffec7f9a6-205d-44fc-9208-fe39c0e6b402.jpg</url>
      <title>DEV Community: Jaap Groeneveld</title>
      <link>https://dev.to/jgroeneveld</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jgroeneveld"/>
    <language>en</language>
    <item>
      <title>Software Testing</title>
      <dc:creator>Jaap Groeneveld</dc:creator>
      <pubDate>Sat, 10 Dec 2022 19:47:34 +0000</pubDate>
      <link>https://dev.to/jgroeneveld/software-testing-2n59</link>
      <guid>https://dev.to/jgroeneveld/software-testing-2n59</guid>
      <description>&lt;p&gt;I think that software testing is essential for ensuring the quality and reliability of software. I believe that a comprehensive testing strategy, including a mix of different types of testing, is necessary to identify and fix any issues with the software before it is released to users. I also believe that testing should be an ongoing process, with tests being performed regularly throughout the development cycle to catch problems early on and prevent them from becoming bigger issues later. Additionally, I believe that testing should be an integral part of the development process, with developers and testers working together to ensure that the software meets the specified requirements and works as intended.&lt;/p&gt;

&lt;p&gt;In this article about testing software I want to explain what software testing is and elaborate on my philosphy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is software testing and why is it important
&lt;/h2&gt;

&lt;p&gt;Software testing is the process of evaluating a software application or system to determine whether it meets the specified requirements and works as intended. It is an important part of the software development process because it helps to identify bugs, defects, and other issues with the software, and ensures that the final product is of high quality and fit for its intended purpose. &lt;/p&gt;

&lt;p&gt;Software can be tested manually and also automatically. The two are not mutually exclusive. &lt;strong&gt;Automated testing is not a replacement for manual testing&lt;/strong&gt;, but it is a useful complement to manual testing. Automated tests can help to quickly and efficiently identify problems with the software, while manual testing can be used to explore the software and test it in ways that automated tests may not cover.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is manual testing?
&lt;/h2&gt;

&lt;p&gt;In manual testing the tester manually performs a series of actions on the software, such as clicking on buttons and entering data, to test its functionality and identify any bugs or defects. &lt;br&gt;
This is in contrast to automated testing, in which the testing is performed using specialized software tools that automatically execute the test cases. Manual testing is useful for testing the user interface and other aspects of the software that may be difficult to test using automated tools. It is also useful for &lt;strong&gt;exploratory testing&lt;/strong&gt;, in which the tester has the freedom to try out different scenarios and test the software in ways that may not be covered by the pre-defined test cases.&lt;/p&gt;

&lt;p&gt;A lot of companies employ specific QA (Quality Assurance or Quality Assistance) experts that help with manual testing as well as with automated testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is automated testing?
&lt;/h2&gt;

&lt;p&gt;Automated testing is a way of testing software using special tools that can run tests automatically without human intervention. These tools can run tests quickly and accurately, and they can be used to test parts of the software that are difficult to test manually. Automated testing is useful because it can help to identify problems with the software and ensure that it works as intended. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated tests can be run quickly and repeatedly, which is useful for performing regression testing to ensure that changes to the software haven't introduced new bugs.&lt;/li&gt;
&lt;li&gt;  Automated tests can be run without human intervention, which is useful for running tests overnight or in continuous integration environments.
&lt;/li&gt;
&lt;li&gt;  Automated tests are (or should be) consistent and accurate, since they are performed using the same set of instructions every time.
&lt;/li&gt;
&lt;li&gt;  Automated tests can cover a larger number of test cases, since they don't rely on a human tester to manually perform each test.
&lt;/li&gt;
&lt;li&gt;  Automated tests can be used to test parts of the software that are difficult or impossible to test manually, such as performance or security.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are many different types of testing, but some common ones include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;Unit testing&lt;/strong&gt;: This involves testing individual components or units of the software to ensure they function as intended.
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Integration testing&lt;/strong&gt;: This involves testing the integration of different components or units of the software to ensure they work together as expected.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;System / End-to-end testing&lt;/strong&gt;: This involves testing the entire system as a whole to ensure it meets the specified requirements and works as intended.
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Regression testing&lt;/strong&gt;: This involves testing the software after making changes to ensure that the changes have not introduced new bugs or defects.
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Acceptance testing&lt;/strong&gt;: This involves testing the software from the end user's perspective to ensure that it is usable and meets their needs.
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Performance testing&lt;/strong&gt;: This involves testing the software to ensure it performs well under expected workloads and doesn't crash or slow down.
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Security testing&lt;/strong&gt;: This involves testing the software to ensure it is secure and protects sensitive data from unauthorized access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smoke testing&lt;/strong&gt;: This involves testing the software to ensure that the most important functions of a software application or system are working properly in a live environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The test pyramid
&lt;/h2&gt;

&lt;p&gt;The test pyramid is a concept in software testing that suggests that the majority of tests should be unit tests, which are the lowest-level tests, followed by a smaller number of integration tests, and even fewer high-level end-to-end tests. This concept is called the "test pyramid" because it is visualized as a pyramid, with the unit tests forming the base and the end-to-end tests forming the tip of the pyramid. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14u8ai5hc4139hmchm7t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14u8ai5hc4139hmchm7t.png" alt="Image description" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea behind the test pyramid is that &lt;strong&gt;unit tests&lt;/strong&gt; are fast and cheap to write and maintain, and they provide good coverage of the code. &lt;strong&gt;Integration tests&lt;/strong&gt; are a bit more expensive to write and maintain, but they test the integration of different components or units of the software, which is important for ensuring that the software works as intended. &lt;strong&gt;End-to-end tests&lt;/strong&gt;, on the other hand, are the most expensive to write and maintain, but they provide the highest level of confidence that the software works as intended from the end user's perspective. The test pyramid is a general guideline, and the specific mix of tests will depend on the specific software being developed and the goals of the testing.&lt;/p&gt;

&lt;p&gt;There are different visual models representing the distribution of tests in the system like the test cone, the test iceberg, the test ladder and the test mosaic. If you are interested, you can do further research.&lt;/p&gt;

&lt;p&gt;Not always a 100% test pyramid distribution is the right way to go. The specific approach to testing will depend on the specific software being developed and the goals of the testing. The test pyramid is a useful starting point, but it may not be the best approach for every situation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The danger of tests
&lt;/h2&gt;

&lt;p&gt;Unit tests are testing individual components (units) of the software to ensure that they function as intended. &lt;br&gt;
A unit is the smallest testable part of the software, such as a &lt;strong&gt;function&lt;/strong&gt;, and a unit test is a test that exercises that unit and &lt;strong&gt;verifies its behavior&lt;/strong&gt;. The idea behind unit testing is to test each unit of the software in isolation, without the need to set up a complex test environment or coordinate the execution of multiple tests. This makes unit tests fast and easy to write and maintain, and they can provide good coverage of the code. &lt;/p&gt;

&lt;p&gt;Integration tests are testing the integration of different components or units of the software to ensure that they work together as expected. &lt;/p&gt;

&lt;p&gt;The problem with the test pyramid is that a lot of unit tests in the real world are actually not testing behavior nor integration. I am sure you have encounted &lt;strong&gt;mock heavy test suites&lt;/strong&gt; that basically test if a method calls 3 other functions but nothing else is tested. They do not guarantee actual business logic nor do they guarantee actual integration with other parts of the application.&lt;/p&gt;

&lt;p&gt;While these tests can still be helpful, they also have some disadvantages, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They do not actually test any behavior. There is no real business value in testing that function A calls function B. &lt;/li&gt;
&lt;li&gt;Thy can be brittle, meaning that they can break easily if the software is changed. This is because like integration tests, mock heavy unit tests often test the interaction between multiple components, and any changes to the interface of one of those components or the structure of the program can affect the behavior of the test.&lt;/li&gt;
&lt;li&gt;  The may not provide complete coverage of the software being tested. They may not exercise all the individual components or units of the software in the same way that real unit and integration tests do.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, unit and integration tests are an important part of the software testing process, but they should be used in combination with other types of testing, such as end-to-end tests, to provide the most comprehensive coverage of the software being tested. &lt;strong&gt;In addition, mocks should be the last resort not the first tool in the box.&lt;/strong&gt; Often, it is a good idea to rethink what a unit boundary is and opt for more integration tests rather than test every single method with a lot of mocks.&lt;/p&gt;

&lt;h2&gt;
  
  
  100% Code Coverage
&lt;/h2&gt;

&lt;p&gt;Code coverage is a measure of how much of your source code is executed when you run your tests. It helps you determine how thorough your tests are, and can help you identify areas of your code that are not being exercised by your tests. This is important because untested code is potentially more likely to contain bugs. Often teams try to aim for 100% code coverage.&lt;/p&gt;

&lt;p&gt;Achieving 100% code coverage does not necessarily mean that your code is free of bugs or that it is adequately tested. It just means that your tests are exercising all of the lines of code in your source code. However, it is possible to have tests that cover all lines of code but still do not adequately test the functionality of your code. For example, you might have tests that only call a function with trivial input values, which means that the function is not being tested under more realistic or challenging conditions. In this case, even though you have 100% code coverage, your tests are not providing a sufficient level of assurance that your code is working correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Top-Down and Bottom-Up testing
&lt;/h2&gt;

&lt;p&gt;Top-down testing and bottom-up testing are both software testing approaches that are used to test the functionality of a system.&lt;/p&gt;

&lt;p&gt;In top-down testing, tests are written at the highest level of the system and then gradually move down to lower levels. This approach starts by testing the overall functionality of the system and then drills down into the individual components and their interactions. The goal of top-down testing is to test the system from the top level and ensure that all of the components work together as intended.&lt;/p&gt;

&lt;p&gt;In bottom-up testing, also known as outside-in testing, tests are written at the lowest level of the system first, and then gradually move up to higher levels. This approach starts by testing the individual components of the system and then moves up to test the interactions between these components. The goal of bottom-up testing is to test the system from the perspective of the user or client, focusing on the interactions between the different components of the system.&lt;/p&gt;

&lt;p&gt;Both top-down and bottom-up testing have their own strengths and weaknesses. Top-down testing can be useful for identifying defects at the higher levels of the system, but it may not adequately test the interactions between the individual components. Bottom-up testing, on the other hand, can be effective for identifying defects in the interactions between the different components of the system, but it may not adequately test the overall functionality of the system. It is often best to use a combination of both approaches in order to get the most thorough and effective testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  TDD - Test Driven Design
&lt;/h2&gt;

&lt;p&gt;Test-driven design (TDD) is an approach in which tests are written for a piece of code before the code itself is written. The tests are initially written to fail, and then the code is written to make the tests pass. This approach helps to ensure that the code is written to satisfy the requirements of the tests, and that it is properly tested and working as expected.&lt;/p&gt;

&lt;p&gt;In TDD, the development process typically follows these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Write a test that defines a piece of functionality that you want to add to your code.&lt;/li&gt;
&lt;li&gt; Run the test and confirm that it fails, because the functionality does not yet exist in the code.&lt;/li&gt;
&lt;li&gt; Write the code to make the test pass.&lt;/li&gt;
&lt;li&gt; Run the test again and confirm that it passes.&lt;/li&gt;
&lt;li&gt; Refactor the code to improve its design and maintainability, without changing its functionality.&lt;/li&gt;
&lt;li&gt; Repeat these steps for each piece of functionality that you want to add to your code.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;TDD can help to ensure that your code is well-designed, properly tested, and free of defects. It can also help to make your code more modular and easier to maintain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48oxo7n2vc9ogyhg7bex.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48oxo7n2vc9ogyhg7bex.png" alt="Image description" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One common criticism of TDD is that it can be time-consuming and may not always be the most efficient way to develop software. Writing tests for every piece of code that you write can take extra time and effort, and it may not always be clear what tests should be written or how to write effective tests. This can lead to tests that are too broad or too specific, which can make the development process more difficult and less efficient.&lt;/p&gt;

&lt;p&gt;Another criticism of TDD is that it &lt;strong&gt;can lead to over-testing&lt;/strong&gt;, where too many tests are written for a given piece of code. This can make the test suite unnecessarily large and complex, and can make it more difficult to maintain and update the tests as the codebase changes over time.&lt;/p&gt;

&lt;p&gt;Additionally, some critics argue that TDD can lead to a focus on testing at the expense of other important aspects of software development, such as design and architecture. This can result in code that is &lt;strong&gt;well-tested but not well-designed&lt;/strong&gt;, which can make the code more difficult to maintain and evolve over time.&lt;/p&gt;

&lt;p&gt;Overall, while TDD can be a useful tool for ensuring that code is properly tested and working as expected, it is important to use it in the right circumstances and to balance it with other important considerations in software development.&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Writing code like writing books</title>
      <dc:creator>Jaap Groeneveld</dc:creator>
      <pubDate>Thu, 08 Dec 2022 18:00:00 +0000</pubDate>
      <link>https://dev.to/jgroeneveld/writing-code-like-writing-books-eeh</link>
      <guid>https://dev.to/jgroeneveld/writing-code-like-writing-books-eeh</guid>
      <description>&lt;p&gt;Writing readable code is important for a few reasons. First, readable code is easier to understand, which means that it is easier to modify and maintain. This can save time and effort, especially for large projects that may be worked on by multiple people. Second, readable code is more likely to be correct, because it is easier to spot mistakes when the code is easy to understand. Finally, writing readable code can improve your own understanding of the code, because the process of writing clearly and concisely can help you to think more deeply about the problem you are trying to solve.&lt;/p&gt;

&lt;p&gt;It is difficult to say exactly how much time developers spend reading and understanding code compared to writing it, as this can vary depending on many factors. However, it is generally accepted that a significant amount of time is spent reading and understanding code, often more than is spent writing it. This is because writing code is just one part of the development process, and it is often necessary to read and understand existing code in order to modify it or add new features. Additionally, many developers find that reading and understanding code can be a challenging and time-consuming task, especially for large and complex projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing code like books
&lt;/h2&gt;

&lt;p&gt;A good way to make code more readable is to get influenced by how people structure books and articles, especially in technical writing. Usually, the main goal of them is to make a complicated matter understandable by the reader. As this is also one of our goals, lets talk about this.&lt;/p&gt;

&lt;p&gt;One way is to use comments and white space to break your code into logical sections, similar to how a book is divided into chapters and paragraphs. You can also use indentation to show the hierarchy and structure of your code, and to make it easier to see how different parts of your code relate to each other. Finally, you can use documentation to provide a high-level overview of your code, similar to how a book might have a table of contents and an introduction.&lt;/p&gt;

&lt;p&gt;We want to read code as a set of "paragraphs" each describing the current level of abstraction and referencing down. This can make it easier to understand the logic and flow of the program.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Place functions in the downward direction.&lt;/li&gt;
&lt;li&gt;Declare variables close to their usage.&lt;/li&gt;
&lt;li&gt;Keep lines short.&lt;/li&gt;
&lt;li&gt;Use white space to associate related things and disassociate weakly related.&lt;/li&gt;
&lt;li&gt;Think about cohesion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Placing functions in the downward direction can help to show the order in which they are called, and declaring variables close to their usage can make it easier to see how they are used in the code. Keeping lines short can also make the code easier to read and understand, as long as the code is still clear and easy to follow. Long lines are fine if it is obvious what is going on and it is not hiding relevant calls.&lt;/p&gt;

&lt;p&gt;Using white space to associate related things and disassociate weakly related items is also a good idea, as it can help to clarify the structure and organization of the code. This can be achieved by using indentation, blank lines, and other techniques to visually separate different parts of the code.&lt;/p&gt;

&lt;p&gt;Cohesion is another important concept in writing readable code. This refers to the degree to which the different parts of a module or function work together to achieve a single, well-defined purpose. A high degree of cohesion can make your code easier to understand and maintain, because it helps to ensure that each module or function has a clear and focused role.&lt;/p&gt;

&lt;p&gt;In this article I will explain the &lt;strong&gt;Step-Down-Rule&lt;/strong&gt; and &lt;strong&gt;Line-of-Sight&lt;/strong&gt;. To principles that will help you to structure code and make it more readable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Step-Down-Rule
&lt;/h2&gt;

&lt;p&gt;The step-down rule is a software engineering principle that suggests that functions should be organized in a hierarchical manner, with higher-level functions calling lower-level functions. This means that higher-level functions should do the overall work of the program, while lower-level functions should perform more specific tasks that support the work of the higher-level functions.&lt;/p&gt;

&lt;p&gt;The step-down rule is based on the idea that it is easier to understand and maintain code when it is organized in a clear and logical manner. By organizing your code in a hierarchical fashion, you can make it easier to see the relationship between different parts of the code, and to understand how they work together to achieve the desired outcome. Additionally, following the step-down rule can help to ensure that your code is modular and reusable, which can make it easier to modify and extend over time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;CreatePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;getPostFromRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;validatePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;savePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;201&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;getPostFromRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;validatePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;savePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code example we have the &lt;code&gt;CreatePost&lt;/code&gt; function that outlines the process and deals with the interface to the outside world. It delegates sub-tasks to other functions and only deals with results and errors. This allows you to quickly understand the overall flow without getting lost in the details on how a post is validated or saved. If you want to know how that works, you can dig deeper. This is also called &lt;strong&gt;separation of concern&lt;/strong&gt; and does not only make the code more readable, it also makes it easier to test.&lt;/p&gt;

&lt;h3&gt;
  
  
  Separation of Concern
&lt;/h3&gt;

&lt;p&gt;Separation of concern refers to the idea of dividing a program into distinct parts, each of which addresses a specific concern or responsibility. This can make code easier to test because it allows you to focus on testing specific parts of the code independently, rather than having to test the entire program at once.&lt;/p&gt;

&lt;p&gt;For example, if you have a program that performs several different tasks, you can divide the code into separate functions or modules, each of which is responsible for a specific task. This allows you to write individual tests for each function or module, and to verify that they are working correctly on their own. This can make it easier to find and fix bugs, because you can isolate the problem to a specific part of the code, rather than having to search through the entire program to find the source of the error.&lt;/p&gt;

&lt;p&gt;Additionally, separation of concern can make it easier to test your code because it can help to ensure that your code is modular and reusable. This means that you can use the same functions or modules in multiple parts of your program, and you only need to test them once. This can save time and effort, and it can also help to reduce the amount of code that you need to write and maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Line of Sight
&lt;/h2&gt;

&lt;p&gt;Line of sight is a software engineering principle that suggests that the flow of control through a program should be easy to follow and understand. This means that the structure of the code should be clear and logical, and that the relationships between different parts of the code should be easy to see.&lt;/p&gt;

&lt;p&gt;One way to achieve line of sight in your code is to use indentation and white space to visually separate different parts of the code and to show the hierarchy and structure of the program. You can also use clear and descriptive variable and function names to make it easier to understand what each part of the code is doing.&lt;/p&gt;

&lt;p&gt;One important idea with the line of sight is to prevent nesting as much as possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is nesting and why do we want to prevent it?
&lt;/h3&gt;

&lt;p&gt;Nesting refers to the practice of placing one control structure inside another, such as putting an if statement inside of a for loop. While this can sometimes be necessary to achieve the desired behavior, excessive nesting can make the code difficult to read and understand.&lt;/p&gt;

&lt;p&gt;One reason to avoid excessive nesting is that it can make the code hard to follow. When you have many levels of nested control structures, it can be difficult to keep track of where you are in the code, and to understand how different parts of the code are related to each other. This can make it hard to find and fix bugs, and it can also make it difficult to modify or extend the code in the future.&lt;/p&gt;

&lt;p&gt;Another reason to avoid excessive nesting is that it can make the code less modular and reusable. When you have many levels of nested control structures, it can be difficult to extract a specific part of the code and use it in a different part of the program. This can make it harder to write clean and concise code, and it can also make it harder to maintain and update the code over time.&lt;/p&gt;

&lt;p&gt;Overall, while some nesting may be necessary in some cases, it is generally best to avoid excessive nesting in your code in order to make it easier to read and understand.&lt;/p&gt;

&lt;p&gt;Here is a example of the above code writting with excessive nesting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;CreatePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;getPostFromRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;validatePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;savePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;201&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"error saving post"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"error validating post"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"error getting post"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How do we prevent nesting?
&lt;/h3&gt;

&lt;p&gt;The golden rule is to align the happy path to the left; you should quickly be able to scan down one column to see the expected execution flow. If everything is fine, continue down, if there is an error, go right, handle it and return.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use early returns&lt;/li&gt;
&lt;li&gt;Extract functions to keep bodies small and readable&lt;/li&gt;
&lt;li&gt;Avoid else returns; consider flipping the if statement&lt;/li&gt;
&lt;li&gt;Put the happy return statement as the very last line&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To prevent excessive nesting in your code, you can follow a few best practices. One way to avoid nesting is to use &lt;strong&gt;early returns&lt;/strong&gt;, which means that you return from a function or method as soon as you have completed the necessary work. This can help to reduce the amount of nesting in your code, because it allows you to exit a function or method without having to place the rest of the code inside of an if statement or other control structure.&lt;/p&gt;

&lt;p&gt;Another way to avoid nesting is to use helper functions or methods to &lt;strong&gt;break up complex code into smaller, more manageable pieces&lt;/strong&gt;. This can make it easier to write clean and concise code, and it can also make it easier to test and debug your code. By dividing your code into smaller, focused functions or methods, you can reduce the amount of nesting and make your code easier to read and understand.&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Interviewing as a Team Lead or Engineering Manager</title>
      <dc:creator>Jaap Groeneveld</dc:creator>
      <pubDate>Tue, 06 Dec 2022 20:00:00 +0000</pubDate>
      <link>https://dev.to/jgroeneveld/interviewing-as-a-team-lead-or-engineering-manager-35ao</link>
      <guid>https://dev.to/jgroeneveld/interviewing-as-a-team-lead-or-engineering-manager-35ao</guid>
      <description>&lt;h2&gt;
  
  
  I have an interview for a software engineering team lead position coming up. What questions should I be prepared for?
&lt;/h2&gt;

&lt;p&gt;In a team lead position, you'll likely be asked questions that evaluate your leadership and management skills, as well as your technical expertise. Some common questions you might be asked include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can you tell me about a time when you led a team or project, and what you did to ensure its success?&lt;/li&gt;
&lt;li&gt;  How do you motivate and manage team members to achieve their goals?&lt;/li&gt;
&lt;li&gt;  How do you handle conflicts within a team and ensure that everyone is working together effectively?&lt;/li&gt;
&lt;li&gt;  Can you provide an example of a difficult technical problem you faced and how you solved it?&lt;/li&gt;
&lt;li&gt;  How do you stay up-to-date with the latest technology and trends in software engineering?&lt;/li&gt;
&lt;li&gt;  What is your approach to project management and planning?&lt;/li&gt;
&lt;li&gt;  How do you communicate with other teams and stakeholders to ensure that everyone is on the same page and working towards the same goals?&lt;/li&gt;
&lt;li&gt;  Can you give an example of a time when you had to make a difficult decision as a team lead, and how you went about making it?&lt;/li&gt;
&lt;li&gt;  How do you balance the needs of the team with the needs of the business or organization?&lt;/li&gt;
&lt;li&gt;  Can you describe a time when you had to deal with a underperforming team member, and how you handled the situation?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Team Lead interviews often rely on &lt;strong&gt;behavioral interviews&lt;/strong&gt; questions designed to elicit specific examples of the candidate's past behavior in order to determine their suitability for the job. The idea behind this type of interview is that a person's past behavior is the best predictor of their future behavior, so asking the candidate to provide specific examples of how they have handled certain situations in the past can provide insight into how they might handle similar situations in the future. Behavioral interviews are often used to assess a candidate's skills, knowledge, and experience, and can help the interviewer determine whether the candidate is a good fit for the job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The STAR model&lt;/strong&gt; is a technique that is often used in behavioral interviews to help structure answers to questions. It stands for Situation, Task, Action, and Result. &lt;br&gt;
When answering a question using the STAR model, you would first describe the specific situation or task that you were faced with, then describe the actions that you took to address the situation, and finally, describe the results of those actions. This technique can help you provide a clear and concise answer to the interviewer, and can also help you demonstrate how your skills and experiences are relevant to the job you are applying for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Answers to some common questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How do I motivate and manage team members to achieve their goals?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ultimately, the key to motivating and managing team members is to create an environment where they can do their best work, and where they feel valued and supported. By focusing on clear goals, open communication, and ongoing support, you can help your team members achieve their goals and succeed.&lt;/p&gt;

&lt;p&gt;To motivate and manage team members to achieve their goals, there are a few key things you can do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Set clear and specific goals for the team and for individual team members. This will help everyone understand what they need to do, and why it's important.&lt;/li&gt;
&lt;li&gt; Communicate regularly with team members to check in on their progress and provide support and guidance.&lt;/li&gt;
&lt;li&gt; Provide opportunities for professional development and training, so that team members can grow and improve their skills.&lt;/li&gt;
&lt;li&gt; Recognize and reward good performance, and provide constructive feedback to help team members improve.&lt;/li&gt;
&lt;li&gt; Create a positive and collaborative work environment, where team members feel valued and supported.&lt;/li&gt;
&lt;li&gt; Be a good role model and lead by example. Show team members what it looks like to work hard, be focused, and deliver high-quality work.&lt;/li&gt;
&lt;li&gt; Be open to feedback and suggestions from team members, and be willing to make changes based on their input.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How do I handle conflicts within a team and ensure that everyone is working together effectively?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Conflict within a team is inevitable, but it can be managed and resolved in a way that ensures that everyone is working together effectively. By addressing conflicts openly and honestly, and working together to find solutions, you can help ensure that your team is able to work together effectively and achieve its goals.&lt;/p&gt;

&lt;p&gt;Here are some steps you can take to handle conflicts within a team:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Address conflicts as soon as they arise. Don't ignore them or hope that they will go away on their own.&lt;/li&gt;
&lt;li&gt; Be open and transparent about the conflict. Encourage team members to express their thoughts and feelings, and listen to what they have to say.&lt;/li&gt;
&lt;li&gt; Identify the root cause of the conflict. Is it a misunderstanding, a personality clash, or a disagreement about how to approach a problem? Understanding the underlying issue can help you find a solution.&lt;/li&gt;
&lt;li&gt; Find a resolution that works for everyone. This may involve compromising, negotiating, or finding a creative solution that meets the needs of all parties involved.&lt;/li&gt;
&lt;li&gt; Follow up to ensure that the conflict is resolved and that everyone is moving forward in a positive way.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Can you provide an example of a difficult technical problem you faced and how you solved it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the STAR model to describe a concrete situation and make sure to highlight your part in the situation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you stay up-to-date with the latest technology and trends in software engineering?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You need to answer this with your personal situation. Here are a few different ways to stay up-to-date with the latest technology and trends in software engineering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Attend conferences and workshops focused on software engineering and related topics. These can be great opportunities to learn about new technologies and best practices, and to network with other professionals in the field.&lt;/li&gt;
&lt;li&gt;  Read blogs, newsletters, and other online resources that cover the latest developments in software engineering. This can help you stay on top of new technologies and trends, and can provide valuable insights and ideas.&lt;/li&gt;
&lt;li&gt;  Join online communities and forums related to software engineering. These can be great places to connect with other professionals, share knowledge and experiences, and learn from each other.&lt;/li&gt;
&lt;li&gt;  Follow thought leaders and influencers in the field of software engineering on social media. This can help you stay informed about the latest developments and ideas, and can also help you connect with other professionals in the field.&lt;/li&gt;
&lt;li&gt;  Experiment with new technologies and tools on your own. This can be a great way to gain hands-on experience and stay up-to-date with the latest developments in software engineering.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is your approach to project management and planning?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In general, effective project management and planning involves a few key steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Define the scope of the project, including the goals and objectives, the deliverables, and the timeline. This will help you and your team understand what needs to be done, and when it needs to be done.&lt;/li&gt;
&lt;li&gt; Develop a detailed project plan, including a schedule, a budget, and a list of tasks and milestones. This will help you organize your work and track your progress.&lt;/li&gt;
&lt;li&gt; Identify the resources you'll need, including people, equipment, and materials. This will help you make sure you have everything you need to complete the project.&lt;/li&gt;
&lt;li&gt; Communicate with your team, stakeholders, and other relevant parties throughout the project. This will help everyone stay informed and on the same page.&lt;/li&gt;
&lt;li&gt; Monitor and track your progress, and make adjustments as needed. This will help you stay on schedule and on budget.&lt;/li&gt;
&lt;li&gt; Review and evaluate the project once it's complete, and use the lessons learned to improve future projects.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How do you communicate with other teams and stakeholders to ensure that everyone is on the same page and working towards the same goals?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Effective communication is key to ensuring that everyone is on the same page and working towards the same goals. Here are some tips for communicating with other teams and stakeholders:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Be clear and concise in your communication. Avoid using technical jargon or complex language that others might not understand.&lt;/li&gt;
&lt;li&gt; Use a variety of communication methods, such as face-to-face meetings, email, and online collaboration tools, to reach different people in different ways.&lt;/li&gt;
&lt;li&gt; Listen to what others have to say, and be open to their feedback and suggestions. This will help you understand their perspectives and build trust.&lt;/li&gt;
&lt;li&gt; Provide regular updates on the progress of the project, and highlight any potential issues or challenges that need to be addressed.&lt;/li&gt;
&lt;li&gt; Be transparent and honest in your communication. If there are problems or delays, let others know as soon as possible, and provide clear explanations for what's happening and how you plan to address it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Can you give an example of a time when you had to make a difficult decision as a team lead, and how you went about making it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In general, when faced with a difficult decision as a team lead, it's important to consider all of the available information and options, and to weigh the potential pros and cons of each. Here are some steps you can take to help you make a difficult decision:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Define the problem or issue that needs to be addressed. This will help you clarify what needs to be decided, and why it's important.&lt;/li&gt;
&lt;li&gt; Gather as much information as possible. This may involve talking to team members, stakeholders, and other relevant parties, as well as researching the issue.&lt;/li&gt;
&lt;li&gt; Consider all of the options and alternatives. Try to be as creative and open-minded as possible, and think about the potential implications of each option.&lt;/li&gt;
&lt;li&gt; Consult with others, as appropriate. This may involve talking to other team leads, managers, or experts in the field.&lt;/li&gt;
&lt;li&gt; Make a decision and take action. Once you've considered all of the information and options, make a decision and take action. Be prepared to explain your decision to others and to defend it if necessary.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use the STAR model to describe a concrete situation and make sure to highlight your part in the situation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you balance the needs of the team with the needs of the business or organization?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As a team lead, it's important to balance the needs of the team with the needs of the business or organization. This can be challenging, but there are a few key things you can do to help you strike the right balance:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Understand the goals and objectives of the business or organization, and make sure that the team's goals and objectives align with them.&lt;/li&gt;
&lt;li&gt; Communicate regularly with stakeholders and other relevant parties, and make sure that everyone is on the same page and working towards the same goals.&lt;/li&gt;
&lt;li&gt; Prioritize tasks and projects based on their importance to the business or organization, and allocate resources accordingly.&lt;/li&gt;
&lt;li&gt; Be flexible and adaptable. Be willing to make changes and adjustments as needed to meet the changing needs of the business or organization.&lt;/li&gt;
&lt;li&gt; Involve the team in decision-making and problem-solving. This will help ensure that the team's needs are taken into account, and that everyone feels invested in the success of the business or organization.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Can you describe a time when you had to deal with a underperforming team member, and how you handled the situation?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In general, when dealing with an underperforming team member, it's important to approach the situation with empathy, respect, and professionalism. Here are some steps you can take to handle the situation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Identify the underlying issue. Is the team member struggling with a specific task or skill, or are there other factors that are impacting their performance?&lt;/li&gt;
&lt;li&gt; Talk to the team member and discuss the issue openly and honestly. Be specific about their performance, and provide concrete examples of what they're doing well and what they need to improve.&lt;/li&gt;
&lt;li&gt; Listen to the team member's perspective, and try to understand their challenges and concerns. Be empathetic and supportive, and avoid being critical or judgmental.&lt;/li&gt;
&lt;li&gt; Develop a plan to help the team member improve their performance. This may involve providing additional training, support, or resources, or setting specific goals and objectives.&lt;/li&gt;
&lt;li&gt; Follow up regularly to check on the team member's progress, and provide ongoing support and guidance.&lt;/li&gt;
&lt;li&gt; Evaluate the team member's performance over time, and be prepared to make changes to the plan if necessary.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use the STAR model to describe a concrete situation and make sure to highlight your part in the situation.&lt;/p&gt;

</description>
      <category>showdev</category>
    </item>
    <item>
      <title>About documentation</title>
      <dc:creator>Jaap Groeneveld</dc:creator>
      <pubDate>Thu, 10 Nov 2022 11:41:40 +0000</pubDate>
      <link>https://dev.to/jgroeneveld/about-documentation-2pac</link>
      <guid>https://dev.to/jgroeneveld/about-documentation-2pac</guid>
      <description>&lt;p&gt;In this Article I am talking about comments but also check out my article on comments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thoughts on documentation
&lt;/h2&gt;

&lt;p&gt;Developers hate writing documentation. And I understand it. Writing it is very hard. Reading bad documentation is never done because nobody reads it anyway. When you are working on a project and you are knee deep in the project, you know everything anyway, why document?&lt;/p&gt;

&lt;p&gt;I am a fan of good documentation. But to understand, what is good documentation, lets talk about the different types of documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of documentation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Inline Documentation: Inline Comments
&lt;/h3&gt;

&lt;p&gt;Comments within the code are also one type of documentation that is often overlooked. You can read my article about them here. &lt;br&gt;
They are used directly within the code to clarify things for the reader.&lt;/p&gt;

&lt;p&gt;In a nutshell: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They are very close to the code&lt;/li&gt;
&lt;li&gt;They are very detail oriented.&lt;/li&gt;
&lt;li&gt;You won't read them in advance when starting a project.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Inline Documentation: Doc Comments
&lt;/h3&gt;

&lt;p&gt;These are used within the code to document higher level components like functions, classes, modules. Quite often, they rely on a standard and can be used to generate documentation in a dedicated place.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Close to the code&lt;/li&gt;
&lt;li&gt;Describe the components within a codebase on a higher level.&lt;/li&gt;
&lt;li&gt;You might read them one by one when using or working on a component or skip through the high level components like modules when starting on a project.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  API Documentation
&lt;/h3&gt;

&lt;p&gt;This one is very obvious. Documenting the API a library or service provides makes total sense. It's the best way to communicate how to use it to a consumer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Often generated within the code by annotating web handlers / controllers.&lt;/li&gt;
&lt;li&gt;They only document the outer interface of a service or library&lt;/li&gt;
&lt;li&gt;You might read them when using something new or to look up details.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pitfalls: Often the API documentation does not contain a complete example on how to use it and how to combine multiple requests. This is very helpful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Readme Documentation
&lt;/h3&gt;

&lt;p&gt;They usually describe one service in a repository. If you have multiple services in one repository, there might be multiple readmes, one per service.  Most often they describe what the service is supposed to be doing and how you get started running and developing it and also contain pointers to further documentation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They are close to the code&lt;/li&gt;
&lt;li&gt;The describe the purpose of the service and how to get started&lt;/li&gt;
&lt;li&gt;You will read them when you get started developing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pitfalls: If the documentation in the readme is to detailed, it will get out of sync with reality very quickly. Therefor it is best practice to only document what is stable and also have every new developer update the readme when they onboard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Application Architecture Documentation
&lt;/h3&gt;

&lt;p&gt;This is where documentation starts to get more visual. If the application is not trivial, it is very helpful to document the application architecture. Usually this emphasizes the layers, bigger modules and direct external dependencies like caches, data store, queues, other API's etc.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This documentation is not very close to the code anymore as it is high level and therefore can not be autogenerated in a meaningful way.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It has to be maintained by hand when something changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pitfalls:  If this is to detailed it will be wrong very soon. If a new dependency is added, often it is forgotten to add it in this documentation. It is very useful to use this document when onboarding new developers and periodically have a team mob-session to update it. This refreshes memory and keeps it more or less up to date.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lFISsW7f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q0rixgxokcbmsnve9lly.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lFISsW7f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q0rixgxokcbmsnve9lly.png" alt="Application Architecture Example" width="880" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  System Architecture documentation
&lt;/h3&gt;

&lt;p&gt;Depending on the size of the system this part documents the services communicating with each other within the org, the department or the team. Sometimes there will be multiple System Architecture Documentations to limit the scope you have to understand. Sometimes it makes sense to add more documentation for specific parts of the architecture.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very far away from the code, focussing on very high level and the communication between systems.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can be augmented with automatic services that analyze services talking to each other and draw diagrams like &lt;a href="https://backstage.io/"&gt;Backstage&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pitfalls:  If this is to detailed it will be wrong very soon. If new services are added, often it is forgotten to add it in this documentation. It is very useful to use this document when onboarding new developers and update it accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3sKj6Ed_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o379z6xmvfe49pngh26b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3sKj6Ed_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o379z6xmvfe49pngh26b.png" alt="System Architecture Example" width="880" height="783"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Infrastructure &amp;amp; Deployment documentation
&lt;/h3&gt;

&lt;p&gt;It is very helpful to quickly understand where and how a service is deployed, when are which tests running and have a visual representation of that.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where is the service deployed? What infrastructure is involved.&lt;/li&gt;
&lt;li&gt;What is the process of deployement, how does the pipeline look like? What checks are running etc.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Sometimes&lt;/em&gt; the visual pipeline documentation of Tools like Github Actions, Jenkins or Concourse can be good enough or helpful and should be at least linked.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Process Documentation / Runtime Views
&lt;/h3&gt;

&lt;p&gt;Every application and every system contains processes. Some more complicated than others, some more important than others. What happens when a user registers? Which services are hit? Are workers involved?&lt;/p&gt;

&lt;p&gt;Pitfalls: Do not fall into the trap and try to be very precise or try to document each process that happens. Practice &lt;strong&gt;MVD - Minimum Viable Documentation&lt;/strong&gt;. Focus on the most important and most used/changed processes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decision Documentation
&lt;/h3&gt;

&lt;p&gt;Documentation and also Code do not document the history of an application. It is also not possible to economically document all bits and bobs of a system. Therefore it make sense to focus on decision documentation that is easy to search.&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is obvious that it was just a moment in time, it might be out of date&lt;/li&gt;
&lt;li&gt;It documents the history, the reason for the decison and also why alternatives have not been chosen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What kind of decisions should be documented?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architecture decisions&lt;/li&gt;
&lt;li&gt;Tech decisions (Language, libraries, frameworks..)&lt;/li&gt;
&lt;li&gt;Process Decisions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pitfalls: In a software projects are a lot of decisions made on a daily basis. It is not easy to see which decision is a documentation worthy decision. in the beginning, decisions should be discussed with the team and documented to get a feeling what are bigger decisions.&lt;/p&gt;

&lt;p&gt;One example for Decision Documentation are &lt;a href="https://adr.github.io/"&gt;ADR - Architecture Decision Records&lt;/a&gt;.&lt;br&gt;
Here is an &lt;a href="https://www.lasssim.com/architecture-decision-records-example/"&gt;example&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  MVD - Minimum Viable Documentation
&lt;/h2&gt;

&lt;p&gt;Have you heard about &lt;code&gt;MVD - Minimum Viable Documentation&lt;/code&gt;? No? Don't worry, it is a term that I just made up.&lt;/p&gt;

&lt;p&gt;Just like with MVP - Minimum Viable Product, the idea behind MVD is to be very mindful about what amount of documentaton actually solves the problem that it aims to solve. Documentation aims to help you, when onboarding into a new project or during the work on a new project to understand specific parts to you do not have in mind.  Too much documentation will just clutter your mind.  Therefore documentation should be optimized for two use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Onboarding: Optimize for quick and high level understandability of the system and application.&lt;/li&gt;
&lt;li&gt;Look up: Optimize for searchability and correctness. Accept incompleteness in the documentation but make it obvious.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Onboarding, good documentation should focus on high level and visual documentation. For Look Up, documentation should additionally focus on decision records and relevant process documentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation should be as lightweight as possible&lt;/strong&gt; - do not use big templates that are filled with irrelevant filler material. &lt;strong&gt;It should be easy to read, search and edit.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Guidelines for good documentation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Be as transparent as possible on what documentation exists and make it hard to miss.&lt;/li&gt;
&lt;li&gt;Kep it as close to the code as possible (what you see is what you know exists)&lt;/li&gt;
&lt;li&gt;Only document things that are very stable and do not change too much. The more something changes the more time you need to spend on keeping documentation correct.&lt;/li&gt;
&lt;li&gt;The more documentation exists, the less people will read it. Practice &lt;strong&gt;MVD - Minimum Viable Documentation&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Embrace fuzzy Documentation for things that do change.&lt;/li&gt;
&lt;li&gt;Document what somebody withour prior knowledge would need to understand the system quickly, without going into details.&lt;/li&gt;
&lt;li&gt;Use onboarding of new developers as a documentation update tool. Use the High level Application Architecture, System Architecture and Deployment Documentation for onboarding and update before and during onboarding.&lt;/li&gt;
&lt;li&gt;Do periodic team mob-sessions to refresh the memory on the high-level architecture and also to update it if it changed.&lt;/li&gt;
&lt;li&gt;Try to standardize the way documentation works across the organization.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Documentation frameworks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://arc42.org/"&gt;arc42 - arc42&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://c4model.com/"&gt;The C4 model for visualising software architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://adr.github.io/"&gt;ADR - Architecture Decision Records&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I prefer arc42 - it not only helps you with architecture and process diagrams but also is a great tool to use when starting a new project. It also covers risks, assumptions, stakeholders, decisions made etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other helpful tools and services
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://backstage.io/"&gt;Backstage&lt;/a&gt; - Service catalog and documentation. List API providers &amp;amp; Consumers &amp;amp; API's, list documentation, etc.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://swagger.io/"&gt;Swagger&lt;/a&gt; API Documentation Generation&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>documentation</category>
      <category>architecture</category>
    </item>
    <item>
      <title>About code comments</title>
      <dc:creator>Jaap Groeneveld</dc:creator>
      <pubDate>Thu, 27 Oct 2022 11:11:32 +0000</pubDate>
      <link>https://dev.to/jgroeneveld/about-code-comments-27ml</link>
      <guid>https://dev.to/jgroeneveld/about-code-comments-27ml</guid>
      <description>&lt;p&gt;Documentation and comments serve a similar purpose. It is about communicating to other developers now, to other developers in the future and also to yourself in the future.&lt;/p&gt;

&lt;p&gt;When I am talking about comments, I am not talking about comments used to document an API, functions, classes or modules. These are not really comments but rather &lt;strong&gt;inline documentation&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;In this Article I am talking about comments but also check out my article on documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comments
&lt;/h2&gt;

&lt;p&gt;Code comments have a really bad reputation and there is a good reason for it.&lt;br&gt;
Comments, just like documentation, &lt;em&gt;lie&lt;/em&gt; really quickly. Most often because they get outdated and are not updated. &lt;/p&gt;

&lt;p&gt;Often, they only state the obvious and this just clutters the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#loop through the values to be checked
while i &amp;lt;= maxNum:
    [...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For this reason, a lot of people have outlawed comments and will not comment their code at all. I understand this but still comments have a really good use and I like to make a case for using them sparingly. &lt;/p&gt;
&lt;h3&gt;
  
  
  Do not use comments if not necessary
&lt;/h3&gt;

&lt;p&gt;Sometimes better names make comments redundant and even improve the code because using the name always carries the meaning.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// price in cents&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;vs&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;priceInCents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Often, comments are used to structure code. For structure we have better tools that never lie.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;processInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="c1"&gt;// validate input  &lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input too short&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input too long&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;  

    &lt;span class="c1"&gt;// remove colors  &lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  

    &lt;span class="c1"&gt;// format result  &lt;/span&gt;
    &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If we just take the comments and make them into functions, the code is even more clear. You don't even have to look at the implementation details if you do not care at this point in time. It can also be used to contain ugly and unclear implementations (sometimes it is just not avoidable).&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;processInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nx"&gt;validateInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;removeColors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;formatResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;validateInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input too short&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input too long&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;removeColors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;formatResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The above code very clearly shows the 3 responsibilities of the &lt;code&gt;processInput&lt;/code&gt; function. validate, do and return formatted.  I do not want to make the point that you always have to structure your functions this way. Often, having the validation inside the "mother" function is a good idea to show exactly what is going on. But when you feel the urge to write a comment to structure code, think about using a function for structure.&lt;/p&gt;
&lt;h3&gt;
  
  
  Use comments to explain the why, the odd and the consequences
&lt;/h3&gt;

&lt;p&gt;What we, more often than not, can not illustrate with code structure is the &lt;em&gt;why&lt;/em&gt;, the &lt;em&gt;odd&lt;/em&gt; and the &lt;em&gt;consequences&lt;/em&gt; of something. Everytime something would surprise you in a year or a new developer, this is a very good reason to introduce a comment.&lt;/p&gt;
&lt;h4&gt;
  
  
  the why
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// we are moving between API's so we are calling new and old apis.&lt;/span&gt;
&lt;span class="nx"&gt;oldUsersApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updateData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;newUserApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updateData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  the odd
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// this is odd but the 3rd party client api enforces us to disconnect before we can connect&lt;/span&gt;
&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  the consequences
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// deleting the user will cascade deletion of all their data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  My guidelines for commenting code well
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Only comment the why and only if not obvious&lt;/li&gt;
&lt;li&gt;Always try to explain yourself in code first.&lt;/li&gt;
&lt;li&gt;Use as explanation of intent.&lt;/li&gt;
&lt;li&gt;Use as clarification of code.&lt;/li&gt;
&lt;li&gt;Use as warning of consequences.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;This article is extracted from a series of talks I gave.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.slideshare.net/JaapGroeneveld2/software-engineering-principlespdf" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--h6VCRrw6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.slidesharecdn.com/ss_thumbnails/softwareengineeringprinciples-221002112710-22c38088-thumbnail.jpg%3Fwidth%3D640%26amp%3Bheight%3D640%26amp%3Bfit%3Dbounds" height="360" class="m-0" width="640"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.slideshare.net/JaapGroeneveld2/software-engineering-principlespdf" rel="noopener noreferrer" class="c-link"&gt;
          Jaap Groeneveld - Software Engineering Principles
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          A talk about software engineering principles &amp;amp; clean code
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wh1pGnlg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://public.slidesharecdn.com/v2/assets/favicon-aeb517165ad56906594e.ico" width="32" height="32"&gt;
        slideshare.net
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>programming</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>About naming things</title>
      <dc:creator>Jaap Groeneveld</dc:creator>
      <pubDate>Sat, 01 Oct 2022 20:42:56 +0000</pubDate>
      <link>https://dev.to/jgroeneveld/about-naming-things-4cjk</link>
      <guid>https://dev.to/jgroeneveld/about-naming-things-4cjk</guid>
      <description>&lt;p&gt;There is this one quote that I hear often repeated.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are only two hard things in Computer Science: cache invalidation and naming things. -- Phil Karlton&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But is it really true? Yes, finding the perfect name for something is difficult. But let us take a step back and think about &lt;em&gt;why&lt;/em&gt; we are naming things and &lt;em&gt;why&lt;/em&gt; we are looking for good names.&lt;/p&gt;

&lt;h2&gt;
  
  
  Names are for humans
&lt;/h2&gt;

&lt;p&gt;The computer usually does not care about how things are named. Therefore the name is just for the human reading and modifying the code.&lt;br&gt;
Therefore, when choosing a name for something we have the goal to &lt;strong&gt;choose descriptive and unambiguous names&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;How do we do this?&lt;/p&gt;
&lt;h3&gt;
  
  
  Make names human
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use pronounceable names.&lt;/li&gt;
&lt;li&gt;Use searchable names.&lt;/li&gt;
&lt;li&gt;Avoid encodings. Don't append prefixes or type information.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having human-readable names make them easier to remember, easier to think about and also easier to discuss with a college.&lt;/p&gt;
&lt;h3&gt;
  
  
  One word per concept
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Make meaningful distinction.&lt;/li&gt;
&lt;li&gt;Having a clear terminology is key to not get confused.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Its more important to be consistent then to be perfect. The only thing that matters is that someone joining the project can learn what the concepts behind things are and that they can infer from one thing to another what it might be about.&lt;/p&gt;

&lt;p&gt;I do not care if the things executing your business logic are called Services, Interactors, Actions, Commands or Use Cases. Just stay with one name. The difference do not matter in the end. It just matters that everyone understands where to put and search for business logic.&lt;/p&gt;

&lt;p&gt;Another example. How to make clear that getting some data involves more than just returning it from memory? Choose a name like for example &lt;code&gt;fetch&lt;/code&gt;.  From now on, every method that gets data from a another API or the database is called &lt;code&gt;fetchX&lt;/code&gt; and everything that returns data from memory is called &lt;code&gt;getX&lt;/code&gt;. You have something that is being calculated based on input data? call it &lt;code&gt;calculateX&lt;/code&gt;&lt;br&gt;
Are these names 100% clear for everyone that is not working on this project? No, they are not. Are these perfect names for the concepts? No, they are not but as long as you keep the naming and meaning consistent, everybody working on the projet will understand and it wil help out.&lt;/p&gt;
&lt;h2&gt;
  
  
  Introducing redundant variables
&lt;/h2&gt;

&lt;p&gt;Often, introducing variables for returned data is technically not needed because you call or return the result directly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;StartTimer&lt;/span&gt;&lt;span class="p"&gt;()()&lt;/span&gt;
    &lt;span class="c"&gt;// [...]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here, we call the function StartTimer. It returns a function that does something and we call it on the exit of the function with &lt;code&gt;defer&lt;/code&gt;. What does the returned function do? We could guess. Maybe we know the &lt;code&gt;StartTimer&lt;/code&gt; function already so we know. We could go into &lt;code&gt;StartTimer&lt;/code&gt; and have a look or read the documentation. The Point is, you need to know or look it up.&lt;/p&gt;

&lt;p&gt;If you introduce a name for the returned function:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;stopTimer&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;StartTimer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;stopTimer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c"&gt;// [...]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This problem goes away. Everybody understands the resulting function instantly. No chance for confusion. Yes, we added 1 extra line, but that does not hurt anyone and we introduced a lot more clarity to our code. One less thing you have to know or look up.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using type aliases
&lt;/h2&gt;

&lt;p&gt;Some languages allow introducing type aliases (for example Kotlin, Typescript, Go), giving a existing type an additional name.&lt;/p&gt;

&lt;p&gt;We can leverage this to make our functions more clear. Often even leverage the type system to catch errors:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;getUserData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;companyID&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="c"&gt;// vs  &lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;CompanyID&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;UserID&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;getUserData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;companyID&lt;/span&gt; &lt;span class="n"&gt;CompanyID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt; &lt;span class="n"&gt;UserID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The benefits are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Impossible to "accidentally" assign something else&lt;/li&gt;
&lt;li&gt;Easy to find where User IDs are used (searchability through static analysis)&lt;/li&gt;
&lt;li&gt;Prevents positional problems in functions, it is not possible to accidentally mix up &lt;code&gt;companyID&lt;/code&gt;and &lt;code&gt;userID&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Depending on the language, they allow adding functions to the type, for example for validation or normalization.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;This article is extracted from a series of talks I gave.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.slideshare.net/JaapGroeneveld2/software-engineering-principlespdf" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--h6VCRrw6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.slidesharecdn.com/ss_thumbnails/softwareengineeringprinciples-221002112710-22c38088-thumbnail.jpg%3Fwidth%3D640%26amp%3Bheight%3D640%26amp%3Bfit%3Dbounds" height="360" class="m-0" width="640"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.slideshare.net/JaapGroeneveld2/software-engineering-principlespdf" rel="noopener noreferrer" class="c-link"&gt;
          Jaap Groeneveld - Software Engineering Principles
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          A talk about software engineering principles &amp;amp; clean code
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wh1pGnlg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://public.slidesharecdn.com/v2/assets/favicon-aeb517165ad56906594e.ico" width="32" height="32"&gt;
        slideshare.net
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>cleancode</category>
      <category>go</category>
    </item>
    <item>
      <title>Programming or Software Engineering?</title>
      <dc:creator>Jaap Groeneveld</dc:creator>
      <pubDate>Sat, 01 Oct 2022 10:33:00 +0000</pubDate>
      <link>https://dev.to/jgroeneveld/software-engineering-principles-1-4e61</link>
      <guid>https://dev.to/jgroeneveld/software-engineering-principles-1-4e61</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Software engineering is what happens to programming when you add time and other programmers. - Russ Cox&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Coding something from scratch is (usually) easy. Getting things to work is (usually) easy. Things get complicated when you think about the past, the future and other people.&lt;/p&gt;

&lt;h3&gt;
  
  
  Software Engineering deals with the challenges of
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Communication between people&lt;/li&gt;
&lt;li&gt;Communication over time&lt;/li&gt;
&lt;li&gt;Changing requirements&lt;/li&gt;
&lt;li&gt;Taming complexity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Clean code is more about humans than its about tech.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why invest in clean code?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Minimizes time spend on reading and understanding&lt;/li&gt;
&lt;li&gt;Easier to grow in the future&lt;/li&gt;
&lt;li&gt;Less hunting for bugs&lt;/li&gt;
&lt;li&gt;Easier onboarding.&lt;/li&gt;
&lt;li&gt;=&amp;gt; Messy code is &lt;strong&gt;Technical debt&lt;/strong&gt;. You will pay for it down the road.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Messy code has the uncanny ability to slow down any developer and make his work much harder&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bad Code smells
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://en.wikipedia.org/wiki/Code_smell"&gt;code smell&lt;/a&gt; is any characteristic in the source code of a program that possibly indicates a deeper problem.&lt;/p&gt;

&lt;p&gt;Here is a list of characteristics of a codebase that might lead you to think there is time to change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rigidity&lt;/strong&gt;. The software is difficult to change. A small change causes a cascade of subsequent changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fragility&lt;/strong&gt;. The software breaks in many places due to a single change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Immobility&lt;/strong&gt;. You cannot reuse parts of the code in other projects because of involved risks and high effort.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Opacity&lt;/strong&gt;. The code is hard to understand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Needless Complexity&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Needless Repetition&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Principles to prevent bad code
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Keep it simple, stupid (KISS)&lt;/strong&gt; and &lt;strong&gt;Clear is better than clever.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Writing clever code feels good. You achieved something. But more often than not, clever code increases the &lt;em&gt;opacity&lt;/em&gt; of the code. If another developer has to stop at a piece of code and has to understand it because it is not communicating clearly what is going on, it either is a very complex matter or the code is more complex than necessary.&lt;/p&gt;

&lt;p&gt;Lets take this snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;myValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;myValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;What is it doing? It reduces the array containing colors by applying a function that is calling replace on myValue for the color it is iterating over and replaces the color with an empty string. So, after understanding that, what it is doing is removing all occurances of the colors in the array from myValue.&lt;/p&gt;

&lt;p&gt;The following snippet is simpler and understood instantly. Yes, it is repeating code. So what? In this case, it does not matter.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;myValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;You aren’t gonna need it (YAGNI)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Do not build things that you think you might need in the future. It overcomplicates the code and experience shows that often things will not be build in the future. Requirements and priorities change. The understanding of the problem will change. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Premature Optimization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The same is true for optimization. Of course it is fine to optimizate code when it does not cost anything. If you know your code is faster if you use a Hashmap and access directly instead of using a List, do it. Writing it costs nothing. But starting out writing complicated solutions to optimize a request by 100ms is not the right way. Only optimize what is actually a problem and only as soon as you know it is a problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't repeat yourself (DRY)&lt;/strong&gt;, single source of truth. &lt;/p&gt;

&lt;p&gt;This is often misunderstood as not having the same lines of code in the program multiple times. &lt;em&gt;Do not repeat the same characters&lt;/em&gt;. But this is actually not the right way to interpret the DRY principle. &lt;strong&gt;Don't confuse syntactic and semantic dry-ness&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;DRY is about not repeating the same business logic in multiple places. There should be only one place in the program that describes how a business process is happening. This is about avoiding magic numbers, avoiding having the calculation of number of posts a user has in multiple places. The reason behind this is that when you have to change the program, you will probably forget to change all occurances of the logic and the number of posts will diverge.&lt;/p&gt;

&lt;p&gt;If the code is simple it might be better for clarity to actually copy it. Do not overstructure things that don't matter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Practice consistency.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Keep your code consistent. The way you code, the way things are structured helps you and other developers. Onboarding will be easier. Humans are great at extracting systematic structure but are really bad at remembering all the special cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep the tests clean.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you let the tests rot, then your code will rot too.&lt;/em&gt;&lt;br&gt;
Tests are code too. You will have to maintain them just like your production code, so treat them like production code. Introduce abstractions, stay DRY, have a high level of quality. Tests are often the best documentation you have, so clarity is extremly important. Make it very obvious what you are actually testing and hide the details. You will thank yourself soon. In my experience, most frustrations during development come from a bad test base.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prepare for change&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All software projects I worked on had in common that they never have been finished. There is always change involved. Therefor it is very important to &lt;em&gt;always ask how will this code behave if X changes (but keep YAGNI in mind)&lt;/em&gt;. If you keep the code somewhat flexible without over-engineering, you will win the game of software development. This is more art then science though and comes with experience. Also, you will be wrong and that is fine!&lt;/p&gt;



&lt;p&gt;This article is extracted from a series of talks I gave.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.slideshare.net/JaapGroeneveld2/software-engineering-principlespdf" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--h6VCRrw6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.slidesharecdn.com/ss_thumbnails/softwareengineeringprinciples-221002112710-22c38088-thumbnail.jpg%3Fwidth%3D640%26amp%3Bheight%3D640%26amp%3Bfit%3Dbounds" height="360" class="m-0" width="640"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.slideshare.net/JaapGroeneveld2/software-engineering-principlespdf" rel="noopener noreferrer" class="c-link"&gt;
          Jaap Groeneveld - Software Engineering Principles
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          A talk about software engineering principles &amp;amp; clean code
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wh1pGnlg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://public.slidesharecdn.com/v2/assets/favicon-aeb517165ad56906594e.ico" width="32" height="32"&gt;
        slideshare.net
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>softwareengineering</category>
      <category>cleancode</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to use minitest/mock to mock any instance</title>
      <dc:creator>Jaap Groeneveld</dc:creator>
      <pubDate>Wed, 02 Mar 2022 14:27:31 +0000</pubDate>
      <link>https://dev.to/jgroeneveld/how-to-use-minitestmock-to-mock-any-instance-3l61</link>
      <guid>https://dev.to/jgroeneveld/how-to-use-minitestmock-to-mock-any-instance-3l61</guid>
      <description>&lt;p&gt;&lt;code&gt;stub_any_instance&lt;/code&gt; is a very helpful utility in common mocking frameworks. minitest/mock does not provide this but its very simple to provide a similar effect.&lt;/p&gt;

&lt;p&gt;Mocking/Stubbing arbitrary instances of classes is very helpful in testing. In ruby it's easy to do this even without  using some sort of dependency injection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's do it!
&lt;/h2&gt;

&lt;p&gt;Lets assume we have a &lt;code&gt;Fetcher&lt;/code&gt; class that needs an instance of &lt;code&gt;ApiClient&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Fetcher&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_data&lt;/span&gt;
    &lt;span class="no"&gt;ApiClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"https://service.com/api/data"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We start by creating a mock and setting the relevant expectations like always.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;mock_api_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Minitest&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;mock_api_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;data: &lt;/span&gt;&lt;span class="s2"&gt;"return-data"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://service.com/api/data"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to make this mock the instance that some class would instantiate by stubbing the class method &lt;code&gt;.new&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;ApiClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:new&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_api_client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Fetcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch_data&lt;/span&gt;
  &lt;span class="n"&gt;assert_equal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;data: &lt;/span&gt;&lt;span class="s2"&gt;"return-data"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mock/stub combination would be active during the duration of the block.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>testing</category>
    </item>
    <item>
      <title>How to run rails tests in Visual Studio Code</title>
      <dc:creator>Jaap Groeneveld</dc:creator>
      <pubDate>Wed, 02 Mar 2022 14:27:22 +0000</pubDate>
      <link>https://dev.to/jgroeneveld/how-to-run-rails-tests-in-visual-studio-code-10be</link>
      <guid>https://dev.to/jgroeneveld/how-to-run-rails-tests-in-visual-studio-code-10be</guid>
      <description>&lt;p&gt;Visual Studio is great. It's very slim and quite fast, at least when updated to the M1 version.&lt;br&gt;
The testing support for rails seems to be quite outdated. There is a plugin &lt;a href="https://marketplace.visualstudio.com/items?itemName=connorshea.vscode-ruby-test-adapter"&gt;Ruby Test Explorer&lt;/a&gt; but it looks like it needs updating for using the new rails test runner &lt;code&gt;rails test&lt;/code&gt;. In the end, it's quite simple to actually run tests on your own and have 100% control over it. This will also allow you to rerun the last test, which is a critical productivity feature.&lt;/p&gt;
&lt;h2&gt;
  
  
  What you will get
&lt;/h2&gt;

&lt;p&gt;With the method I show here, you can customise your test running as you wish. In the end, you will have the following shortcuts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;run all tests&lt;/strong&gt;: ctrl+t ctrl+a  (&lt;em&gt;bin/rails test&lt;/em&gt;)&lt;br&gt;
&lt;strong&gt;run all tests in current file&lt;/strong&gt;: ctrl+t ctrl+f  (&lt;em&gt;bin/rails test {file}&lt;/em&gt;)&lt;br&gt;
&lt;strong&gt;run test under cursor&lt;/strong&gt;: ctrl+t ctrl+l (&lt;em&gt;bin/rails test {file:line}&lt;/em&gt;)&lt;br&gt;
&lt;strong&gt;rerun last test&lt;/strong&gt;: ctrl+t ctrl+t&lt;/p&gt;
&lt;h2&gt;
  
  
  The method
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Create a custom script
&lt;/h3&gt;

&lt;p&gt;To gain the ability to rerun tests, we have to somehow store what we already ran. I am sure, there is an easier way within VSCode, but this method works for sure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a file &lt;code&gt;bin/editor-test&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;touch bin/editor-test &amp;amp;&amp;amp; chmod +x bin/editor-test&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add the following script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="c"&gt;# used to run tests with editor and saving the last run so we can repeat.&lt;/span&gt;
&lt;span class="c"&gt;# for each test run it will save the last args in "tmp/editor-test-last-args".&lt;/span&gt;
&lt;span class="c"&gt;# usage&lt;/span&gt;
&lt;span class="c"&gt;# run file:&lt;/span&gt;
&lt;span class="c"&gt;#   bin/editor-test some_file.rb:12&lt;/span&gt;
&lt;span class="c"&gt;# run all:&lt;/span&gt;
&lt;span class="c"&gt;#   bin/editor-test&lt;/span&gt;
&lt;span class="c"&gt;# run last:&lt;/span&gt;
&lt;span class="c"&gt;#   bin/editor-test run-last&lt;/span&gt;

&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"run-last"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"tmp/editor-test-last-args"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;bin/rails &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&amp;lt;tmp/editor-test-last-args&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"No last test saved (file tmp/editor-test-last-args does not exist)"&lt;/span&gt;
  &lt;span class="k"&gt;fi
else
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; tmp/editor-test-last-args
  bin/rails &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This provides you will the possibility to rerun tests from the console by storing the last test args in &lt;em&gt;tmp/editor-test-last-args&lt;/em&gt;. Now, lets hook up vscode.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup custom VSCode Tasks
&lt;/h3&gt;

&lt;p&gt;This is a per-project task file, so you could customize this per project.&lt;/p&gt;

&lt;p&gt;Run the vscode command (cmd+shift p) "Tasks: Configure Task" and configure the following tasks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tasks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"repeat last test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bin/editor-test run-last"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"problemMatcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"presentation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"clear"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"launch tests for project"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bin/editor-test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"problemMatcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"presentation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"clear"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"launch tests for current file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bin/editor-test ${file}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"problemMatcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"presentation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"clear"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"launch test for current line"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bin/editor-test ${file}:${lineNumber}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"problemMatcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"presentation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"clear"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setup keybindings
&lt;/h3&gt;

&lt;p&gt;To have perfect productivity, lets create some keybindings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ctrl+t ctrl+a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.action.tasks.runTask"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"launch tests for project"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ctrl+t ctrl+f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.action.tasks.runTask"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"launch tests for current file"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ctrl+t ctrl+l"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.action.tasks.runTask"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"launch test for current line"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ctrl+t ctrl+t"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workbench.action.tasks.runTask"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"repeat last test"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There you have it. Super simple, easy to customise test running. This approach will work with every technology, not only rails and no need for plugins.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
