<?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: Luís Soares</title>
    <description>The latest articles on DEV Community by Luís Soares (@lsoares).</description>
    <link>https://dev.to/lsoares</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%2F393589%2F053768d8-675b-4be2-b963-8cf1f50faf7e.jpg</url>
      <title>DEV Community: Luís Soares</title>
      <link>https://dev.to/lsoares</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lsoares"/>
    <language>en</language>
    <item>
      <title>Unit testing a gateway with Javalin</title>
      <dc:creator>Luís Soares</dc:creator>
      <pubDate>Fri, 05 Jun 2020 15:01:01 +0000</pubDate>
      <link>https://dev.to/lsoares/unit-testing-a-gateway-with-javalin-5463</link>
      <guid>https://dev.to/lsoares/unit-testing-a-gateway-with-javalin-5463</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/@lsoares/unit-testing-a-gateway-with-javalin-24e3b7e88ef2?source=rss-54ea764ff544------2"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_cKZ6ePI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1260/1%2A4kX92_Lwp-E6xq7TFuO8zw.png" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Kotlin/Java, how would you test that your app is properly consuming an external REST API?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@lsoares/unit-testing-a-gateway-with-javalin-24e3b7e88ef2?source=rss-54ea764ff544------2"&gt;Continue reading on Medium »&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javalin</category>
      <category>mockserver</category>
      <category>unittesting</category>
      <category>wiremock</category>
    </item>
    <item>
      <title>Anti-patterns of automated software testing</title>
      <dc:creator>Luís Soares</dc:creator>
      <pubDate>Sun, 24 May 2020 13:06:35 +0000</pubDate>
      <link>https://dev.to/lsoares/anti-patterns-of-automated-software-testing-576d</link>
      <guid>https://dev.to/lsoares/anti-patterns-of-automated-software-testing-576d</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/swlh/anti-patterns-of-automated-software-testing-b396283a4cb6"&gt;Sometimes it’s easier to learn from ‘what not to do’ rather than from ‘what to do’. So I wrote this article about stuff you should avoid in your tests. Hope you enjoy.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>antipatterns</category>
    </item>
    <item>
      <title>You should be using Value Objects</title>
      <dc:creator>Luís Soares</dc:creator>
      <pubDate>Wed, 13 May 2020 13:25:05 +0000</pubDate>
      <link>https://dev.to/lsoares/you-should-be-using-value-objects-1807</link>
      <guid>https://dev.to/lsoares/you-should-be-using-value-objects-1807</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/swlh/you-should-be-using-value-objects-568b19b1df8d?source=rss-54ea764ff544------2"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s5Wet6pR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2600/1%2AD8VygRHScNSidulpPqq1MQ.jpeg" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Value objects are one of the building blocks of domain-driven design. Let’s see the value they bring.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/swlh/you-should-be-using-value-objects-568b19b1df8d?source=rss-54ea764ff544------2"&gt;Continue reading on The Startup »&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>cleanarchitecture</category>
      <category>kotlin</category>
      <category>valueobjects</category>
    </item>
    <item>
      <title>Anti-patterns of automated software testing</title>
      <dc:creator>Luís Soares</dc:creator>
      <pubDate>Thu, 16 Apr 2020 17:08:30 +0000</pubDate>
      <link>https://dev.to/lsoares/anti-patterns-of-automated-software-testing-1iib</link>
      <guid>https://dev.to/lsoares/anti-patterns-of-automated-software-testing-1iib</guid>
      <description>&lt;h4&gt;
  
  
  Sometimes it’s easier to learn from ‘&lt;em&gt;what not to do’&lt;/em&gt; rather than from ‘&lt;em&gt;what to do’&lt;/em&gt;. Anti-patter_ns represent c_ommon bad practices, &lt;a href="https://en.wikipedia.org/wiki/Code_smell"&gt;code smells&lt;/a&gt; and pitfalls, in this case, when creating automated tests. You should learn them so that you can spot them.
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q02lXlbD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AlgpPDW08K5GQnD1IW12MiQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q02lXlbD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AlgpPDW08K5GQnD1IW12MiQ.jpeg" width="800" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Creating patterns to describe something creates nomenclature. Once you have a name for something, it’s easier to recognize when you see it again.&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.goodreads.com/book/show/3411606-the-productive-programmer"&gt;The Productive Programmer, Neal Ford&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;📝 &lt;em&gt;The list applies regardless of the language/runtime.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  No clear structure within the test
&lt;/h3&gt;

&lt;p&gt;Not following an expectable structure in each test makes it hard to maintain it. &lt;strong&gt;Tests are living code documentation&lt;/strong&gt; , so everyone should be able to quickly read/change them.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://wiki.c2.com/?ArrangeActAssert"&gt;Arrange, Act, Assert&lt;/a&gt; is a pattern for structuring code in test methods. Basically, you &lt;strong&gt;organize your code in phases for the sake of clarity&lt;/strong&gt;. It can be mapped to &lt;em&gt;Setup, Exercise, Verify, Teardown&lt;/em&gt; in the &lt;a href="https://thoughtbot.com/blog/four-phase-test"&gt;four-phase test&lt;/a&gt; pattern and to &lt;a href="https://www.agilealliance.org/glossary/gwt/"&gt;&lt;em&gt;Given, When, Then&lt;/em&gt;&lt;/a&gt; in &lt;a href="https://en.wikipedia.org/wiki/Behavior-driven_development"&gt;BDD&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Arrange&lt;/strong&gt; /&lt;em&gt;Given&lt;/em&gt;/&lt;em&gt;Setup&lt;/em&gt;: initialization of the SUT (&lt;a href="https://en.wikipedia.org/wiki/System_under_test"&gt;&lt;em&gt;system under test&lt;/em&gt;&lt;/a&gt;&lt;em&gt;,&lt;/em&gt; whatever you’re testing) and other dependencies like mocks and fakes;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Act&lt;/strong&gt; /&lt;em&gt;When&lt;/em&gt;/&lt;em&gt;Exercise&lt;/em&gt;: the call to the method being tested — ideally a single-liner;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assert&lt;/strong&gt; /&lt;em&gt;Then&lt;/em&gt;/&lt;em&gt;Verify&lt;/em&gt;: assertions of the output or verifications of calls made;&lt;/li&gt;
&lt;li&gt;(Optional) Teardown: if there are resources to be freed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rSRSQB-x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2ARGFt7NBhOLdnnxKJX24jtw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rSRSQB-x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2ARGFt7NBhOLdnnxKJX24jtw.png" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a consequence, I usually &lt;strong&gt;have 3 phases visually separated by empty lines&lt;/strong&gt;. If you reply with: “But I have lots of code in my test! I need more than 2 empty lines!”, I’d say “that’s likely a design smell”: you might be testing a &lt;a href="https://en.wikipedia.org/wiki/God_object"&gt;&lt;em&gt;god object&lt;/em&gt;&lt;/a&gt; which you need to split, you might need to create a “local &lt;a href="https://en.wikipedia.org/wiki/Domain-specific_language"&gt;DSL&lt;/a&gt;” — high-level helper methods, or you could consider extracting the common setup and teardown elsewhere.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  TL;DR
&lt;/h4&gt;

&lt;p&gt;👎 &lt;em&gt;Having no consistent test structure, harming readability;&lt;/em&gt;&lt;br&gt;&lt;br&gt;
👍 &lt;em&gt;Applying Arrange/Act/Assert consistently, visually separated by newlines.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Refactoring when adding a feature
&lt;/h3&gt;

&lt;p&gt;Adding a new feature bears some risk and stress, even when you do TDD. So, why would you make things worse by fixing &lt;em&gt;this&lt;/em&gt; or improving &lt;em&gt;that&lt;/em&gt; simultaneously? This can lead to an explosion of untested cases and hard-to-track down bugs, but the worse is the anxiety it brings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NhzZ1Wl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/220/0%2AANqaoJ-2KuuqQ6ul" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NhzZ1Wl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/220/0%2AANqaoJ-2KuuqQ6ul" width="220" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the bottom line is: &lt;strong&gt;relax and focus on the feature at hand&lt;/strong&gt;. It’s true that you should leave the code in a better state than you found it — &lt;a href="https://martinfowler.com/bliki/OpportunisticRefactoring.html"&gt;&lt;em&gt;opportunistic refactoring&lt;/em&gt;&lt;/a&gt;), but please do it &lt;strong&gt;before&lt;/strong&gt; (if it helps the feature) or &lt;strong&gt;after&lt;/strong&gt; the feature. If it’s after, consider writing the refactoring ideas in a sheet of paper, as TODOs in the code, in tasks/stories in your tracker, to reduce the “fear of forgetting”.&lt;/p&gt;
&lt;h4&gt;
  
  
  TL;DR
&lt;/h4&gt;

&lt;p&gt;👎 &lt;em&gt;Improving things you step into, while you create a feature;&lt;/em&gt;&lt;br&gt;&lt;br&gt;
👍 &lt;em&gt;Doing the refactor before the feature or noting it down for later.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Changing implementation to make tests possible
&lt;/h3&gt;

&lt;p&gt;I recently read &lt;a href="https://www.goodreads.com/book/show/387190.Test_Driven_Development"&gt;&lt;em&gt;Test-Driven Development by Example by Kent Beck&lt;/em&gt;&lt;/a&gt; and I was a bit disappointed that he was teaching why and how to test private methods (using Java reflection). Later, I think he made up his mind:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1258954349314625538-313" src="https://platform.twitter.com/embed/Tweet.html?id=1258954349314625538"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1258954349314625538-313');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1258954349314625538&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;I never faced a situation where I needed to test private methods; it always feels like a big red flag.&lt;/p&gt;

&lt;p&gt;In “&lt;em&gt;unit test&lt;/em&gt;”, the word unit represents a piece of a public interface. Private methods are an implementation detail — auxiliaries of public methods — and are to be tested indirectly through them! There’s probably no exception to this rule. If you find it hard to test all private method possibilities, then maybe you have a &lt;em&gt;god object&lt;/em&gt; that you should split into multiple components.&lt;/p&gt;

&lt;p&gt;“Ah.. but I can make the method public!”. That’s even worse… &lt;strong&gt;you should not change the code implementation just for making testing possible&lt;/strong&gt;. Testing private methods is just an example, but there’s much more. This usually means you’re doing something wrong.&lt;/p&gt;

&lt;h4&gt;
  
  
  TL;DR
&lt;/h4&gt;

&lt;p&gt;👎 &lt;em&gt;Changing the implementation solely for the sake of making testing possible;&lt;/em&gt;&lt;br&gt;&lt;br&gt;
👍 &lt;em&gt;Be hinted to redesign the implementation code because the tests are hard to write.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The test is hard to write
&lt;/h3&gt;

&lt;p&gt;A common reason for a &lt;em&gt;hard-to-write-test&lt;/em&gt; is that you’re new to the problem and need to get more familiar with it. In that case, try explaining the problem to someone (or even &lt;a href="https://en.wikipedia.org/wiki/Rubber_duck_debugging"&gt;to a duck&lt;/a&gt;) or take a break to get your ideas organized.&lt;/p&gt;

&lt;p&gt;If you’re using TDD, you can try the &lt;em&gt;starter test&lt;/em&gt; (a really basic one) or the &lt;em&gt;explanatory test&lt;/em&gt; (the one you’d use to explain to someone).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DKeZNp7k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2ABve2haCED7kVOFW8" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DKeZNp7k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2ABve2haCED7kVOFW8" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, if the test ends up being too complicated, too long (e.g. lots of setup code), or it feels like a hack, probably there’s a better way. A good way of finding if your code is too complicated is the need to add comments to explain it: &lt;strong&gt;code should speak for itself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Generally speaking, &lt;strong&gt;tests that are hard to write or understand are a symptom of bad code design.&lt;/strong&gt; Tests are a client of the implementation code — when tests of a component are hard to write, you can extrapolate how hard is to use that component.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If it’s hard to write a test, it’s a signal that you have a design problem, not a testing problem. Loosely coupled, highly cohesive code is easy to test.&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.goodreads.com/book/show/67833.Extreme_Programming_Explained"&gt;Extreme Programming Explained, Kent Beck&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In that case, you should consider if the implementation code needs a refactor to make it easier to test and maintain. The solution may be &lt;em&gt;divide and conquer&lt;/em&gt;, as your &lt;a href="https://en.wikipedia.org/wiki/System_under_test"&gt;SUT&lt;/a&gt; may be a &lt;a href="https://en.wikipedia.org/wiki/God_object"&gt;&lt;em&gt;god object&lt;/em&gt;&lt;/a&gt;. It may also be wise to try to use more adequate &lt;a href="https://en.wikipedia.org/wiki/Software_design_pattern"&gt;&lt;em&gt;software design patterns&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  TL;DR
&lt;/h4&gt;

&lt;p&gt;👎 &lt;em&gt;Making hacks that need an explanation or having complicated setups, so that a scenario can be tested;&lt;/em&gt;&lt;br&gt;&lt;br&gt;
👍 &lt;em&gt;Considering a code redesign when a test is hard to write.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Optimizing DRY
&lt;/h3&gt;

&lt;p&gt;This is the most common mistake I encounter. People see a repeated value and they will immediately create a variable for it. That’s not an early optimization: it’s just making documentation (tests) harder to read.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In tests, some repetition is bearable for the sake of clarity.&lt;/strong&gt; This is one of the few differences between test code and implementation code. &lt;strong&gt;Test code&lt;/strong&gt; ≠ &lt;strong&gt;implementation code. Tests should more&lt;/strong&gt; &lt;a href="https://testing.googleblog.com/2019/12/testing-on-toilet-tests-too-dry-make.html"&gt;&lt;strong&gt;DAMP (Descriptive And Meaningful Phrases)&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;than&lt;/strong&gt; &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;&lt;strong&gt;DRY&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;(Don’t Repeat Yourself).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On a related note, I hate when I have to scroll up and down or open multiple files to understand a single test. A typical case is a folder full of sample data that is used everywhere. Sometimes it’s fine to leave repeated setup and teardown in all tests in all cases. &lt;strong&gt;Tests should be self-evident&lt;/strong&gt;. Tests are documentation. Therefore, I’d prefer to read tests &lt;em&gt;top-down&lt;/em&gt;, like in a user manual (imagine if you had to swap pages multiple times when reading your washing machine manual…). This is also a callout to &lt;strong&gt;avoid using globals in tests&lt;/strong&gt; (i.e., class or file globals).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iQ8KSz4b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AKoAhqPj_pJEh63J4Uve4Lw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iQ8KSz4b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AKoAhqPj_pJEh63J4Uve4Lw.png" width="800" height="461"&gt;&lt;/a&gt;A very hard to read test; the more dependency arrows, the harder to read&lt;/p&gt;
&lt;h4&gt;
  
  
  TL;DR
&lt;/h4&gt;

&lt;p&gt;👎 &lt;em&gt;Pursuing&lt;/em&gt; &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;&lt;em&gt;DRY&lt;/em&gt;&lt;/a&gt;&lt;em&gt;ness by creating variables and functions in tests;&lt;/em&gt;&lt;br&gt;&lt;br&gt;
👍 &lt;em&gt;Starting with everything local and evident; break the rule only if it brings more value.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Very similar test cases
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Copy-pasting&lt;/em&gt; of more than one line of code should generally raise an alarm in your head. Well… it’s OK to do it just to make it work, but you should fix it later. It’s worse if you copy an entire test where only the initial values vary. This calls out loud to resort to &lt;em&gt;table-driven testing,&lt;/em&gt; also known as &lt;a href="https://en.wikipedia.org/wiki/Data-driven_testing"&gt;&lt;em&gt;data-driven testing&lt;/em&gt;&lt;/a&gt;. &lt;strong&gt;Table-driven testing allows running the same test multiple times, one per set of inputs and expected output&lt;/strong&gt; (or other consequences).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Input | Output    
   -----------------
       1 | 1         
       2 | 2         
       3 | Fizz      
       5 | Buzz      
      15 | Fizz Buzz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📝 &lt;em&gt;It’s not my goal to teach you here about it, so I’ll leave a few links:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests"&gt;&lt;em&gt;JUnit parameterized tests&lt;/em&gt;&lt;/a&gt; &lt;em&gt;(Java, Kotlin);&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/nunit/docs/wiki/Parameterized-Tests"&gt;&lt;em&gt;NUnit parameterized tests&lt;/em&gt;&lt;/a&gt;_ (C#);_&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jestjs.io/docs/en/api#testeachtablename-fn-timeout"&gt;&lt;em&gt;Jest each method&lt;/em&gt;&lt;/a&gt; &lt;em&gt;(JavaScript, TypeScript);&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://relishapp.com/rspec/rspec-core/docs/example-groups/shared-examples"&gt;&lt;em&gt;RSpec shared_examples&lt;/em&gt;&lt;/a&gt; &lt;em&gt;(Ruby);&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@jmdalmeida/table-driven-testing-b07ea4be21f4"&gt;&lt;em&gt;Table-driven testing in Go, Python, and PHP&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bottom line: &lt;strong&gt;use table-driven testing if you keep duplicating the same test with different data&lt;/strong&gt;. As advantages, you’ll have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Less code because you don’t repeat very similar tests;&lt;/li&gt;
&lt;li&gt;Easy comparison of test cases;&lt;/li&gt;
&lt;li&gt;Quick ability to add or remove test cases;&lt;/li&gt;
&lt;li&gt;Better documentation, because positive, negative, and edge cases are explicit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⚠️ &lt;em&gt;In table-driven testing,&lt;/em&gt; &lt;strong&gt;&lt;em&gt;do not mix the happy path with the error scenarios&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;. These should be kept apart for clarity reasons.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Finally, consider the trade-off you’re making, given that the tests become less &lt;a href="https://stackoverflow.com/questions/6453235/what-does-damp-not-dry-mean-when-talking-about-unit-tests"&gt;DAMP&lt;/a&gt; when applying this technique.&lt;/p&gt;

&lt;h4&gt;
  
  
  TL;DR
&lt;/h4&gt;

&lt;p&gt;👎 &lt;em&gt;Copy-pasting many similar chunks of test code to add new test cases;&lt;/em&gt;&lt;br&gt;&lt;br&gt;
👍 &lt;em&gt;Learning how to do table-driven testing with your language/library.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Testing everything
&lt;/h3&gt;

&lt;p&gt;According to the &lt;a href="https://en.wikipedia.org/wiki/Diminishing_returns"&gt;law of diminishing returns&lt;/a&gt;, there’s a point where the cost to add tests does not compensate for its benefits anymore.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5sMZZoBL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/301/1%2A9gw9caDNRCWuXo-gGSMGpQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5sMZZoBL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/301/1%2A9gw9caDNRCWuXo-gGSMGpQ.png" width="301" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Applied to automated testing, &lt;strong&gt;not every possibility needs to be tested&lt;/strong&gt;. Some situations can be left untested:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;some are too rare or exotic;&lt;/li&gt;
&lt;li&gt;others will quickly arise when using the software (e.g. missing env. var.)&lt;/li&gt;
&lt;li&gt;many won’t have a big impact if they fail (e.g. CSS styling, animations).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How to determine if a certain test is worth it? You should roughly calculate its &lt;a href="https://en.wikipedia.org/wiki/Benefit%E2%80%93cost_ratio"&gt;benefit-cost ratio&lt;/a&gt;: is &lt;strong&gt;&lt;em&gt;benefit/cost&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;≥ 1&lt;/em&gt;? Within &lt;em&gt;benefit&lt;/em&gt; consider the permanent prevention against the problem (&lt;a href="https://www.sasworkshops.com/unit-testing-as-a-safety-net/"&gt;&lt;em&gt;testing as a safety net&lt;/em&gt;&lt;/a&gt;). For the &lt;em&gt;cost&lt;/em&gt;, take into account the effort to simulate the test scenario and the resources (lines of code to maintain, time to run) it will require from thereon.&lt;/p&gt;
&lt;h4&gt;
  
  
  TL;DR
&lt;/h4&gt;

&lt;p&gt;👎 &lt;em&gt;Religiously trying to test everything;&lt;/em&gt;&lt;br&gt;&lt;br&gt;
👍 &lt;em&gt;Analyzing the cost-ratio test by test, to decide if it’s worth it.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Other smells and anti-patterns
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Using the word “and” when describing a test&lt;/strong&gt; : this hints that you should split the test in two, each asserting/verifying different things (check code example above);&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing lots of combinations&lt;/strong&gt; (&lt;a href="https://www.freecodecamp.org/news/combinatorics-handle-with-care-ed808b48e5dd/"&gt;&lt;em&gt;combinatorial explosion&lt;/em&gt;&lt;/a&gt;): this is a smell that you have multiple components into one; the solution is to recognize them and slowly split them apart.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treating test code as a second class citizen&lt;/strong&gt; : test code is your safety net so take good care of it; most good code practices are transversal to any source code (e.g. avoid globals);&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not discarding a&lt;/strong&gt; &lt;a href="https://en.wikipedia.org/wiki/Spike_(software_development)"&gt;&lt;strong&gt;spike&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;’s code, especially when doing TDD&lt;/strong&gt; : a spike is a learning tool; its code should not be kept and evolve;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing business rules though UI&lt;/strong&gt; : business rules should be tested regardless of the UI being used. Of course, end-to-end testing is an exception;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quantity without diversity&lt;/strong&gt; : test cases should be different somehow — do not add cases for the sake of quantity; the same applies to test scenarios: they should vary;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/testdouble/contributing-tests/wiki/Don't-mock-what-you-don't-own"&gt;&lt;strong&gt;Mocking what you don’t own&lt;/strong&gt;&lt;/a&gt;: avoid leakage of libraries into your software (runtime or external); there are alternatives like wrappers and mock servers;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conditionals in tests&lt;/strong&gt; : having &lt;em&gt;“ifs”&lt;/em&gt; in tests is wrong; it’s proof that you need another test scenario;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overvaluing test coverage&lt;/strong&gt; : coverage shouldn’t be something you pursue just for the sake of it because you may be near 100% and still have crappy tests. Anyway, with TDD, coverage is almost an irrelevant concept.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Early optimization&lt;/strong&gt; : in TDD, always reduce the “distance” between a red (now) and a green state (future). Do the “&lt;em&gt;quick and dirty&lt;/em&gt;” implementation even if it means to &lt;em&gt;return a constant&lt;/em&gt; or do an ugly or slow implementation. Make it pass, then make it beautiful. The reason is not only psychological — it’s dopamine-freeing to see a green state — but it’s also about learning sooner. You learn, from the start, more about the problem and the solution (e.g. code design) if you make it pass first.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Final remarks
&lt;/h3&gt;

&lt;p&gt;One could notice that a lot of anti-patterns in tests can be attributed to an anti-pattern in implementation: &lt;a href="https://en.wikipedia.org/wiki/God_object"&gt;the &lt;em&gt;god object&lt;/em&gt;&lt;/a&gt;&lt;em&gt;:&lt;/em&gt; having huge test files, having long tests, a test being hard to write, among others are warning signs. That said, my advice is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write software in a &lt;em&gt;top-down&lt;/em&gt; approach&lt;/strong&gt; , so that you can more easily understand the “components below” deriving from the “ones above” (and you only implement what’s needed);&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recognize when you have multiple reasons to change&lt;/strong&gt; a component so you can split it (&lt;a href="https://en.wikipedia.org/wiki/Single-responsibility_principle"&gt;&lt;em&gt;single-responsibility principle&lt;/em&gt;&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bottom line: if it’s complicated, you’re doing it wrong. &lt;strong&gt;The ideal solution is usually simple; you just need to be persevering and iterate until you achieve it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The presented list was not supposed to be exhaustive since there are good resources out there (e.g. &lt;a href="https://stackoverflow.com/questions/333682/unit-testing-anti-patterns-catalogue"&gt;StackOverflow’s thread&lt;/a&gt;, &lt;a href="https://www.yegor256.com/2018/12/11/unit-testing-anti-patterns.html"&gt;Yegor Bugayenko’s list&lt;/a&gt;). &lt;a href="http://blog.codepipes.com/testing/software-testing-antipatterns.html"&gt;&lt;em&gt;Software Testing Anti-patterns&lt;/em&gt; by Kostis Kapelonis&lt;/a&gt; is a must-read. You can find good patterns in Part III of &lt;a href="https://www.goodreads.com/book/show/387190.Test_Driven_Development"&gt;&lt;em&gt;Test-Driven Development by Example&lt;/em&gt; by Kent Beck&lt;/a&gt;. Finally, watch &lt;a href="https://www.youtube.com/watch?v=EZ05e7EMOLM"&gt;TDD, Where Did It All Go Wrong by Ian Cooper&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/EZ05e7EMOLM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




</description>
      <category>goodpractices</category>
      <category>testing</category>
      <category>antipattern</category>
    </item>
    <item>
      <title>Our approach to quality in Volkswagen Software Dev Center Lisbon</title>
      <dc:creator>Luís Soares</dc:creator>
      <pubDate>Wed, 18 Sep 2019 11:24:31 +0000</pubDate>
      <link>https://dev.to/lsoares/our-approach-to-quality-in-volkswagen-software-dev-center-lisbon-141k</link>
      <guid>https://dev.to/lsoares/our-approach-to-quality-in-volkswagen-software-dev-center-lisbon-141k</guid>
      <description>&lt;h4&gt;
  
  
  Assuring quality on the demanding software products we build at Volkswagen SDC:LX is not easy. Saying we’re agile is not enough, so I’ll present the soft and hard factors that ensure the required standards are met.
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tRdml4jQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2A-Nrp3ycbKNGWZh2DnkgUEQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tRdml4jQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2A-Nrp3ycbKNGWZh2DnkgUEQ.jpeg" width="800" height="601"&gt;&lt;/a&gt;&lt;a href="https://www.vwds.pt/sdclx.html"&gt;Volkswagen SDC:LX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a disclaimer, this is solely my point of view.&lt;/p&gt;

&lt;h3&gt;
  
  
  Culture
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Team members are part of the hiring evaluation stages&lt;/strong&gt; , which greatly improves compatibility and ensures the culture and methodology continuity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Critical thinking&lt;/strong&gt; is highly appreciated and everyone is free to challenge what’s defined and the others (regardless of the role). This is supported by our non-judgmental environment.&lt;/li&gt;
&lt;li&gt;We rely on a scientific approach to problems by &lt;strong&gt;setting hypotheses and assumptions and seeking to confirm or disprove them&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team empowerment fosters ownership&lt;/strong&gt; : since the team is responsible for the product (building and operating it), everyone is more dedicated to it. We have a flat structure and teams are balanced (PMs, designers and developers) for autonomy reasons.&lt;/li&gt;
&lt;li&gt;Context switching is expensive, so &lt;strong&gt;focus&lt;/strong&gt; is essential to our way of working. For example, you only work in a single product at a time.&lt;/li&gt;
&lt;li&gt;Discussions of development good practices are welcomed, valued and common.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;We promote rotation&lt;/strong&gt; amongst teams and even offices (we run programs for the interchange of people between offices). This allows the sharing of ideas and solutions, to compare and learn, and to question the implemented habits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A feedback culture&lt;/strong&gt; promotes individual/team improvement (team, product and office retrospectives, individual feedback, etc.). Everyone reflects on it and gets continuously better.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparency&lt;/strong&gt; and &lt;strong&gt;happiness&lt;/strong&gt; are kept so everyone feels part of the office. Weekly office syncs are held with everyone and social events are regularly organized by the happiness team.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;culture of constant learning&lt;/strong&gt; is held. It’s common to share interesting articles and other web resources. We have a book library and free access to online courses. We organize, attend, and host events. We have internal weekly meetups where anyone can present something.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Practices
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Every potential product starts with a scoping meeting to define the boundaries of the problem to be tackled; this is followed by a discovery/framing phase to better understand the problem and validate if we should move on. If so, we do an inception to develop an &lt;a href="https://en.wikipedia.org/wiki/Minimum_viable_product"&gt;MVP&lt;/a&gt; so we can quickly test it within a real environment. This ensures we do the minimum to validate it quickly and get feedback as soon as possible (&lt;a href="https://en.wikipedia.org/wiki/Lean_software_development"&gt;lean development&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;A user-centric philosophy is followed. &lt;strong&gt;Every feature in the backlog is written in a clear way that brings&lt;/strong&gt; &lt;a href="https://www.goodreads.com/book/show/13436116-lean-ux"&gt;&lt;strong&gt;value for the user&lt;/strong&gt;&lt;/a&gt;; this explains you won’t find stories split by backend and frontend — we always split “vertically”.&lt;/li&gt;
&lt;li&gt;We do small experiments within the teams and the office, by trying new things that could improve our work (e.g. regarding our practices). Everyone is free to suggest improvements.&lt;/li&gt;
&lt;li&gt;Most documents are produced in a collaborative way and are quickly iterated. This is achieved by the use of &lt;strong&gt;collaborative tools&lt;/strong&gt; like digital whiteboards, word processors, issue trackers, etc.&lt;/li&gt;
&lt;li&gt;By constantly &lt;a href="https://dev.to/lsoares/emotions-management-when-pair-programming-18b8-temp-slug-3294279"&gt;pairing&lt;/a&gt;, we are running &lt;strong&gt;continuous live code reviews&lt;/strong&gt; , as opposed to decoupled/async code reviews; the feedback is immediate and contextualized, thus more valuable.&lt;/li&gt;
&lt;li&gt;Pairing guarantees &lt;strong&gt;knowledge sharing&lt;/strong&gt; because of its nature and also due to the daily pair rotations. As a consequence, all the team knows the codebase/architecture and it’s less dependent on individuals (‘no heroes’ culture). Pairing also happens with designers and product managers (PMs) which &lt;strong&gt;promotes know-how sharing amongst roles&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decisions are debated&lt;/strong&gt; which improves their quality. By default, they are done as a pair but if they feel needed, they’ll reach out the team or even other teams for discussion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Besides all the automatic quality checks, manual testing&lt;/strong&gt; is done by the team, per feature: developers validate the stories and PMs/designers accept them in a near-production environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuous improvement&lt;/strong&gt; happens in a codebase level. Refactorings are usually done when working on a story. Other refactors and tech debts are tracked so they are not lost (any team member can add them to the backlog). Keeping the code maintainable is a core value.&lt;/li&gt;
&lt;li&gt;Voluntary facilitators &lt;strong&gt;improve the quality and outcome of meetings&lt;/strong&gt;. They make sure the meeting is time-boxed and focused. We start by diverging and converge in the end.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test Driven Development&lt;/strong&gt; ( &lt;strong&gt;TDD&lt;/strong&gt; ) ensures a better software design and code gets documented and tested as a consequence. Since we focus on the behavior (BDD), the implementation derives directly from the user requirements.&lt;/li&gt;
&lt;li&gt;The whole team (and possibly other people) is frequently invited to &lt;strong&gt;design sessions&lt;/strong&gt; (e.g. to design a feature) organized by the designers. This feedback is taken into consideration and the designs are iterated.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Technology
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Developers are full-stack&lt;/strong&gt; which promotes feature know-how/ownership from top to bottom, start to end, and a skill set across multiple technologies.&lt;/li&gt;
&lt;li&gt;There’s a general passion for technology (that’s almost a requirement) but we have methods to make sure it doesn’t bias our decisions so we keep our focus on the users.&lt;/li&gt;
&lt;li&gt;The team is free to choose the languages, runtimes, and frameworks and tries to make informed decisions when picking them.&lt;/li&gt;
&lt;li&gt;For each language and runtime, we choose and set up our IDEs, editors, utilities, and plugins so that we get code warnings, tips, validations, autocomplete, etc. These are kept always up-to-date.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attention to warnings&lt;/strong&gt; : every warning in the code editor, logs, or other, is a symptom of something, so we always try to fix them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static code analysis&lt;/strong&gt; : the code is automatically analyzed regarding code conventions and other concerns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versions checking&lt;/strong&gt; : we make sure that the latest versions of the runtimes, frameworks, and libraries are used. This reduces the number of bugs such as security fixes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unit testing&lt;/strong&gt; , &lt;strong&gt;integration testing&lt;/strong&gt; , and &lt;strong&gt;end-to-end (E2E) testing&lt;/strong&gt; are done by default for all software components, testing multiple layers and combinations. Since those are developed in TDD, we feel really safe when refactoring or adding features. All the test suites are run per code push.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuous Delivery/Integration (CD/CI)&lt;/strong&gt;: the features are pushed to the master branch (trunk based development) and automatically deployed to pre-production. That way, we don’t have to keep track of lots of feature branches and releases. The CI pipeline is constantly visible on a TV.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Different environments&lt;/strong&gt; in the CI before reaching production: if any test fails, the code is not deployed. This also gives more opportunities to find problems before production since all team members, directors and POs use them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://vwds.pt/sdclx.html"&gt;More info&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>codequality</category>
      <category>qualityassurance</category>
    </item>
    <item>
      <title>Emotions management when pair programming</title>
      <dc:creator>Luís Soares</dc:creator>
      <pubDate>Tue, 06 Nov 2018 15:42:32 +0000</pubDate>
      <link>https://dev.to/lsoares/emotions-management-when-pair-programming-14m8</link>
      <guid>https://dev.to/lsoares/emotions-management-when-pair-programming-14m8</guid>
      <description>&lt;h3&gt;
  
  
  Emotion management when pair programming
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Pairing is not just two people working together. Mutual respect, emotion management and other psychological factors come into play. Doing it well takes time, so be patient, repeat it properly until you can reach the “&lt;a href="http://www.sportspsychologybasketball.com/2012/08/what-is-the-zone/"&gt;pairing zone&lt;/a&gt;”.
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mt0scpeN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1000/0%2ANV2LOBi6QnMmLvp7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mt0scpeN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1000/0%2ANV2LOBi6QnMmLvp7.jpg" width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don’t understand the advantages of pairing, perhaps you should start with that. Let’s quickly recap them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You’re “forced” to put your thoughts and ideas into concrete words, which contributes to &lt;a href="https://en.wikipedia.org/wiki/Rubber_duck_debugging"&gt;solving problems&lt;/a&gt; and helps you consolidating knowledge;&lt;/li&gt;
&lt;li&gt;Pairs complement/help each other (e.g. you don’t get stuck for hours in a bug); you move steadily and with increased predictability; you feel useful at the end of the day;&lt;/li&gt;
&lt;li&gt;The focus is higher since you have to respect your pair’s time and effort (e.g. you won’t be checking your phone every time) and you’ll have someone helping to manage time (e.g. who can tell you when you’re sliding away);&lt;/li&gt;
&lt;li&gt;Code reviews and &lt;a href="https://en.wikipedia.org/wiki/Four_eyes"&gt;decisions&lt;/a&gt; happen “on-the-fly” rather than in a separate phase (better context, less long discussions); quality is improved as you’re actively reviewing;&lt;/li&gt;
&lt;li&gt;You learn on the job much more, as you may be pairing with an expert on the topic;&lt;/li&gt;
&lt;li&gt;The knowledge is spread across the team; you share solutions and patterns; there are no preassigned tasks; the team doesn’t depend on specific people to move forward; on-boarding/off-boarding is not a pain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/jordanpoulton/607a8854673d9f22c696"&gt;Let’s now go through some tips for the driver (the one writing the code) and the navigator (the one specifying).&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Discipline and focus
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clear out the assumptions&lt;/strong&gt; before starting. Make sure you read the user story in detail. Don’t rush to start. Agree on the strategy beforehand (using flowcharts, ‘to do’ lists, mental maps, and other diagrams).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timebox experiments.&lt;/strong&gt; If one needs to make some code experiment or a small spike, propose a time slot to try it out (e.g. 15 min., 1 hour, till lunch). That will help keep focus.&lt;/li&gt;
&lt;li&gt;As the driver dedicates more mental power to interact with the computer, the navigator has more responsibility to &lt;strong&gt;keep things on tracks&lt;/strong&gt; (ensuring focus at the story). It’s easy to detour but you can say: “Is that related to the story? Could we do it later?”. Otherwise, you’ll keep “opening brackets without closing any”.&lt;/li&gt;
&lt;li&gt;Try to &lt;strong&gt;understand if the driver is refactoring too soon&lt;/strong&gt;. Refactoring should always happen after getting the tests green. Also, be aware if the refactoring is too big or unrelated to the user story; that means it’s time to create a specific story for that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not keep interrupting the driver with early optimizations/improvement&lt;/strong&gt; s (e.g. typos, code repetitions). Think of time split into small slots and wait for one to end to expose them. In TDD, you should only do optimizations/improvements when the tests are green. Write them in a notebook so you can mention them when possible (and you can relax meanwhile). Interestingly, many of my notes are scratched as the code evolved meanwhile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Respect pauses&lt;/strong&gt;. Realize and enjoy when you accomplished something and propose a pause. Focused and intense moments should be followed by pauses (try the &lt;a href="https://en.wikipedia.org/wiki/Pomodoro_Technique"&gt;Pomodoro technique&lt;/a&gt; if it helps).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Respect and empathy
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ask the driver to&lt;/strong&gt; &lt;a href="https://en.wikipedia.org/wiki/Think_aloud_protocol"&gt;&lt;strong&gt;think aloud&lt;/strong&gt;&lt;/a&gt; but respect that not everything needs to be put into words. Sometimes, just go along and/or wait for the experiment to finish. Try to follow it but interrupt if you’re lost.&lt;/li&gt;
&lt;li&gt;Create empathy with the navigator, and &lt;strong&gt;keep probing if your pair is still on board.&lt;/strong&gt; While listening, wait till the end of the sentence rather guessing it. Look at your pair sometimes when speaking/listening.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Have the initiative to switch roles.&lt;/strong&gt; You can propose the ‘specifier/implementer’ technique (one writes the spec, the other implements) if you need to explain a complex topic or feel the navigator is lost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not criticize&lt;/strong&gt; the apparently “non-sense Google searches” made by the driver; that’s part of the research. If you let the driver finish thoughts, there’ll be two perspectives to face the problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid condescending explanations&lt;/strong&gt;. Try to teach within the context and in small chunks rather than shoving/showing off your immense knowledge about the project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid repeating “I know that”&lt;/strong&gt; , “Yes I saw that”. Even if true, you might be preventing future teachings. Just move on. Prefer to say “interesting” when you learn something.&lt;/li&gt;
&lt;li&gt;Avoid sentences that start with “in my last company” or “given my experience”. Go directly the the underlying facts.&lt;/li&gt;
&lt;li&gt;The driver is responsible for the implementing but if you see him/her stuck, you may politely say “Can I try something?” so you can switch roles.&lt;/li&gt;
&lt;li&gt;Be aware, from time to time, if the navigator wants to say something. He/she may be holding to avoid interrupting you, so &lt;strong&gt;pause sometimes to listen&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make questions.&lt;/strong&gt; Every question is valid but not all answers are. Challenge the driver. Phrase questions without looking like a “&lt;a href="https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect"&gt;smart ass&lt;/a&gt;”.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don’t dictate code&lt;/strong&gt; : if you know what you want, just type it down. Dictating is tiring to understand and can seem condescending.&lt;/li&gt;
&lt;li&gt;If you enjoyed the day, finish it saying “thanks for the day” or “it was a nice pairing with you today”.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kEbhqt2c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2A07vV1hhpbvSnaYp7DSuq2w.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kEbhqt2c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2A07vV1hhpbvSnaYp7DSuq2w.jpeg" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Emotions
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Don’t stress&lt;/strong&gt; if you don’t understand everything, especially when you’re the new guy. Try to help somehow (code contributions aren’t the only contributions). &lt;strong&gt;Your mental models will iterate and refine with time.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don’t get too personal&lt;/strong&gt; ; pairs work closely and it can be emotionally hard. For example, it’s easy to feel attacked if someone criticizes your code, but you can learn how to deal with it, on both roles. Coding is just a tool; not a personal trait.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.researchgate.net/publication/18509826_Timing_of_Self-Disclosure_and_its_Effects_on_Personal_Attraction"&gt;Be open about your weaknesses from the start; mention your strengths later.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Be gentle and tolerant. &lt;strong&gt;Don’t make the other feel threatened for not knowing something.&lt;/strong&gt; Never say “didn’t you know that?”. Don’t judge the other’s knowledge. Pairing is a symbiosis; not a competition.&lt;/li&gt;
&lt;li&gt;Behavior generates behavior, so &lt;strong&gt;don’t let feelings escalate in the wrong direction&lt;/strong&gt;. Making fun isn’t welcomed. Strive for empathy and positive mood.&lt;/li&gt;
&lt;li&gt;People are different, so adjust to your pair. You want to be treated that way so think “what if I was in his/her shoes” often.&lt;/li&gt;
&lt;li&gt;Accept that you’ll be slower sometimes so &lt;strong&gt;manage anxiety&lt;/strong&gt;. You feel you could go so much faster on your own, but recall that you belong to a team that desires no single points of know-how. Be patient. You’re not only building software but also a team that can do it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the end, if you’re having a lot of effort you may be doing it wrong; or your pair may be making things hard. If that’s the case, ask for a personal feedback session where you clearly state the areas of improvement.&lt;/p&gt;

</description>
      <category>pairprogramming</category>
      <category>tdd</category>
      <category>extremeprogramming</category>
    </item>
    <item>
      <title>Building an autonomous UI</title>
      <dc:creator>Luís Soares</dc:creator>
      <pubDate>Mon, 14 May 2018 09:18:01 +0000</pubDate>
      <link>https://dev.to/lsoares/building-an-autonomous-ui-3d9p</link>
      <guid>https://dev.to/lsoares/building-an-autonomous-ui-3d9p</guid>
      <description>&lt;h4&gt;
  
  
  An autonomous UI doesn’t rely on animations, sound, colors, shortcuts, and help to be understood and used. It doesn’t mean it shouldn’t have them but it shouldn’t depend on them.
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h8BoZtE7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AZMxSxtnk6LPk6GB9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h8BoZtE7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AZMxSxtnk6LPk6GB9.jpg" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Animation
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Animations help to reinforce the chosen visual metaphor&lt;/strong&gt; (e.g. a slide right to express a card removal; a loader to show there’s some background job) and create visual harmony (e.g. to soften transitions). They should be simple, tenuous, used consistently (e.g. fade in vs fade out to express opposite concepts). Use them in moderation and if they bring value. Animations aren’t supposed to be constantly noticed by users, as they’d be distracting from what matters. They shouldn’t be used just to “make the app cooler”.&lt;/p&gt;

&lt;p&gt;Excessive and heavy animations can be really bad, consuming lots of CPU time or being harmful to people with certain disabilities (e.g. epilepsy), so in certain cases, it should be possible to &lt;a href="https://api.jquery.com/jquery.fx.off"&gt;turn them off&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A nice experiment to try is to turn off all the animations and confirm if the UI is still usable (preferably with users). This helps to understand if certain animations are there to camouflage or reinforce bad or good design decisions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Color
&lt;/h4&gt;

&lt;p&gt;Color, shape, position, contrast, texture are basic elements of graphical design. Colors are associated with moods and emotions that may vary with culture; they can also serve to highlight elements, thus having high expressive power. However, you should never use color as the single differentiating element. If you have several items that you need to distinguish, color can reinforce it, but it shouldn’t be used alone. The main reason is accessibility (e.g. people with color blindness would have problems using such UIs). On the other hand, you usually don’t know the color limitations of the users’ displays.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CfI-o3Dx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/235/0%2AqQ8M1R7l2razXFdK." class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CfI-o3Dx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/235/0%2AqQ8M1R7l2razXFdK." width="235" height="176"&gt;&lt;/a&gt;&lt;em&gt;In addition to color, the shape also helps you realize what the icon is (Google Drive)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The general rule is to use shape to differentiate items and color as an addition. Luminosity itself is also a differentiating element. To know if you pass this “color test”, &lt;strong&gt;try to use your interface in shades of gray&lt;/strong&gt; and see if it needs some fix.&lt;/p&gt;

&lt;h4&gt;
  
  
  Help
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;A good interface doesn’t require the user to depend on help to perform tasks&lt;/strong&gt;. This is not saying that the application shouldn’t have a user manual or contextual help. On the contrary, the help must exist and be as contextualized as possible (e.g. well-placed tooltips; contextual links to help); what you should aim for is that the users shouldn’t have to consult it, especially on repeated usage. &lt;strong&gt;A good UI should “speak for itself”&lt;/strong&gt;. For this, &lt;a href="https://medium.com/@lsoares/what-developers-need-to-know-about-ux-974b99d61d05"&gt;a minimalist design, a natural flow of information&lt;/a&gt;, a good information architecture, among others contribute a lot.&lt;/p&gt;

&lt;p&gt;Avoid instructions; you can do it naturally, transparently and implicitly. If your UI needs and relies on instructions, “you’re doing it wrong”. Well, not necessary, but try to build the UI like that was true.&lt;br&gt;&lt;br&gt;
If users rely too much on help, this may be a symptom that something is wrong with the design or even with the information architecture.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sound
&lt;/h4&gt;

&lt;p&gt;A sound effect at the right time can be helpful. It can be used to draw attention (e.g. new message arrived), to reinforce a concept (e.g. successful operation), to signal an error, among others.&lt;/p&gt;

&lt;p&gt;Like animations, &lt;strong&gt;sound must always be used as a complement to the UI and never as a primary form of communication&lt;/strong&gt;. You should never rely on sound since the user may lack a sound device or have it muted, be in a noisy place or have some kind of hearing disability.&lt;br&gt;&lt;br&gt;
If adding a certain sound really brings value, then it should be used with consideration. Inappropriate use can be annoying and tiring.&lt;/p&gt;

&lt;h4&gt;
  
  
  Mouse
&lt;/h4&gt;

&lt;p&gt;The dependence of the mouse can also sometimes be negative. Typical examples are mouse-over and right mouse button operations which become unusable on touch-only devices. You can use the right button, but only for the sake of flexibility and speed — and again, an alternative method of interaction. For navigation, consider also keyboard shortcuts.&lt;br&gt;&lt;br&gt;
The same applies to the mouse wheel; there should exist an alternative to its use. Finally, depending solely on the mouse also impacts accessibility.&lt;/p&gt;

&lt;h4&gt;
  
  
  Keyboard
&lt;/h4&gt;

&lt;p&gt;Keyboard shortcuts (e.g. Ctrl+C to copy, Tab to navigate) aren’t supposed to be the only means of interaction — most are for advanced users. What’s done with a shortcut should be explicitly offered in the UI (hidden under menus or not).&lt;/p&gt;

&lt;h4&gt;
  
  
  Navigation controls
&lt;/h4&gt;

&lt;p&gt;You shouldn’t expect users to click on the browser ‘refresh’ button to recover from errors or to force data updates. Also, try to avoid depending on the ‘back’ and ‘forward’ buttons to navigate. &lt;strong&gt;The software should be self-contained in terms of navigation, error recovery and data update&lt;/strong&gt; (specially &lt;a href="https://en.wikipedia.org/wiki/Single-page_application"&gt;SPA&lt;/a&gt;s).&lt;br&gt;&lt;br&gt;
In native Android apps, you can offer an alternative to ‘menu’ and ‘back’ in the app UI itself.&lt;/p&gt;

&lt;h4&gt;
  
  
  Permissions
&lt;/h4&gt;

&lt;p&gt;In web and native apps, you can ask for hardware and software permissions (e.g. camera, microphone, location, showing notifications) but your app should work without them (e.g. if the user declined permission). If it depends on them to be used, you should explain it to users.&lt;/p&gt;

&lt;h4&gt;
  
  
  Messages
&lt;/h4&gt;

&lt;p&gt;Don’t assume users read error/warning messages in dialogs. Many times they dismiss them without reading their text. &lt;a href="https://userexperiences.co/design-ui-don-t-punish-the-humans-53807f955517"&gt;Don’t punish&lt;/a&gt; users for missing them. The app should have ways to repeat the message or display it inline (contextually) instead.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ids
&lt;/h4&gt;

&lt;p&gt;Don’t create UI use cases that depend on ids (database identifiers) to be accomplished. For example, why would you show identifiers on a data table? Why would you let the user assign an object to another requesting its id? Friendly titles are for humans; identifiers are for machines.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SkcpW7N---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/600/0%2ABwKrnIMcfQ3e8GW7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SkcpW7N---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/600/0%2ABwKrnIMcfQ3e8GW7.jpg" width="600" height="285"&gt;&lt;/a&gt;Why show ids when creating objects?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cDLeGKp5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2ArULUr15ySIgj3XK_urcqKA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cDLeGKp5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2ArULUr15ySIgj3XK_urcqKA.png" width="800" height="352"&gt;&lt;/a&gt;Why display ids in data tables?&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;As a general rule of thumb, try to design each “place in the app” in a way that the users wouldn’t need to know what they’ve done to get there. They could be really forgetful or always going to coffee. That said, each place should have the necessary information to be understood by itself allowing users to resume the task at hands.&lt;/p&gt;

&lt;p&gt;When designing UIs, we need to decide what are the means of interaction and divide them into primary and auxiliary. Generally, animation, sounds, color, and help, should be seen as an auxiliary — to reinforce or complement the main concepts and ideas. Of course, sometimes they can be of great value (e.g. inline icons to give contextual help, breadcrumbs as shortcuts), but at least you should try to design the UI without depending on them. The general guideline is to turn all off, and test how the UI “behaves”.&lt;/p&gt;

&lt;p&gt;In web apps/sites, it’s obvious at these days that you should avoid depending on the target audience’s display capabilities, like screen size and resolution, color schema, etc. Embrace &lt;a href="https://css-tricks.com/the-difference-between-responsive-and-adaptive-design/"&gt;responsive and adaptive design&lt;/a&gt;. Also, beware and run away from non-standard dependencies like Flash, Java, and Silverlight.&lt;/p&gt;

&lt;p&gt;Don’t assume users will see initially hidden information like tooltips, unselected tabs, dropdown options, etc. Bear in mind there are certain &lt;a href="https://en.wikipedia.org/wiki/Interaction_design_pattern"&gt;interaction design patterns&lt;/a&gt; that are inherently an alternative to something (auxiliary), and never the primordial form of interaction. For example, breadcrumbs shouldn’t be the only form of navigation; these are only a shortcut/alternative to the main navigation.&lt;/p&gt;

&lt;p&gt;There are items that you want users to see and others that they can discover later (depending on task importance). However, you should present items in ways that they wouldn’t need to be instructed beforehand. Design the UI in such a way that it can be self discoverable. Aim for self explainable, autonomous and independent UIs.&lt;/p&gt;

&lt;p&gt;Note that the rules above should serve only as a reference, as they may have exceptions (however, to break the rules, you need to know them). Only by testing with users can you be sure that they are met. It’s never enough to repeat that just &lt;a href="https://www.nngroup.com/articles/why-you-only-need-to-test-with-5-users/"&gt;5 users are enough to detect most UI problems&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://luissoares.com/uma-interface-independente/"&gt;&lt;em&gt;Original article in Portuguese.&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>interactiondesign</category>
      <category>interfacedesign</category>
      <category>ux</category>
      <category>design</category>
    </item>
  </channel>
</rss>
