<?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>Forem: Wealize</title>
    <description>The latest articles on Forem by Wealize (@wealize).</description>
    <link>https://forem.com/wealize</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%2Forganization%2Fprofile_image%2F769%2F16b000b8-a7e6-4dc2-a441-a8d0b8a0f81a.png</url>
      <title>Forem: Wealize</title>
      <link>https://forem.com/wealize</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/wealize"/>
    <language>en</language>
    <item>
      <title>Avoiding IF nesting ✨</title>
      <dc:creator>Jesús Mejías Leiva</dc:creator>
      <pubDate>Sun, 25 Oct 2020 18:33:43 +0000</pubDate>
      <link>https://forem.com/wealize/clean-code-avoiding-if-nesting-25en</link>
      <guid>https://forem.com/wealize/clean-code-avoiding-if-nesting-25en</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Today I come to share a little tip to &lt;strong&gt;&lt;em&gt;improve the readability of our code&lt;/em&gt;&lt;/strong&gt;. We will achieve this by using &lt;strong&gt;guard clauses&lt;/strong&gt; which will help us avoid this &lt;code&gt;IF&lt;/code&gt; nesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Bad ❌
&lt;/h4&gt;

&lt;p&gt;In this example, we can see how and &lt;code&gt;IF&lt;/code&gt; nesting appears, in this case, it is a simple example but this can get complicated, with each nesting that is added the code will become &lt;strong&gt;less readable and therefore less friendly and less maintainable&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;calculatePercentageHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;width&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="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;isNaN&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isInteger&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="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="k"&gt;else&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;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&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="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// use function&lt;/span&gt;
&lt;span class="nx"&gt;calculatePercentageHeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// result 100&lt;/span&gt;
&lt;span class="nx"&gt;calculatePercentageHeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&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;// result 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Good ✅
&lt;/h4&gt;

&lt;p&gt;Using &lt;strong&gt;guard clauses&lt;/strong&gt; we avoid the nesting of &lt;code&gt;IF&lt;/code&gt; conditionals since we will &lt;strong&gt;&lt;em&gt;"first control the error cases&lt;/em&gt;"&lt;/strong&gt;, and then we will continue with our logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;calculatePercentageHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;width&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="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;isNaN&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="k"&gt;return&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;// guard clause&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isInteger&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="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="c1"&gt;// guard clause&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;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// use function&lt;/span&gt;
&lt;span class="nx"&gt;calculatePercentageHeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// result 100&lt;/span&gt;
&lt;span class="nx"&gt;calculatePercentageHeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&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;// result 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Using &lt;strong&gt;guard clauses&lt;/strong&gt; is good practice to avoid unnecessary ramifications and therefore make your &lt;strong&gt;code easier and more readable&lt;/strong&gt;. If we apply these guidelines we will make our &lt;strong&gt;software much more maintainable and friendly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading me. 😊&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3ohs4kI2X9r7O8ZtoA/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3ohs4kI2X9r7O8ZtoA/giphy.gif" alt="thanks"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>codequality</category>
    </item>
    <item>
      <title>Translations for React using i18n hook</title>
      <dc:creator>Jesús Mejías Leiva</dc:creator>
      <pubDate>Thu, 25 Jun 2020 17:23:29 +0000</pubDate>
      <link>https://forem.com/wealize/translations-for-react-using-i18n-hook-1616</link>
      <guid>https://forem.com/wealize/translations-for-react-using-i18n-hook-1616</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Recently in my work, the need to include translations to a project built with React arose. I had to investigate and came to this solution, which I think someone might find helpful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation of necessary packages
&lt;/h3&gt;

&lt;p&gt;For the installation of these packages, we will need to have previously installed and configured &lt;a href="https://www.npmjs.com/get-npm"&gt;npm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once we have &lt;strong&gt;npm&lt;/strong&gt; installed we must install the following packages:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install --save i18next&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;



&lt;p&gt;&lt;code&gt;npm install --save react-i18next&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;



&lt;p&gt;&lt;code&gt;npm install --save i18next-browser-languagedetector&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a file where translations will be stored
&lt;/h3&gt;

&lt;p&gt;We will create a folder called translations within src and, within the translations folder, we will create a folder for each language to which we want to add the translations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./src
    ./translations
        ./es
            ./translations.js

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will create the translation.js file where the translations stored in this case for the Spanish language:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// File: translations.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TRANSLATIONS_ES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;female&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="s2"&gt;Femenino&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;h3&gt;
  
  
  Create the configuration file for i18n
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./src
    ./translations
        ./i18n.js

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// File: i18n.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;i18n&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;i18next&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;initReactI18next&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-i18next&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;LanguageDetector&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;i18next-browser-languagedetector&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// import translations file&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TRANSLATIONS_ES&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../translations/es/translations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;i18n&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LanguageDetector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initReactI18next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;es&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// use translations file for spanish resources&lt;/span&gt;
            &lt;span class="na"&gt;translation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TRANSLATIONS_ES&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using the hook for translations in component
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// File: ExampleComponent.js&lt;/span&gt;

&lt;span class="c1"&gt;// import hook for translations and i18n configuration file&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useTranslation&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-i18next&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../translations/i18n.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ExampleComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// destructuring t() function for useTranslation()&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useTranslation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="c1"&gt;// using t() function for translate}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;female&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;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;p&gt;Thanks for reading me. 😊&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/xThtafIpo4LZgPEQuY/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/xThtafIpo4LZgPEQuY/giphy.gif" alt="thank you"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>npm</category>
      <category>hook</category>
    </item>
    <item>
      <title>Why we ditched story points to be more value-oriented</title>
      <dc:creator>Javier Aguirre</dc:creator>
      <pubDate>Wed, 11 Dec 2019 09:00:00 +0000</pubDate>
      <link>https://forem.com/wealize/why-we-ditched-story-points-to-be-more-feature-oriented-3i1i</link>
      <guid>https://forem.com/wealize/why-we-ditched-story-points-to-be-more-feature-oriented-3i1i</guid>
      <description>&lt;p&gt;At &lt;a href="https://theneonproject.org"&gt;TNP&lt;/a&gt; we worked using story points to estimate and control the amount of work everybody on the team was doing, but we decided to ditch it, here is why.&lt;/p&gt;

&lt;p&gt;We discovered several problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;People were stressed to finish their points, and they couldn’t focus on helping each other because they wanted to end their user stories. This issue was pushing individualism rather than quality and ship feature focus.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Having story points wasn’t pointing us to build faster or with more quality. User story points weren’t focusing the work on value but rather on risk, time, and complexity of the user story and features. 1-week sprints were making everything worse due to this fact when we finished features that weren’t good enough to put in production and were coming back to haunt us.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/26hitt0thlwfoNRaE/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/26hitt0thlwfoNRaE/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We always like to iterate on processes to improve it and reduce friction at maximum, so everybody is comfortable working and focusing on delivering as much value as possible. With this idea, we decided to focus much more on delivery, following some rules.&lt;/p&gt;

&lt;p&gt;We have two-week sprints, and we organize teams by features, so everybody is on board to ship the feature and responsible for it. We don’t have departments, but feature teams with different roles. I haven’t invented this. It’s from &lt;a href="https://pragprog.com/book/rjnsd/the-nature-of-software-development"&gt;The Nature of Software Development book&lt;/a&gt; that &lt;a href="https://twitter.com/stanete"&gt;@stanete&lt;/a&gt; recommended some time ago. Every user story or feature has a team behind, design, product, development, and everybody is needed to accomplish it.&lt;/p&gt;

&lt;p&gt;We had to improve user story definition, make them more shippable and self-contained so we could deploy each of them with value for the client. That’s why we decided to be much more product-oriented. Make those &lt;em&gt;minimum viable features&lt;/em&gt; to adjust the value and time consumption working on them. This idea is probably the most difficult to achieve. Still, we think it is better to work in this direction rather than trying to estimate better, which won’t focus on deliverability but internal needs.&lt;/p&gt;

&lt;p&gt;This new way of working makes it more natural to have other advantages for the team. For example, when someone finished their stories early, he/she has to help the rest of the team on the features to complete for this sprint so we can ship as a team. We have time every week to learn in the process because we’re not stressed, and the time is much less tight. Improve accomplishment managing scope rather than improving estimates. We plan to do as much as in the last iteration to do good work at a consistent pace.&lt;/p&gt;

&lt;p&gt;In the case of engineering tasks and reducing technical debt, we follow the rule ‘leave the campground better than you found it.’ I have adopted that rule for years since I read &lt;a href="https://www.amazon.es/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882"&gt;Clean Code&lt;/a&gt;, but all the team must stay in tune, so every time we do a feature, we can clean up the area where we are going to work. We’re exhaustive on testing and good quality code to avoid technical debt. We also try to move the QA phase of the feature as soon as possible and not only when it’s done. Once we ship, the feature shouldn’t come back with defects in it; otherwise, It disrupts our development pace.&lt;/p&gt;

&lt;p&gt;We haven’t invented this way of working. Some of the tips are from the Influence of the &lt;strong&gt;Nature of Software Development and Clean Code&lt;/strong&gt; , among other books. We’re always iterating to improve our processes and learning new things so that these changes will vary in the future.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/6brH8dM3zeMyA/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/6brH8dM3zeMyA/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover Photo by Franck V. on Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>codequality</category>
      <category>feature</category>
      <category>delivery</category>
      <category>product</category>
    </item>
    <item>
      <title>Get release tag from GitHub Actions to debug on Heroku</title>
      <dc:creator>Javier Aguirre</dc:creator>
      <pubDate>Thu, 28 Nov 2019 09:00:00 +0000</pubDate>
      <link>https://forem.com/wealize/get-release-tag-from-github-actions-to-debug-on-heroku-3583</link>
      <guid>https://forem.com/wealize/get-release-tag-from-github-actions-to-debug-on-heroku-3583</guid>
      <description>&lt;p&gt;In TNP we’ve moved everything to GitHub Actions and we’re very happy about it. :-)&lt;/p&gt;

&lt;p&gt;But… this article is not about how happy we are using it but a small tip on how we could simplify every day debugging with some simple improvements.&lt;/p&gt;

&lt;p&gt;As a good metric oriented company, We measure and monitor everything we believe relevant, this is a solution to control which release we have in production and being able to monitor its breaking changes in a simple way.&lt;/p&gt;

&lt;p&gt;We decided to add the git release tag to our deploy and our app footers, with the following steps.&lt;/p&gt;

&lt;p&gt;First, We push to production only when a git tag (a release) is created on GitHub.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;...&lt;/span&gt;

  &lt;span class="s"&gt;deploy_production&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;...&lt;/span&gt;

    &lt;span class="s"&gt;if&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;success() &amp;amp;&amp;amp; contains(github.ref, 'tags')&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We deploy to Heroku where is super easy to set a config variable via API, so we decided to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get the release tag from the current release&lt;/li&gt;
&lt;li&gt;Update a &lt;code&gt;RELEASE_VERSION&lt;/code&gt; variable on Heroku every time a new deploy is successful.&lt;/li&gt;
&lt;li&gt;Profit!
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Push to Heroku&lt;/span&gt;
   &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;git push -f https://heroku:${{ secrets.HEROKU_API_TOKEN }}@git.heroku.com/${{ secrets.HEROKU_APP_PRODUCTION }}.git origin/master:master&lt;/span&gt;
 &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Update RELEASE_VERSION on Heroku production&lt;/span&gt;
   &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;success()&lt;/span&gt;
   &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;curl -n -X PATCH https://api.heroku.com/apps/${{ secrets.HEROKU_APP_PRODUCTION }}/config-vars \&lt;/span&gt;
    &lt;span class="s"&gt;-d '{&lt;/span&gt;
      &lt;span class="s"&gt;"RELEASE_VERSION”: "${{ github.ref }}",&lt;/span&gt;
    &lt;span class="s"&gt;}’ \&lt;/span&gt;
    &lt;span class="s"&gt;-H "Authorization: Bearer ${{ secrets.GITHUB_API_TOKEN }}"&lt;/span&gt;
    &lt;span class="s"&gt;-H "Content-Type: application/json" \&lt;/span&gt;
    &lt;span class="s"&gt;-H "Accept: application/vnd.heroku+json; version=3"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to set two variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;HEROKU_API_TOKEN&lt;/code&gt;: Your personal token, you can get it from your &lt;a href="https://dashboard.heroku.com/account"&gt;account settings&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HEROKU_APP_PRODUCTION&lt;/code&gt;: Your production app name on Heroku, we don’t hardcode it, so it’s easier to share these recipes in other projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s It! You’ll have something like this on your Heroku app if all goes well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UKiDaAuu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/488556/69890303-37c27600-12f5-11ea-9280-6a89fa3b74c4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UKiDaAuu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://user-images.githubusercontent.com/488556/69890303-37c27600-12f5-11ea-9280-6a89fa3b74c4.png" alt="Screenshot 2019-11-29 at 22 10 38" width="800" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover Image Garett Mizunaka - Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>actions</category>
      <category>cicd</category>
      <category>heroku</category>
    </item>
    <item>
      <title>Natural Language Processing with Google Cloud AutoML for safer humans</title>
      <dc:creator>Francisco Aranda</dc:creator>
      <pubDate>Wed, 17 Jul 2019 10:21:54 +0000</pubDate>
      <link>https://forem.com/theneonproject/natural-language-processing-with-google-cloud-automl-for-safer-humans-5cne</link>
      <guid>https://forem.com/theneonproject/natural-language-processing-with-google-cloud-automl-for-safer-humans-5cne</guid>
      <description>&lt;p&gt;At The Neon Project, we enjoy participating in projects that require the application of date technologies such as artificial intelligence and, more specifically, machine learning. These technologies help us extract and analyze large amounts of data to make better decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Natural language processing in our last project&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In our most recent project for an organization in the USA, we have been given the task to help reduce and ultimately eliminate mistakes in a disaster prevention system through &lt;a href="https://en.wikipedia.org/wiki/Natural_language_processing" rel="noopener noreferrer"&gt;natural language processing&lt;/a&gt; (NLP).&lt;/p&gt;

&lt;p&gt;The organization currently uses a system that relies on a traditional parser in order to extract relevant data from informative documents. These documents are manually written by humans from trusted organizations. In this scenario, a document with a wrong format that is not processed by the parser is critical for the rest of the infrastructure.&lt;/p&gt;

&lt;p&gt;Because of the sensitivity of the system to false negatives (documents that are ignored by the parser but that are actually relevant and critical), the organization requires engineers to check a lot of the documents rejected by the parser at whatever time they come in.&lt;/p&gt;

&lt;p&gt;Technically the source of the problem is that data is heterogeneous and reports don’t necessarily match a standard or template. Human typing mistakes can be expected as they are generated in critical and tense contexts. In this scenario, a traditional parser has major technical limitations.&lt;/p&gt;

&lt;p&gt;Our approach was to design a natural language processing model that can identify a set of identities within a huge set of documents. After a few training and validation iterations, this model can replace the current parser and be better at identifying relevant documents. This reduces the risk of false negatives and the need for human intervention for corrections.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheneonproject.org%2Fwp-content%2Fuploads%2F2019%2F07%2FEntities-1024x982.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheneonproject.org%2Fwp-content%2Fuploads%2F2019%2F07%2FEntities-1024x982.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Adding Google Cloud AutoML in our tech stack&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Google launched last April a new set of services for machine learning development under the name &lt;a href="https://cloud.google.com/automl/" rel="noopener noreferrer"&gt;Google Cloud AutoML&lt;/a&gt;. We were very excited to use them in a real-world use case, so this seemed to be a great chance to do it.&lt;/p&gt;

&lt;p&gt;AutoML offers a simple interface where we could easily upload sample documents to create a dataset. We had documents that were shared by our clients. We completed this data set with similar documents we scraped from trusted sources on the Internet.   &lt;/p&gt;

&lt;p&gt;Once the documents were uploaded, we had to tag with labels the entities we wanted our model to recognize. Only after the dataset had a minimum quantity of samples for each label, we could begin the training of the model. Once finished, our model was able to identify the entities from a new document, not previously known to the system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheneonproject.org%2Fwp-content%2Fuploads%2F2019%2F07%2Flabel-stats-1024x309.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheneonproject.org%2Fwp-content%2Fuploads%2F2019%2F07%2Flabel-stats-1024x309.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As soon as we had validated the model was properly designed and trained, we used the &lt;a href="https://github.com/googleapis/nodejs-automl" rel="noopener noreferrer"&gt;Node.js library&lt;/a&gt; for the AutoML API. In addition, we built a proxy API service together with a simple web interface. In the interface, users can upload documents and see how confident the system is of the importance of the report, based on the content and context of the document and not on its format.&lt;/p&gt;

&lt;p&gt;Building the model and the user interface took days instead of weeks thanks to Google Cloud AutoML and allowed us to make our clients happy. We found AutoML an exciting platform for creating machine learning solutions. Getting things done was very straight-forward, and the results were pretty good. We will continue using it in the future!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Do you have a conversational project?&lt;/strong&gt;
&lt;/h3&gt;

&lt;h2&gt;
  
  
  &lt;a href="//mailto:hola@theneonproject.org"&gt;&lt;strong&gt;Let’s work together&lt;/strong&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The post &lt;a href="https://theneonproject.org/nlp-with-auto-ml-for-safer-humans/" rel="noopener noreferrer"&gt;Natural Language Processing with Google Cloud AutoML for safer humans&lt;/a&gt; was first published at &lt;a href="https://theneonproject.org" rel="noopener noreferrer"&gt;The Neon Project - Agency for the digital transformation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>resources</category>
      <category>ai</category>
      <category>automl</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Improve code reviews using pull request templates </title>
      <dc:creator>Daniel Luque Quintana</dc:creator>
      <pubDate>Tue, 09 Jul 2019 10:12:55 +0000</pubDate>
      <link>https://forem.com/wealize/improve-code-reviews-using-pull-request-templates-10he</link>
      <guid>https://forem.com/wealize/improve-code-reviews-using-pull-request-templates-10he</guid>
      <description>&lt;p&gt;At The Neon Project we care about our internal processes: we believe they’re important, we design them meticulously, we use them, and we improve them as we learn from their performance in the real world. &lt;/p&gt;

&lt;p&gt;One of the most important processes when developing software is code review, where at least one teammate will review your code. This process improves the quality of the code since, many times, code that seems easy to understand for the author is not as clear for the rest of the team. Everyone involved in the code review learns: learn how to give feedback, learn how your partners think and write code &amp;amp; learn technical details.&lt;/p&gt;

&lt;p&gt;To make the code review process as easy and quick as possible, the more context we give our colleagues about what we have done and why, the better. After reviewing the &lt;a href="https://github.com/thepracticaldev/dev.to"&gt;Dev.to Github repository&lt;/a&gt; and seeing some pull requests, I thought there was a way to improve our code review process in The Neon Project: using templates for pull requests.&lt;/p&gt;

&lt;p&gt;A pull request template is, basically, a file containing markdown text that is added to your pull request description automatically when it is created.&lt;/p&gt;

&lt;p&gt;The file must have the name &lt;strong&gt;pull_request_template.md&lt;/strong&gt;. In our case, this file is in a hidden folder named .github, but you can put it wherever you want (more information about Github pull request templates &lt;a href="https://help.github.com/en/articles/creating-a-pull-request-template-for-your-repository" rel="noopener noreferrer"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Our template consists of the following parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A reminder&lt;/strong&gt;: as we use Jira for project management, a very useful feature is to link a PR to a Jira issue by adding the issue code to the PR title. This way we can see its status from Jira&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Type of PR&lt;/strong&gt;: consists of 3 checkboxes, indicating whether the pull request is a bugfix, a new feature or a refactor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;: a brief description of what we can expect from PR. This part is essential for the person who reviews the code to know, in one pass and briefly, what to expect in the code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Screenshots (if there are changes of UI)&lt;/strong&gt;: one of the problems of the PR that have visual changes is to know what has changed or what is the final result. In general, the process to execute the code locally and see it won't be fast, the person will have to download the code changes in their machine, have the environment configured, etc. A few simple photos and/or videos will save a lot of time to see what's new. Personally, I use &lt;a href="https://support.apple.com/en-us/HT201361" rel="noopener noreferrer"&gt;macOS screenshots&lt;/a&gt; and &lt;a href="http://imgur.com" rel="noopener noreferrer"&gt;Imgur&lt;/a&gt; to upload them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;(optional) a gif that describes how it makes you feel&lt;/strong&gt;: because there's always a good reason to put gifs, right? 🤓&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgur.com%2FhGh0RGD.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgur.com%2FhGh0RGD.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this simple way, we improve the code review process: more information and context so that code reviewers can understand quickly what they are going to review and thus are able to deploy code more often 🚀&lt;/p&gt;

&lt;h3&gt;
  
  
  One more thing...
&lt;/h3&gt;

&lt;p&gt;After the announcement that &lt;a href="https://github.blog/2019-06-17-github-acquires-pull-panda/" rel="noopener noreferrer"&gt;Github has acquired Pull Panda&lt;/a&gt;, we have integrated it into our process and we are very satisfied! For those who don't know it, Pull Panda allows you to remember through Slack when a contributor needs to have a PR checked, can assign a reviewer automatically and offers a series of very interesting analytics to know, for example, the average time needed to make reviews or how many took more than 8 hours. And it's free!&lt;/p&gt;

&lt;p&gt;That's it, folks. So, how's your code review process? Any advice on how to improve ours?&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Automatize your new developer’s team onboarding with this simple app (in Python)</title>
      <dc:creator>Javier Aguirre</dc:creator>
      <pubDate>Sun, 23 Jun 2019 09:00:00 +0000</pubDate>
      <link>https://forem.com/wealize/automatize-your-new-developer-s-team-onboarding-with-this-simple-app-in-python-22pg</link>
      <guid>https://forem.com/wealize/automatize-your-new-developer-s-team-onboarding-with-this-simple-app-in-python-22pg</guid>
      <description>&lt;p&gt;When a new developer joins our team, everybody wants to give them the best possible experience 🙌.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/FQyQEYd0KlYQ/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/FQyQEYd0KlYQ/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’ve created a simple command line app in Python that with minimum configuration helps the new developer, in a geeky way, set up his/her environment and checks if everything works! It also gives information about which services would they have access to so they can check and don’t need to go somewhere else for that info.&lt;/p&gt;

&lt;p&gt;We use &lt;a href="https://click.palletsprojects.com/en/7.x/" rel="noopener noreferrer"&gt;Click&lt;/a&gt;, the library to create Command line interfaces in Python, and YAML for the configuration. The config has a specific structure moreover, we can configure the file path so someone could reuse the project for their own company 🤓.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/TheNeonProject/onboarding" rel="noopener noreferrer"&gt;The documentation is in the README&lt;/a&gt;. You can set the company information in the config, as &lt;a href="https://github.com/TheNeonProject/onboarding/blob/master/config.yml" rel="noopener noreferrer"&gt;in our own that you could use as an example&lt;/a&gt;. To use your config file, you can set &lt;code&gt;ONBOARDING_FILE_PATH&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can install it with &lt;a href="https://github.com/pypa/pipenv" rel="noopener noreferrer"&gt;pipenv&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip3 &lt;span class="nb"&gt;install &lt;/span&gt;pipenv
pipenv &lt;span class="nt"&gt;--python&lt;/span&gt; 3.7
pipenv &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this command finishes, we can run it using &lt;code&gt;pipenv&lt;/code&gt;.&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="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ONBOARDING_FILE_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;config.yml
pipenv run python cli.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/TheNeonProject/onboarding/blob/master/.vscode/launch.json" rel="noopener noreferrer"&gt;It has the configuration to launch from VS Code Debug tab too&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can see here the output of the app with my company configuration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F488556%2F59706185-3a765680-9200-11e9-90ce-490c377e7016.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F488556%2F59706185-3a765680-9200-11e9-90ce-490c377e7016.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F488556%2F59706184-3a765680-9200-11e9-9a29-a10e7fe8fff1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F488556%2F59706184-3a765680-9200-11e9-9a29-a10e7fe8fff1.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/TheNeonProject/onboarding" rel="noopener noreferrer"&gt;The project is open source and can you can clone it from GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Maybe if we have time, we’ll create a Python package and add more functionality 🎸, but for now, it does the trick. :-)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover image by Photo by Harley-Davidson on Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>management</category>
      <category>onboarding</category>
    </item>
    <item>
      <title>The Journey to control Code Quality</title>
      <dc:creator>Javier Aguirre</dc:creator>
      <pubDate>Wed, 05 Jun 2019 22:21:00 +0000</pubDate>
      <link>https://forem.com/wealize/the-journey-to-control-code-quality-4njl</link>
      <guid>https://forem.com/wealize/the-journey-to-control-code-quality-4njl</guid>
      <description>&lt;p&gt;Coding, programming, developing, name your action! Such a funny and exciting amusement, sometimes going wrong under stress or when lacking experience in a certain technology.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Challenge
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/xTkcERvSGMZOpp9RkI/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/xTkcERvSGMZOpp9RkI/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We sometimes need to write code we’re not proud of, but nowadays we have mechanisms to quantify that and improve its quality. Like boy scouts, we can go back and clean the camp, make more tests because we didn’t have enough coverage and we could be not catching all the possible bugs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/pFwRzOLfuGHok/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/pFwRzOLfuGHok/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I go back and read my code from some time ago, I’m ashamed, and that’s a good thing, It means we’re growing. Otherwise, we wouldn’t notice.&lt;/p&gt;

&lt;p&gt;I’ve always been in the improving code quality path, I know projects and startups need to achieve their goals, otherwise, we all could lose our jobs, but that’s why it’s so important to have proper processes and a good CI/CD, control code quality, and measure legacy code so it doesn’t grow too much.&lt;/p&gt;

&lt;p&gt;I’ve been a testing advocate for years now. I know what we should test and what is more challenging to test, why should we refactor if our tests are too complex because we have an architecture problem, what parts are more likely to be problematic. Still, there is usually doubt, risk and terror.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/Qw4X3FN8Elnz2ew3UFa/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/Qw4X3FN8Elnz2ew3UFa/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, when you’re in a small agency like mine, you need to have metrics, you need to rely on excellent services, so you save all the time possible to do what it gives value to the company. We need to improve the process every time (otherwise what’s the fun in doing everything always the same way right? :-)).&lt;/p&gt;

&lt;h1&gt;
  
  
  The Journey
&lt;/h1&gt;

&lt;p&gt;Our journey for a better code starts with reviews, we defined the user story and estimated the cost of development (more on this on the following article), a member of the team got to it, implemented it and created a PR on GitHub.&lt;/p&gt;

&lt;p&gt;The first step, in this case, assures two checks are passing within the PR:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gitlab CI&lt;/strong&gt; would run the tests and tell us if they passed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Codacy&lt;/strong&gt; tells us if there were significant regressions in terms of code complexity, code duplication, standards, and code coverage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the checks pass at least a developer in the team reviews the PR code for clarity, good patterns, functionality. If everything goes well, the code gets merged to the release branch and, when the sprint ends, to master. We can never remove the human interaction since code patterns, architecture and naming are so dependant on the domain and context of the application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6xq9hl5qij6n7kmbcqce.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6xq9hl5qij6n7kmbcqce.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codacy.com" rel="noopener noreferrer"&gt;Codacy&lt;/a&gt; brings us more functionality than other contenders, such as &lt;a href="https://danger.systems/" rel="noopener noreferrer"&gt;Danger&lt;/a&gt; or &lt;a href="https://codeclimate.com/" rel="noopener noreferrer"&gt;Code Climate&lt;/a&gt;, but if you don’t like it, you might check it out those. We chose Codacy over the others because it gave us better progress feedback, and they have excellent code coverage integration, much easier to set up than Code Climate (for example). It gave us more than Danger since Danger is usually more used as linter but doesn’t get anything regarding code coverage.&lt;/p&gt;

&lt;p&gt;When we started using Codacy, something great happened, the Pull Requests were more alive since everybody was trying to minimize the technical debt they were adding, so Codacy gamified our Pull Requests too. :-)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fwpzpenl2rrgyph2xk4my.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fwpzpenl2rrgyph2xk4my.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Codacy integrates with many languages, we usually use Python Pylint, Bandit, Prospector, and ESLint for Node. Codacy would read these libraries config in your repositories and use that configuration if it exists. Otherwise, you can check the configuration items you want from a particular tool right from their project settings view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F66nfdt7wqxlkmy2hq481.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F66nfdt7wqxlkmy2hq481.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At that point, our CI gets triggered (because we merge to master) and if the tests pass the code is automatically deployed to our staging environment, usually Heroku, but also AWS/Kubernetes.&lt;/p&gt;

&lt;p&gt;When we want to deploy to production, we create a new tag like &lt;strong&gt;vYYYY.MM.DD&lt;/strong&gt; and the CI/CD triggers the deploy to production.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fjavaguirre.me%2Fassets%2Fimages%2Fgitlab-ci1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fjavaguirre.me%2Fassets%2Fimages%2Fgitlab-ci1.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The Destiny
&lt;/h1&gt;

&lt;p&gt;When the code reaches production, we have two services giving us input so we know if something is wrong or an alert is triggered.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://sentry.io" rel="noopener noreferrer"&gt;Sentry&lt;/a&gt; has been my favorite for years in terms of controlling errors in production, it’s straightforward to use, to tag, to separate between different environments (backend, frontend, mobile) and it works so well!&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://newrelic.com/" rel="noopener noreferrer"&gt;New Relic&lt;/a&gt; is mighty, and we use it to detect bottlenecks and performance problems when they occur (or before it is too late if you configure your alerts well!). It’s so nice to be able to monitor your queries and see how are they behaving to be able to prevent a problem in the future, New Relic is excellent for that.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/cI5CL3l9kZ62w0Kh3c/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/cI5CL3l9kZ62w0Kh3c/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What are your favourites? What are your recommendations? Let me know!&lt;/p&gt;

</description>
      <category>codequality</category>
      <category>cicd</category>
      <category>codacy</category>
    </item>
    <item>
      <title>Debug Python and Django easily from Visual Studio Code</title>
      <dc:creator>Javier Aguirre</dc:creator>
      <pubDate>Wed, 22 May 2019 22:21:00 +0000</pubDate>
      <link>https://forem.com/wealize/debug-python-and-django-easily-from-visual-studio-code-4dfk</link>
      <guid>https://forem.com/wealize/debug-python-and-django-easily-from-visual-studio-code-4dfk</guid>
      <description>&lt;p&gt;Debugging code, sometimes painful, sometimes funny, but always an exciting task.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fheqpunsveb24zdu61swv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fheqpunsveb24zdu61swv.gif" width="250" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we don’t use the right tools, It’s where the developer can waste more time. Making debugging easy for developers has been sometimes a problem for technology, but fortunately, in Python, there have been good debug options right from the start.&lt;/p&gt;

&lt;p&gt;Visual Studio Code has a very powerful and configurable tab where you can define the desired configuration for your project. You can have all the configurations you want! (for testing, debugging, running a specific process…)&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;From VS Code, we can easily debug Python code locally but also when running inside of a Docker container using ptvsd. I’ll tell you how.&lt;/p&gt;

&lt;h2&gt;
  
  
  Print
&lt;/h2&gt;

&lt;p&gt;We all have printed code at some point of our career, but the path to becoming a better developer goes beyond that, it’s essential to spend time researching until we find better tools for the task.&lt;/p&gt;

&lt;p&gt;Printing has never been cool, but before learning the proper debugging tools, it has always been that quick and dirty option to check variable output.&lt;/p&gt;

&lt;h2&gt;
  
  
  PDB
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PDB&lt;/strong&gt; and &lt;strong&gt;pudb&lt;/strong&gt; are great tools! I still use them sometimes when I want to debug something tricky, but for debugging speed purposes I find much more convenient using VS Code Debug tab, where I can see all the context on a specific line of code.&lt;/p&gt;

&lt;p&gt;Before that, I used to have a snippet for &lt;code&gt;pdb&lt;/code&gt;, and that would extend to &lt;code&gt;import pdb; pdb.set_trace()&lt;/code&gt; so I could stop the execution at a specific line of code. Then with &lt;code&gt;(n)ext&lt;/code&gt;, &lt;code&gt;(c)ontinue&lt;/code&gt;, &lt;code&gt;(q)uit&lt;/code&gt;… I could control the execution line by line and &lt;code&gt;step into&lt;/code&gt; a specific function or method (more on &lt;a href="https://docs.python.org/3/library/pdb.html"&gt;pdb&lt;/a&gt; and &lt;a href="https://pypi.org/project/pudb/"&gt;pudb&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  VS Code
&lt;/h2&gt;

&lt;p&gt;After a while using VS Code I started getting deep into different user and workspace configurations on Django and Node/React, this article gives an example on how we could configure a Django project to use the VS Code debugging tab.&lt;/p&gt;

&lt;p&gt;Starting services having installed a Django project locally is easy, we could just use runserver. We’d click the Debug tab, select &lt;code&gt;Add configuration...&lt;/code&gt; in the selector and follow the wizard selecting &lt;code&gt;Django: runserver&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feonsw6lemtleeis76ofg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feonsw6lemtleeis76ofg.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The configuration would look like this:&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Django: Runserver"&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;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"request"&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"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"program"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${workspaceFolder}/manage.py"&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="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"runserver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"--noreload"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"--nothreading"&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;"django"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use &lt;code&gt;pipenv&lt;/code&gt;, &lt;code&gt;virtualenv&lt;/code&gt; or have selected the &lt;code&gt;pythonPath&lt;/code&gt; on your workspace configuration (&lt;code&gt;Command-,&lt;/code&gt; on Mac), VS Code knows how to run the command automatically. We could have a command for testing too, having an &lt;code&gt;envvar&lt;/code&gt; to select another &lt;code&gt;DJANGO_SETTINGS_MODULE&lt;/code&gt;.&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Django: 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;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"request"&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"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"program"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${workspaceFolder}/manage.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"env"&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="nl"&gt;"DJANGO_SETTINGS_MODULE"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"myproject.settings.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;"args"&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="s2"&gt;"test"&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;"django"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’d click play and have our tests passed. :-)&lt;/p&gt;

&lt;h2&gt;
  
  
  VS Code debug in Docker
&lt;/h2&gt;

&lt;p&gt;Debugging inside a Docker container is a bit trickier, we need to open a &lt;code&gt;socket&lt;/code&gt; so we can debug from VS Code, let’s see how.&lt;/p&gt;

&lt;p&gt;Our Django Dockerfile looks something like this if we use &lt;code&gt;pipenv&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.7&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; /code

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /code&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;pipenv
&lt;span class="k"&gt;ADD&lt;/span&gt;&lt;span class="s"&gt; Pipfile /code/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pipenv &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--dev&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /code/&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could have a &lt;code&gt;docker-compose.yml&lt;/code&gt; file to manage dependencies easier, such as &lt;code&gt;postgres&lt;/code&gt;, &lt;code&gt;redis&lt;/code&gt;, or just the ports opened for the host.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.7'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;...&lt;/span&gt;

  &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mydjangoproject&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pipenv run manage.py runserver 0.0.0.0:8000&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;DJANGO_DEBUG&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
      &lt;span class="na"&gt;DJANGO_SETTINGS_MODULE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myproject.settings.local&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.:/code&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;8000:8000&lt;/span&gt; &lt;span class="c1"&gt;# Serving Django&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;8888:8888&lt;/span&gt; &lt;span class="c1"&gt;# debugging service (ptvsd)&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;

  &lt;span class="na"&gt;frontend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we open the &lt;code&gt;8000&lt;/code&gt; for Django &lt;code&gt;runserver&lt;/code&gt; and the &lt;code&gt;8888&lt;/code&gt; so VS Code can connect via the Debug tab to Django.&lt;/p&gt;

&lt;p&gt;To be able to do this, Microsoft created a library, &lt;a href="https://github.com/microsoft/ptvsd"&gt;ptvsd&lt;/a&gt; &lt;strong&gt;the Python tools for the Visual Studio debugger&lt;/strong&gt;. This library runs within our Python code and opens a socket we can connect to debug the application. In Django, we can put it on the &lt;code&gt;wsgi.py&lt;/code&gt; file and It will only run if &lt;code&gt;settings.DEBUG&lt;/code&gt; is &lt;code&gt;True&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.core.wsgi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_wsgi_application&lt;/span&gt;

&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setdefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DJANGO_SETTINGS_MODULE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;myproject.settings&lt;/span&gt;&lt;span class="sh"&gt;"&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;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DJANGO_DEBUG&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="c1"&gt;# You can use django.conf settings.DEBUG
&lt;/span&gt;    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ptvsd&lt;/span&gt;
    &lt;span class="n"&gt;ptvsd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enable_attach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8888&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;ptvsd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait_for_attach&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# We can remove this line it gives you trouble,
&lt;/span&gt;                             &lt;span class="c1"&gt;# but it's good to know if the debugger started or not
&lt;/span&gt;                             &lt;span class="c1"&gt;# blocking the execution for a while :-)
&lt;/span&gt;
&lt;span class="n"&gt;application&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_wsgi_application&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We open the socket to the outside world &lt;code&gt;0.0.0.0&lt;/code&gt; in the port &lt;code&gt;8888&lt;/code&gt; so we can connect from the host, our machine.&lt;/p&gt;

&lt;p&gt;We execute our &lt;code&gt;docker-compose&lt;/code&gt; script, in my case &lt;code&gt;docker-compose up backend&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In VS Code the configuration would be pretty straight forward, we add the &lt;code&gt;port&lt;/code&gt; where ptvsd opened the socket, we tell VS Code, our &lt;code&gt;localRoot&lt;/code&gt; is the current project and the &lt;code&gt;remoteRoot&lt;/code&gt; which is my &lt;code&gt;/code&lt;/code&gt; path, defined on my &lt;code&gt;Dockerfile&lt;/code&gt; for this project.&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;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Remote Django App"&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;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"attach"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pathMappings"&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;"localRoot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${workspaceFolder}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"remoteRoot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/code"&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;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8888&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"localhost"&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;p&gt;Now It’s when the magic happens! You should be able to do something like this. :-)&lt;/p&gt;

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

&lt;p&gt;Do you know more tricks debugging on VS Code? Let me know in the comments!&lt;/p&gt;

</description>
      <category>python</category>
      <category>vscode</category>
      <category>django</category>
    </item>
    <item>
      <title>Common Git problems and easy incremental solutions for all the family</title>
      <dc:creator>Javier Aguirre</dc:creator>
      <pubDate>Wed, 22 May 2019 21:07:59 +0000</pubDate>
      <link>https://forem.com/wealize/common-git-problems-and-easy-incremental-solutions-for-all-the-family-10gd</link>
      <guid>https://forem.com/wealize/common-git-problems-and-easy-incremental-solutions-for-all-the-family-10gd</guid>
      <description>&lt;p&gt;Git is a gentle beast, but beasts are wild, and they require taming, here are some tips to resolve 99% of git problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3oEduIpnblLzPwzJPG/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3oEduIpnblLzPwzJPG/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Working with developers of different experience levels made me realize we should have a simple suitable method to resolve all possible issues when working on a git project, that's why I wrote this tutorial in the first place.&lt;/p&gt;

&lt;p&gt;At my company, we follow a small variation of &lt;a href="https://es.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow" rel="noopener noreferrer"&gt;git flow&lt;/a&gt;, where there are no &lt;strong&gt;develop&lt;/strong&gt; branch, but a &lt;strong&gt;release&lt;/strong&gt; one&lt;br&gt;
that gets merged every sprint with &lt;strong&gt;master&lt;/strong&gt; and gets recreated for the next sprint until we merge again, deploying automatically to production.&lt;/p&gt;

&lt;p&gt;We did this variation because we found out that keeping the &lt;strong&gt;develop&lt;/strong&gt; branch neat and clean when there are different levels of git knowledge in the company is challenging.&lt;/p&gt;

&lt;p&gt;We use &lt;strong&gt;git fetch&lt;/strong&gt; to update our git database locally, so we have the latest changes. In case of doubt, we always rebase and create branches from &lt;strong&gt;origin&lt;/strong&gt;, never from a local branch because we might mess up.&lt;/p&gt;

&lt;p&gt;When developing a feature, we always use &lt;strong&gt;rebase&lt;/strong&gt; to update our current feature from &lt;strong&gt;release&lt;/strong&gt;. We squash the &lt;strong&gt;feature&lt;/strong&gt; branches into one commit, so it's easy to rollback a feature once it is reviewed and ready to merge.&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;# Being on the feature/my-tasty-feature branch&lt;/span&gt;

git fetch origin
git rebase origin/release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creating a feature branch:&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;# Being on master or release or any other branch different from the one created&lt;/span&gt;

git fetch origin
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature/my-tasty-feature origin/release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  First problem and solution
&lt;/h2&gt;

&lt;p&gt;We need to update our code with &lt;strong&gt;release&lt;/strong&gt; because we don't have the latest changes. In our feature branch we can do:&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;# Being on the feature/my-tasty-feature branch&lt;/span&gt;

git fetch origin
git rebase origin/release
git push &lt;span class="nt"&gt;-f&lt;/span&gt; feature/my-tasty-feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;-f&lt;/code&gt; can only be used on an unmerged personal branch. It means &lt;em&gt;force&lt;/em&gt; and it rewrites the git history, so we need to be very careful when using it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Second problem and solution
&lt;/h2&gt;

&lt;p&gt;We have to rebase from &lt;strong&gt;release&lt;/strong&gt;, we have many commits, and we need to solve several conflicts on different painfully commits, we need to make our branch changes into one!&lt;/p&gt;

&lt;p&gt;First, we need to know how many commits do we want to add to &lt;strong&gt;release&lt;/strong&gt; and squash them.&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;# Being on the feature/my-tasty-feature branch&lt;/span&gt;

git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; HEAD~5 &lt;span class="c"&gt;# where five is the number of commits&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We replace all the first lines &lt;strong&gt;pick&lt;/strong&gt; for &lt;strong&gt;squash&lt;/strong&gt; except in the first line and save.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fh5xfptmpnqrcsacl3ujn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fh5xfptmpnqrcsacl3ujn.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Farxr6ftdute5fun5va7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Farxr6ftdute5fun5va7w.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can change the commit name and put something relevant, save the file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fi7qlkxyvbuhqv4co9k0c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fi7qlkxyvbuhqv4co9k0c.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F99kcy65673fnm9jhvkkr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F99kcy65673fnm9jhvkkr.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Done!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1h6sjduvwot1x6gtsz6k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1h6sjduvwot1x6gtsz6k.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we need to fix the conflict:&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;# Being on the feature/my-tasty-feature branch&lt;/span&gt;

git rebase origin/release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We fix the conflicts on our favorite editor and add the files, then&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;# Being on the feature/my-tasty-feature branch&lt;/span&gt;

git rebase &lt;span class="nt"&gt;--continue&lt;/span&gt;
git push &lt;span class="nt"&gt;-f&lt;/span&gt; feature/my-tasty-feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Third problem and solution
&lt;/h2&gt;

&lt;p&gt;In our GitHub pull request we have commits that don't belong to our branch, but are from &lt;strong&gt;release&lt;/strong&gt;, this might happen for two reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Because we didn't do the &lt;em&gt;first solution&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Because we updated the &lt;strong&gt;master&lt;/strong&gt; branch and some commit hashes have changed (This should seldom happen).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://es.atlassian.com/git/tutorials/rewriting-history/git-rebase" rel="noopener noreferrer"&gt;Check the link if you want to know more about how &lt;code&gt;rebase&lt;/code&gt; works&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this case, the best approach (or most straightforward) is usually to rebuild our branch. First, we need to know how many commits do we want to add to &lt;strong&gt;release&lt;/strong&gt; and squash them, so we'll do the &lt;em&gt;second solution&lt;/em&gt; entirely.&lt;/p&gt;

&lt;p&gt;After doing the second solution, we'll do the following.&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;# We are on the feature/my-tasty-feature branch&lt;/span&gt;

git fetch origin

git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature/my-backup-branch origin/feature/my-tasty-branch

&lt;span class="c"&gt;# We delete the branch we're going to rebuild locally&lt;/span&gt;

&lt;span class="c"&gt;# We are on feature/my-backup-branch&lt;/span&gt;
git branch &lt;span class="nt"&gt;-D&lt;/span&gt; feature/my-tasty-branch
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature/my-tasty-branch origin/release

git log feature/my-backup-branch

&lt;span class="c"&gt;# We are on feature/my-tasty-branch&lt;/span&gt;
&lt;span class="c"&gt;# We copy the last commit hash (see screenshot below)&lt;/span&gt;
git cherry-pick the-hash-we-have-copied
git push &lt;span class="nt"&gt;-f&lt;/span&gt; origin/feature/my-tasty-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5swzgk561fnx3941dpm8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5swzgk561fnx3941dpm8.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Done!&lt;/p&gt;

&lt;p&gt;These are my tips for people starting on my team when they have problems with Git, what do you think? Would you change anything? Any recommendations?&lt;/p&gt;

</description>
      <category>git</category>
    </item>
    <item>
      <title>CI/CD on a Hyperledger Fabric project</title>
      <dc:creator>Javier Aguirre</dc:creator>
      <pubDate>Mon, 20 May 2019 18:43:17 +0000</pubDate>
      <link>https://forem.com/wealize/ci-cd-on-a-hyperledger-fabric-project-83b</link>
      <guid>https://forem.com/wealize/ci-cd-on-a-hyperledger-fabric-project-83b</guid>
      <description>&lt;p&gt;Today we bring you the second post of this series of technical articles regarding development with Hyperledger Fabric.&lt;/p&gt;

&lt;p&gt;Last time we &lt;a href="https://dev.to/javaguirre/testing-chaincode-on-hyperledger-fabric-2j8k"&gt;talked about how we test our chaincode&lt;/a&gt;,&lt;br&gt;
today we go one step further and we’ll show you how we deploy the code automatically.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/26DNdV3b6dqn1jzR6/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/26DNdV3b6dqn1jzR6/giphy.gif" alt="" width="470" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CI/CD&lt;/strong&gt; is the combined practice of automating the testing of our application and the deployment of the application to our servers.&lt;/p&gt;

&lt;p&gt;Our workflow integrates different platforms in our pipeline, Github, Gitlab CI and IBM Blockchain. We store the code in Github, when we push code to Github it automatically goes to Gitlab CI where the automated tests are executed. If everything goes well we deploy the code to IBM automatically.&lt;/p&gt;
&lt;h1&gt;
  
  
  Continuous Integration
&lt;/h1&gt;

&lt;p&gt;Continuous Integration is a practice that requires developers to &lt;strong&gt;integrate&lt;/strong&gt; code into a shared repository several times a day. Every time the code is pushed to the code repository, the automated tests are executed.&lt;/p&gt;

&lt;p&gt;There are many cool CI services and we’ve used several of them, right now we’re happy with Gitlab CI, very easy to configure and full of possibilities!&lt;/p&gt;

&lt;p&gt;There are two phases on our CI/CD process: the testing and the deploy phase. You can have several phases in parallel, in the test phase we run three processes, backend, frontend, and chaincode testing. When the tests pass and if the rules are met, the application and chaincode are &lt;em&gt;deployed&lt;/em&gt;. :-)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/KsCtl2h2RZKso/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/KsCtl2h2RZKso/giphy.gif" alt="" width="361" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we’re gonna show you the configuration for the chaincode only since the rest of the application is well documented everywhere (we use industry standards such as Django, React, etc…).&lt;/p&gt;

&lt;p&gt;In the test phase we run the chaincode tests with this configuration, the steps are documented in the code snippet:&lt;/p&gt;


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


&lt;h1&gt;
  
  
  Continuous Delivery
&lt;/h1&gt;

&lt;p&gt;Every change that passes the automated tests is deployed to production automatically, so when the tests pass it’s time to deploy!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/CDZwopbecAbIc/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/CDZwopbecAbIc/giphy.gif" alt="" width="706" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This stage is executed only in two specific cases, for the &lt;strong&gt;staging&lt;/strong&gt; and the &lt;strong&gt;production&lt;/strong&gt; environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Staging&lt;/strong&gt;: When we push the changes to &lt;strong&gt;master&lt;/strong&gt; in Git&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production&lt;/strong&gt;: When we push the changes with a Git &lt;strong&gt;tag&lt;/strong&gt;. We use the following formats for the tags &lt;em&gt;vYYYY.MM.DD&lt;/em&gt; (Year.Month.Day)&lt;/li&gt;
&lt;/ul&gt;


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


&lt;p&gt;Each deploy consists of two API calls. The first one is used to &lt;strong&gt;install the chaincode in the platform&lt;/strong&gt;, the second one to &lt;strong&gt;instantiate the chaincode in one of our channels&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can read the &lt;a href="https://blockchain-starter.eu-gb.bluemix.net/api-docs/#/Channels/instantiateChaincode"&gt;IBM Blockchain API documentation&lt;/a&gt; to know what can you send on these API calls.&lt;/p&gt;

&lt;p&gt;The variables used within Gitlab CI are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NETWORK_ID&lt;/strong&gt;: network_id in IBM Network credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NETWORK_KEY&lt;/strong&gt;: key in IBM Network credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NETWORK_PASS&lt;/strong&gt;: secret in IBM Network credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CHANNEL_{ENVIRONMENT}_ID&lt;/strong&gt;: the channel is the name we added when we created the channel for this project (&lt;em&gt;defaultchannel&lt;/em&gt; by default on IBM Blockchain)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/javaguirre/24130c063131f7c5a0bee1022b4ebdac"&gt;See the entire example recipe to CI/CD Hyperledger Fabric on IBM Blockchain&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Enter IBM Blockchain
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VN96sW9U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/u2e5cnma6keaophto8d9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VN96sW9U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/u2e5cnma6keaophto8d9.png" alt="" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;IBM Blockchain&lt;/strong&gt; platform is, by far, the easiest way we used to build a Hyperledger Fabric network, it has also a nice API to interact with it remotely, it saves a lot of time and pain not needing to administer any of the typical components within a Fabric network. There are only some details we need to take into account when using it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When we deploy several smart contracts with the same name it might be difficult to know which is the last one deployed, there is no chaincode grouping by name.&lt;/li&gt;
&lt;li&gt;There is no way of archiving old chaincode release, so we end up with many chaincode versions in the chaincode list.&lt;/li&gt;
&lt;li&gt;There is no way of telling IBM Blockchain that my smart contract, built in Go, has an external dependency.&lt;/li&gt;
&lt;li&gt;Logging is not integrated in the platform, it opens a Kibana dashboard for us to see the logs (I’m not sure if this is good or bad, but the experience is weird).&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Once CI/CD is well configured, creating and instantiating chaincode on IBM Blockchain is a breeze, but there are some caveats we need to overcome to get the most of their platform.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/KINAUcarXNxWE/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/KINAUcarXNxWE/giphy.gif" alt="" width="500" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was written on my &lt;a href="https://javaguirre.me/2019/02/25/cicd-hyperledger-fabric-chaincode-golang"&gt;blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>hyperledger</category>
      <category>devops</category>
    </item>
    <item>
      <title>Testing chaincode on Hyperledger Fabric</title>
      <dc:creator>Javier Aguirre</dc:creator>
      <pubDate>Sun, 19 May 2019 22:10:20 +0000</pubDate>
      <link>https://forem.com/wealize/testing-chaincode-on-hyperledger-fabric-2j8k</link>
      <guid>https://forem.com/wealize/testing-chaincode-on-hyperledger-fabric-2j8k</guid>
      <description>&lt;p&gt;&lt;a href="https://www.hyperledger.org/"&gt;Hyperledger&lt;/a&gt; is the Blockchain family of tools and frameworks for permissioned networks. &lt;a href="https://theneonproject.org"&gt;We've&lt;/a&gt; been working with solutions built with &lt;a href="https://www.hyperledger.org/projects/fabric"&gt;Hyperledger Fabric&lt;/a&gt; for a while now.&lt;/p&gt;

&lt;p&gt;Hyperledger Fabric is a complex system to deploy and it’s important to be careful when we configure certificates, open ports or assign roles, among other things. Luckily there are some good documentation articles from Hyperledger you could read to extend your knowledge if you are interested, such as &lt;a href="https://hyperledger-fabric.readthedocs.io/en/latest/build_network.html"&gt;how to build your first network&lt;/a&gt; or &lt;a href="https://hyperledger-fabric.readthedocs.io/en/latest/write_first_app.html"&gt;writing your first application&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Our workflow integrates different platforms in our pipeline: It starts on Github, goes to Gitlab CI and finally deploys the smart contract on the IBM Blockchain platform.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8cnkWZv9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/kyselcfls5np9wnnms1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8cnkWZv9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/kyselcfls5np9wnnms1w.png" alt="" width="800" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today we want to talk about the first part that makes our development faster, the unit, integration and acceptance tests for the chaincode.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test all the things!
&lt;/h2&gt;

&lt;p&gt;We have automated testing at our core. &lt;a href="https://en.wikipedia.org/wiki/CI/CD"&gt;We apply Continuous Integration and Continuous Delivery&lt;/a&gt; in all our projects,&lt;br&gt;
so it made sense for us to create a more robust test suite for our chaincode.&lt;/p&gt;

&lt;p&gt;We decided to go with Go, static typing, Go structs and the &lt;a href="https://github.com/hyperledger/fabric-test"&gt;examples in the Hyperledger Fabric official repositories&lt;/a&gt; made testing easy and straightforward.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/LFmxDLUTQH7dS/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/LFmxDLUTQH7dS/giphy.gif" alt="" width="500" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make Hyperledger Fabric chaincode easier to test, the developers have created a &lt;a href="https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim#NewMockStub"&gt;MockStub&lt;/a&gt; struct. A mock is a service simulating functionality so you don’t call the real one while testing. For example, if we use a service to send SMS, we don’t want our tests to send SMS every time we run them, that’s why we usually use a mock, to simulate we call the method and its response. There are still several commands that &lt;a href="https://github.com/hyperledger/fabric/blob/release-1.4/core/chaincode/shim/mockstub.go#L282-L293"&gt;aren’t implemented in the mock needed for some of the MockStub&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Run the tests
&lt;/h2&gt;

&lt;p&gt;To run the tests locally, we use a &lt;em&gt;Dockerfile&lt;/em&gt; that builds our environment. The &lt;strong&gt;Dockerfile&lt;/strong&gt; would be something like this:&lt;/p&gt;


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


&lt;p&gt;We’re using &lt;strong&gt;Go v1.10&lt;/strong&gt; and copying our project code to &lt;strong&gt;/go/src/app&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We need to install the dependencies, we’ll use &lt;a href="https://github.com/hyperledger/fabric-sdk-go"&gt;hyperledger/fabric-sdk-go&lt;/a&gt;, &lt;a href="https://godoc.org/github.com/pgpst/pgpst/internal/github.com/stretchr/testify/assert"&gt;testify/assert&lt;/a&gt; to have a nice way of asserting in our tests and optionally if we do acceptance tests, &lt;a href="https://github.com/DATA-DOG/godog"&gt;cmd/godog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We’ll need &lt;strong&gt;libltdl-dev&lt;/strong&gt; and install in the Fabric library manually in the &lt;strong&gt;$GOPATH&lt;/strong&gt;, it didn’t work for us at the time, but this might be easier with the new version of Fabric.&lt;/p&gt;

&lt;p&gt;We define the path where our chaincode lives (&lt;em&gt;$GOPATH/src/gitlab.com/TheNeonProject/mychaincode&lt;/em&gt;) and run the tests with go test -v ..&lt;/p&gt;

&lt;p&gt;To run this locally we use two commands, one to build the Docker container, and another one to run the tests.&lt;/p&gt;


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


&lt;p&gt;We’ll get a response like this if everything went nicely.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sY3Bh4A1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/4e4t4d7fwyov2kzjrwai.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sY3Bh4A1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/4e4t4d7fwyov2kzjrwai.png" alt="" width="800" height="563"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Code Example
&lt;/h1&gt;

&lt;p&gt;But talk is cheap, so we’ll show you a code example. :-)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/r056JQBFkE8QE/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/r056JQBFkE8QE/giphy.gif" alt="" width="440" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you have a chaincode example with a method &lt;code&gt;getAsset&lt;/code&gt;. Read through to see how it looks and we’ll explain right afterwards.&lt;/p&gt;


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


&lt;p&gt;This code is for a smart contract with a method getAsset.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Invoke&lt;/strong&gt; method is the entry point when calling our smart contract via &lt;em&gt;RPC&lt;/em&gt;; if the method is not supported it will return an error.&lt;br&gt;
That would be a very good initial test to check if our test environment is correctly configured. :-)&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;getObjectAsBytes&lt;/strong&gt; method is just used to return a saved object as a response in the method call.&lt;/p&gt;

&lt;p&gt;So going back to the &lt;strong&gt;getAsset&lt;/strong&gt; method, it receives a parameter, which is the ID of the resource and, if it exists, it returns the result as JSON.&lt;/p&gt;

&lt;p&gt;Now you know what the code does, let’s create some tests for this beast, because, as great chefs do, we always need to taste the recipe before serving.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l2YWuhILzuqDcexaw/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l2YWuhILzuqDcexaw/giphy.gif" alt="" width="480" height="204"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Tests
&lt;/h1&gt;

&lt;p&gt;We’re going to &lt;strong&gt;create a test suite with two main test cases&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test when the ID sent doesn’t exist, we’ll assert the error.&lt;/li&gt;
&lt;li&gt;Test when the ID sent does exist, we’ll assert the response is good and an attribute of the object (the name) is present.&lt;/li&gt;
&lt;/ul&gt;


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


&lt;p&gt;We follow &lt;a href="http://wiki.c2.com/?ArrangeActAssert"&gt;AAA (Arrange Act Asset)&lt;/a&gt; principle to see the different parts of the test cases easily. In the different part of the test cases we can see:&lt;/p&gt;

&lt;p&gt;In this case, the &lt;strong&gt;Arrange&lt;/strong&gt; would need to initialize the smart contract “connection” and, in case of a valid id, &lt;strong&gt;create the Asset with its name&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Act&lt;/strong&gt; part of the test, we’ll do mostly the same, use the method name, the ID, and in case of creation or append(edit), the JSON object&lt;br&gt;
with the payload.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Assert&lt;/strong&gt; we’ll check if the response is &lt;em&gt;OK&lt;/em&gt; or &lt;em&gt;Error&lt;/em&gt;, and we can also check with the variables &lt;strong&gt;res.Message&lt;/strong&gt; or &lt;strong&gt;res.Payload&lt;/strong&gt; if the content&lt;br&gt;
of the response is what the right one.&lt;/p&gt;

&lt;p&gt;That’s it for now! In following articles we’ll talk about how to do BDD for the chaincode, data format manipulation for chaincode methods and Continuous Integration / Continuous Deployment for our chaincode on an Hyperledger Fabric network.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/ch1Z4rUWBZBnO/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/ch1Z4rUWBZBnO/giphy.gif" alt="" width="400" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post was written appeared first on my &lt;a href="https://javaguirre.me/2019/01/21/testing-chaincode-on-hyperledger-fabric"&gt;blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>hyperledger</category>
    </item>
  </channel>
</rss>
