<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Jean Emer</title>
    <description>Personal website and blog</description>
    <link>http://jcemer.com</link>
    <atom:link href="http://jcemer.com/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>Types in JavaScript: why you should care</title>
        <description>&lt;p&gt;In simple terms, a type helps group similar values on which common operations can be performed. Based on our Mathematical knowledge, it is easy to identify that it is possible to sum the values in the sequence &lt;code&gt;11&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;, &lt;code&gt;67&lt;/code&gt;, and &lt;code&gt;89&lt;/code&gt;. At the same time, we know that we can&amp;#39;t multiply the values in the following sequence &lt;code&gt;JS&lt;/code&gt;, &lt;code&gt;is&lt;/code&gt;, and &lt;code&gt;cool&lt;/code&gt;, but we can naturally merge them. Numbers and strings are the most popular types.&lt;/p&gt;

&lt;p&gt;In a programming language, the types are what determine the amount of memory allocated to save a value. The type of a value also determine the operations and methods allowed to be performed on it.&lt;/p&gt;

&lt;p&gt;JavaScript has six primitives types: &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;undefined&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt;, &lt;code&gt;boolean&lt;/code&gt;, and &lt;code&gt;symbol&lt;/code&gt;. There is also a compound type or &lt;code&gt;object&lt;/code&gt;. Interestingly, the primitive types are &lt;strong&gt;immutable and don&amp;#39;t have properties&lt;/strong&gt;. For example, because of the &lt;code&gt;String&lt;/code&gt; object you can retrieve the length of a string. The code &lt;code&gt;&amp;quot;a&amp;quot;.length&lt;/code&gt; is evaluated as &lt;code&gt;new String(&amp;quot;a&amp;quot;).length&lt;/code&gt; by the interpreter like magic. There are also the objects &lt;code&gt;Number&lt;/code&gt;, &lt;code&gt;Boolean&lt;/code&gt;, and &lt;code&gt;Symbol&lt;/code&gt; which also add properties to its own primitives.&lt;/p&gt;

&lt;p&gt;The types in JavaScript look simple and useless but knowing how they work is important. They help give a better understanding of the language and its behavior.&lt;/p&gt;

              &lt;h1 id=&quot;Dynamic-type-checking&quot;&gt;
                &lt;a name=&quot;Dynamic-type-checking&quot; href=&quot;#Dynamic-type-checking&quot;&gt;&lt;/a&gt;Dynamic type checking
              &lt;/h1&gt;
            
&lt;p&gt;Types are one of the main foundations of a programming language. Many execution errors in JavaScript are type errors. For example, when we try to multiply a &lt;code&gt;number&lt;/code&gt; by a &lt;code&gt;string&lt;/code&gt; we get a silent error in the form of &lt;code&gt;Not a Number&lt;/code&gt; returned. Have you ever called a function and received the error &lt;code&gt;undefined is not a function&lt;/code&gt;? This happens when we try to access a property that is not defined. Since Javascript cannot locate the property it returns its default fallback value: &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another common type-related mistake is when we try to change or access a property from a value that is &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;. Keep in mind that there aren&amp;#39;t constructors like &lt;code&gt;Undefined&lt;/code&gt; or &lt;code&gt;Null&lt;/code&gt; to save us here. We end up with an error. Not to mention all the times that we mistake the value type of &lt;code&gt;this&lt;/code&gt; and try forbidden things on it.&lt;/p&gt;

&lt;p&gt;A good type system helps us avoid these common mistakes. By definition JavaScript is an interpreted and dynamic language and it requires that the type system works during the code execution. The language also tries to help by silently converting value types. It works in your favor when you multiply &lt;code&gt;2&lt;/code&gt; by &lt;code&gt;&amp;#39;3&amp;#39;&lt;/code&gt; and not so much when you are trying to sum a number with a &lt;code&gt;string&lt;/code&gt; that contains a number. :sweat_smile:&lt;/p&gt;

&lt;p&gt;Type changing or coercion is the reason many developers switch over to strictly using &lt;code&gt;===&lt;/code&gt; for checking the equality of values, but there is a lot more to it than that as &lt;a href=&quot;https://davidwalsh.name/fixing-coercion&quot;&gt;Fixing Coercion, Not The Symptoms&lt;/a&gt; explains.&lt;/p&gt;

&lt;p&gt;In essence, &lt;strong&gt;types in JavaScript are a moving target, it is difficult to hit them&lt;/strong&gt;. Besides it isn&amp;#39;t possible to predict or assure the variable type since the language is weakly typed and that type may change.&lt;/p&gt;

              &lt;h1 id=&quot;Static-type-checking&quot;&gt;
                &lt;a name=&quot;Static-type-checking&quot; href=&quot;#Static-type-checking&quot;&gt;&lt;/a&gt;Static type checking
              &lt;/h1&gt;
            
&lt;p&gt;Static type checking ensures that the program is correct, at least statically prior to execution. There are alternative ways to annotate the value types in JavaScript. It avoids you to bug the user trying to operate different types in a crazy way.&lt;/p&gt;

&lt;p&gt;The code below calculates the price of a &lt;code&gt;Product&lt;/code&gt;. From lines 4 to 6, we define the type of the &lt;code&gt;Product&lt;/code&gt; properties with the &lt;a href=&quot;https://flow.org/&quot;&gt;Flow&lt;/a&gt; annotation. The rest of the code is plain JavaScript but notice there is a value incompatibility at the line 19. This is the kind of code that gifts you with a &lt;code&gt;NaN&lt;/code&gt; value. Fortunately, the Flow analyzer warns you know about that potential error while writing the code.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a name=&quot;line-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;cm&quot;&gt;/* @flow */&lt;/span&gt;
&lt;a name=&quot;line-2&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-3&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kr&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Product&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-4&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt;
&lt;a name=&quot;line-5&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;nx&quot;&gt;cost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;
&lt;a name=&quot;line-6&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;nx&quot;&gt;tax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;
&lt;a name=&quot;line-7&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-8&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;nx&quot;&gt;constructor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-9&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;
&lt;a name=&quot;line-10&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cost&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cost&lt;/span&gt;
&lt;a name=&quot;line-11&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tax&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tax&lt;/span&gt;
&lt;a name=&quot;line-12&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;a name=&quot;line-13&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-14&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;nx&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-15&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cost&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;a name=&quot;line-16&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;a name=&quot;line-17&quot;&gt;&lt;/a&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;a name=&quot;line-18&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-19&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Banana&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;%30&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The Flow annotation allows you to define all the different &lt;a href=&quot;https://flow.org/en/docs/types/primitives/&quot;&gt;primitives&lt;/a&gt;,
&lt;a href=&quot;https://flow.org/en/docs/types/objects/&quot;&gt;objects&lt;/a&gt;, &lt;a href=&quot;https://flow.org/en/docs/types/classes/&quot;&gt;constructors/classes&lt;/a&gt; (&lt;code&gt;Date&lt;/code&gt;, &lt;code&gt;Array&lt;/code&gt;, ...) and even &lt;a href=&quot;https://flow.org/en/docs/types/literals/&quot;&gt;literals&lt;/a&gt;. There are some advanced types like &lt;a href=&quot;https://flow.org/en/docs/types/any/&quot;&gt;&lt;em&gt;any&lt;/em&gt;&lt;/a&gt; which accepts all types; &lt;a href=&quot;https://flow.org/en/docs/types/maybe/&quot;&gt;&lt;em&gt;nullable&lt;/em&gt; or &lt;em&gt;maybe&lt;/em&gt;&lt;/a&gt;, to indicate a type or &lt;code&gt;null&lt;/code&gt;; and also  &lt;a href=&quot;https://flow.org/en/docs/types/unions/&quot;&gt;unions&lt;/a&gt; and &lt;a href=&quot;https://flow.org/en/docs/types/intersections/&quot;&gt;intersections&lt;/a&gt; of types and interfaces (more about that below).&lt;/p&gt;

&lt;p&gt;IMHO, the most powerful annotations are the &lt;a href=&quot;https://flow.org/en/docs/types/aliases/&quot;&gt;new types or &lt;em&gt;aliases&lt;/em&gt;&lt;/a&gt;, that allow you to give a name to a group of types for exclusive properties; &lt;a href=&quot;https://flow.org/en/docs/types/interfaces/&quot;&gt;interfaces&lt;/a&gt; which define a non-exclusive group of important properties or methods that a context is concerned about; and &lt;a href=&quot;https://flow.org/en/docs/types/generics/&quot;&gt;&lt;em&gt;generics&lt;/em&gt;&lt;/a&gt;. This last one, allows you to define the type of an array&amp;#39;s values or the type of the result of a &lt;code&gt;Promise&lt;/code&gt; for example.&lt;/p&gt;

&lt;p&gt;According to &lt;a href=&quot;https://www.youtube.com/watch?v=6mUAvd6i4OU&quot;&gt;Kris Jenkins&lt;/a&gt;, through type definition, it is possible to predict design problems. A function that returns many different types could mean a fault in planning. The creation of new types helps the programmer define the problem&amp;#39;s entities. In any case, type annotation is a good resource to write safer and more understandable code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A Type System is, first and foremost a communication mechanism - Sarah Mei&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Besides Flow, there is also &lt;a href=&quot;https://www.typescriptlang.org/&quot;&gt;TypeScript&lt;/a&gt; language which is statically typed with a syntax close to JavaScript. But bear in mind that Flow or TypeScript code needs conversion to JavaScript before running on the client machine. Type annotation requires effort not without meaningful outcome. The paper &lt;a href=&quot;http://ttendency.cs.ucl.ac.uk/projects/type_study/documents/type_study.pdf&quot;&gt;To Type or Not to Type: Quantifying Detectable Bugs in JavaScript&lt;/a&gt; concludes that a type analyzer could catch around 15% of production &lt;em&gt;bugs&lt;/em&gt; in a reviewed and test covered codebase. It is quite impressive.&lt;/p&gt;

              &lt;h2 id=&quot;IO-Data&quot;&gt;
                &lt;a name=&quot;IO-Data&quot; href=&quot;#IO-Data&quot;&gt;&lt;/a&gt;IO Data
              &lt;/h2&gt;
            
&lt;p&gt;Programs in general and special interface code get a lot of external values to work with which means static analyzers require a contract declaring the types of the external data. The TypeScript code below indicates that the API response is a list of strings:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a name=&quot;line-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kr&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ItemsResponse&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-2&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;nx&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;a name=&quot;line-3&quot;&gt;&lt;/a&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;a name=&quot;line-4&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-5&quot;&gt;&lt;/a&gt;&lt;span class=&quot;nx&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ItemsResponse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/api/items&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;a name=&quot;line-6&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-7&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;results&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;results&lt;/span&gt;
&lt;a name=&quot;line-8&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;From this annotation, the rest of of the code is analyzed to ensure that all references match. &lt;strong&gt;The static analyzer, however, works if this contract is respected&lt;/strong&gt;. If the production API returns something other than &lt;code&gt;strings&lt;/code&gt;, the risk of a runtime execution error is high.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;any&lt;/code&gt; is the type of &lt;a href=&quot;https://github.com/facebook/flow/blob/0d385002cef6601cf741ffe917e7410a996bb265/lib/bom.js#L557&quot;&gt;all JavaScript&lt;/a&gt; &lt;a href=&quot;https://github.com/facebook/flow/blob/4eb62a5597d59174531d44e532c65daa25d8331b/lib/streams.js#L54&quot;&gt;APIs that return&lt;/a&gt; data from abroad. And by definition, the &lt;code&gt;any&lt;/code&gt; could be converted to a more specific type. Quoting the Flow documentation: using any is completely unsafe, and should be avoided whenever possible. But talking about external data it looks like anything could be done. It looks...&lt;/p&gt;

              &lt;h3 id=&quot;Elm&quot;&gt;
                &lt;a name=&quot;Elm&quot; href=&quot;#Elm&quot;&gt;&lt;/a&gt;Elm
              &lt;/h3&gt;
            
&lt;p&gt;There is a language catching a lot of attention that ensures there are no runtime execution errors at all. &lt;a href=&quot;http://elm-lang.org/&quot;&gt;Elm&lt;/a&gt; is a statically typed language for the web with a syntax and paradigm different than JavaScript.&lt;/p&gt;

&lt;p&gt;Let&amp;#39;s go back to our &lt;code&gt;Product&lt;/code&gt; with price calculation. In the code below you&amp;#39;ll see that the way to solve the problem isn&amp;#39;t close to the Object Oriented JavaScript World™. Lines 1 to 5, 7, 11, and 14 are strictly responsible for type annotation. Lines 8 and 9 define the global price calculation and line 12 defines a sample product. Finally, the price calculation is performed on line 15.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a name=&quot;line-1&quot;&gt;&lt;/a&gt;type alias Product =
&lt;a name=&quot;line-2&quot;&gt;&lt;/a&gt;  { name : String
&lt;a name=&quot;line-3&quot;&gt;&lt;/a&gt;  , cost : Float
&lt;a name=&quot;line-4&quot;&gt;&lt;/a&gt;  , tax : Float
&lt;a name=&quot;line-5&quot;&gt;&lt;/a&gt;  }
&lt;a name=&quot;line-6&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-7&quot;&gt;&lt;/a&gt;price : Product -&amp;gt; Float
&lt;a name=&quot;line-8&quot;&gt;&lt;/a&gt;price {cost,tax} =
&lt;a name=&quot;line-9&quot;&gt;&lt;/a&gt;  cost * (tax + 1)
&lt;a name=&quot;line-10&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-11&quot;&gt;&lt;/a&gt;item : Product
&lt;a name=&quot;line-12&quot;&gt;&lt;/a&gt;item = { name = &amp;quot;Banana&amp;quot;, cost = 2, tax = 0.3 }
&lt;a name=&quot;line-13&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-14&quot;&gt;&lt;/a&gt;itemPrice : Float
&lt;a name=&quot;line-15&quot;&gt;&lt;/a&gt;itemPrice = price item
&lt;a name=&quot;line-16&quot;&gt;&lt;/a&gt;-- 2.6 : Float
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All of this is pretty impressive for the purpose of this post, the most important takeaway is the decoders. Elm requires you to define and test all the types of the IO data. A decoder can return &lt;code&gt;Err&lt;/code&gt; with a message (like on the line 6 below) or an &lt;code&gt;Ok&lt;/code&gt; with the decoded data (line 10).&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a name=&quot;line-1&quot;&gt;&lt;/a&gt;import Json.Decode exposing (..)
&lt;a name=&quot;line-2&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-3&quot;&gt;&lt;/a&gt;resultsDecoder = field &amp;quot;results&amp;quot; (list string)
&lt;a name=&quot;line-4&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-5&quot;&gt;&lt;/a&gt;decodeString resultsDecoder &amp;quot;bla&amp;quot;
&lt;a name=&quot;line-6&quot;&gt;&lt;/a&gt;Err &amp;quot;Given an invalid JSON: Unexpected token b in JSON…&amp;quot;
&lt;a name=&quot;line-7&quot;&gt;&lt;/a&gt;    : Result.Result String (List String)
&lt;a name=&quot;line-8&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-9&quot;&gt;&lt;/a&gt;decodeString resultsDecoder &amp;quot;{ \&amp;quot;results\&amp;quot;: [\&amp;quot;1\&amp;quot;, \&amp;quot;2\&amp;quot;] }&amp;quot;
&lt;a name=&quot;line-10&quot;&gt;&lt;/a&gt;Ok [&amp;quot;1&amp;quot;,&amp;quot;2&amp;quot;] : Result.Result String (List String)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The code must thread the two possible cases in runtime execution: the &lt;code&gt;Ok&lt;/code&gt; and the &lt;code&gt;Err&lt;/code&gt;. This is one of the secrets for how maintain a language without runtime exceptions.&lt;/p&gt;

              &lt;h3 id=&quot;JavaScript-counter-attacks&quot;&gt;
                &lt;a name=&quot;JavaScript-counter-attacks&quot; href=&quot;#JavaScript-counter-attacks&quot;&gt;&lt;/a&gt;JavaScript counter-attacks
              &lt;/h3&gt;
            
&lt;p&gt;The JavaScript ecosystem already has libraries which check value types at runtime. The code below throws an exception if the API we already know returns something other than &lt;code&gt;strings&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-JavaScript&quot; data-lang=&quot;JavaScript&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a name=&quot;line-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;tcomb&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;a name=&quot;line-2&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-3&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Results&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
&lt;a name=&quot;line-4&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;nx&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;a name=&quot;line-5&quot;&gt;&lt;/a&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Results&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;a name=&quot;line-6&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-7&quot;&gt;&lt;/a&gt;&lt;span class=&quot;nx&quot;&gt;Results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
&lt;a name=&quot;line-8&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;nx&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;a name=&quot;line-9&quot;&gt;&lt;/a&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;a name=&quot;line-10&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-11&quot;&gt;&lt;/a&gt;&lt;span class=&quot;nx&quot;&gt;Results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
&lt;a name=&quot;line-12&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;nx&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;a name=&quot;line-13&quot;&gt;&lt;/a&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;a name=&quot;line-14&quot;&gt;&lt;/a&gt;&lt;span class=&quot;c1&quot;&gt;// TypeError: [tcomb] Invalid value 2 supplied to Results/results: Array&amp;lt;String&amp;gt;/0: String&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Libraries like &lt;a href=&quot;https://github.com/gcanti/tcomb&quot;&gt;tcomb&lt;/a&gt; and &lt;a href=&quot;https://github.com/phadej/typify&quot;&gt;typify&lt;/a&gt; check types on the client machine. As a proof of concept, I drafted a simple &lt;a href=&quot;https://gist.github.com/jcemer/f4bef63864f73307df44d3ddc2383214&quot;&gt;example using the Elm Result (&lt;code&gt;Ok&lt;/code&gt; and &lt;code&gt;Err&lt;/code&gt;) concept with typify in JavaScript&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now that you&amp;#39;re aware of all of the problems and outcomes, &lt;strong&gt;remember that you just need to cover all of the possible cases of your code scope (using any language or library) to avoid runtime execution errors&lt;/strong&gt;. Type annotation and runtime type checking are great allies that help with that task.&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;Thanks to &lt;a href=&quot;http://www.irasantiago.com/&quot;&gt;Ira Santiago&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Mon, 13 Nov 2017 00:00:00 +0000</pubDate>
        <link>http://jcemer.com/types-in-javascript-what-you-should-care.html</link>
        <guid isPermaLink="true">http://jcemer.com/types-in-javascript-what-you-should-care.html</guid>
      </item>
    
      <item>
        <title>Client, Network, Server and Application Caching on the Web</title>
        <description></description>
        <pubDate>Mon, 17 Apr 2017 00:00:00 +0000</pubDate>
        <link>http://jcemer.com/client-network-server-and-application-caching-on-the-web.html</link>
        <guid isPermaLink="true">http://jcemer.com/client-network-server-and-application-caching-on-the-web.html</guid>
      </item>
    
      <item>
        <title>Front-end (React) Snapshot Testing with Jest: What is it for?</title>
        <description></description>
        <pubDate>Tue, 11 Apr 2017 00:00:00 +0000</pubDate>
        <link>http://jcemer.com/front-end-react-snapshot-testing-with-jest-what-is-it-for.html</link>
        <guid isPermaLink="true">http://jcemer.com/front-end-react-snapshot-testing-with-jest-what-is-it-for.html</guid>
      </item>
    
      <item>
        <title>Você é irresponsável por não escrever testes de Front-end?</title>
        <description>&lt;p&gt;Nesta semana tivemos o 1º Meetup do Facebook Developer Circle — React em Porto Alegre. O evento atraiu uma audiência bem diversa e graças a seu formato, trouxe uma discussão muito interessante: &lt;strong&gt;qual a importância de testes no desenvolvimento de código&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Apesar de o assunto não ser novidade para mim, já ouço falar sobre testes há quase uma década, toda vez que acompanho uma discussão a respeito, aprendo um pouco mais. Com certeza não sou um especialista no assunto, estou bem longe disto, mas gostaria de sumarizar neste texto aquilo que já aprendi.&lt;/p&gt;

&lt;p&gt;Em primeira análise, é importante destacar que existem diferentes tipos de testes que garantem o correto funcionamento e adequação de diferentes aspectos de um projeto. Aqui, irei me deter muito mais aos &lt;strong&gt;testes unitários&lt;/strong&gt;, que são aqueles que se propõe a garantir o correto funcionamento das menores porções de uma aplicação.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s absolutely irresponsible not to write automated [unit] tests as part of software development and you should avoid jobs at companies that don’t do it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O trecho acima, extraído de uma &lt;a href=&quot;https://www.quora.com/Would-you-work-for-a-company-who-doesnt-write-tests/answer/Tim-Moore-2?srid=OBCN&quot;&gt;discussão sobre empresas em que programadores não escrevem testes unitários&lt;/a&gt;, poderia facilmente encerrar qualquer debate sobre a necessidade ou não de se manter testes de código. Porém, Desenvolvimento Web nem sempre é sobre Desenvolvimento de Software e saber como e o que testar nem sempre é algo simples.&lt;/p&gt;

              &lt;h2 id=&quot;Tipos-de-projetos&quot;&gt;
                &lt;a name=&quot;Tipos-de-projetos&quot; href=&quot;#Tipos-de-projetos&quot;&gt;&lt;/a&gt;Tipos de projetos
              &lt;/h2&gt;
            
&lt;p&gt;A primeira metade da minha carreira dediquei ao desenvolvimento de páginas Web estáticas e bem simples. Passei mais de meia década criando diversos Websites institucionais e não tenho vergonha alguma de dizer que, naquela época, não sabia ao menos como escrever uma única linha de testes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Web development can range from developing the simplest static single page of plain text to the most complex web-based internet applications, electronic businesses, and social network services. — Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Até mesmo hoje, ainda mantenho alguns projetos sem nenhum teste. Indo um pouco além, acredito que projetos que são &lt;strong&gt;simples&lt;/strong&gt; e que serão desenvolvidos em &lt;strong&gt;poucas semanas&lt;/strong&gt;, não necessitam da escrita de testes. Mesmo porque, é inegável que existe um custo atrelado a esta prática.&lt;/p&gt;

&lt;p&gt;Por outro lado, 1) projetos que tomarão meses para serem escritos, 2) projetos que terão alguns ciclos de desenvolvimento ou 3) possuem &lt;a href=&quot;https://github.com/jcemer/minimalistic-shop&quot;&gt;lógicas até mesmo pouco complexas&lt;/a&gt;, são Aplicações Web ou Projetos de Software e &lt;strong&gt;devem ser acompanhados por testes&lt;/strong&gt;. Nestes casos, o custo de escrita de testes torna-se rapidamente um investimento.&lt;/p&gt;

              &lt;h2 id=&quot;Aplicações-Web-sem-testes&quot;&gt;
                &lt;a name=&quot;Aplicações-Web-sem-testes&quot; href=&quot;#Aplicações-Web-sem-testes&quot;&gt;&lt;/a&gt;Aplicações Web sem testes
              &lt;/h2&gt;
            
&lt;p&gt;Como apontado em &lt;a href=&quot;http://blog.codeclimate.com/blog/2013/12/05/refactoring-without-good-tests/&quot;&gt;Refactoring Without Good Tests&lt;/a&gt;, em códigos sem testes não é possível identificar se mudanças irão quebrar outras partes da aplicação. &lt;strong&gt;Não existe refactoring em código sem testes&lt;/strong&gt;. Além disto, testes unitários reforçam boas práticas, podem antecipar a identificação de falhas no código e servem como documentação de funcionalidades.&lt;/p&gt;

&lt;p&gt;Este círculo vicioso explica facilmente a falácia de desenvolvedores muito ocupados para escrever testes: 1) estes perdem muito tempo experimentando o impacto de novas funcionalidades, 2) corrigindo bugs que já estão em produção ou 3) tentando entender decisões de design de código infelizes as quais tem &lt;strong&gt;medo de alterar&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Alguns dos argumentos contra a escrita de testes apontam que a suíte para determinado projeto seria impraticável e lenta e que um roll-out faseado (deploy para uma pequena porção de clientes) permite melhor identificar bugs através de usuários reais. O que foi apontado até aqui e ainda mais pagar o preço da frustração de alguns usuários tornam argumentos como estes inválidos. Ainda, estes argumentos evidenciam decisões ruins de design e arquitetura de um projeto.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Aplicações Web mantidas sem nenhum tipo de teste e com uma equipe de desenvolvimento sem planos para reverter esta situação indicam uma cultura de desenvolvimento envenenada. — eu mesmo é que acho isto!&lt;/p&gt;
&lt;/blockquote&gt;

              &lt;h2 id=&quot;Aprendendo-a-testar&quot;&gt;
                &lt;a name=&quot;Aprendendo-a-testar&quot; href=&quot;#Aprendendo-a-testar&quot;&gt;&lt;/a&gt;Aprendendo a testar
              &lt;/h2&gt;
            
&lt;p&gt;Apesar de existirem diversas teorias que você já deve conhecer, &lt;strong&gt;enxergar valor na escrita de testes&lt;/strong&gt; vai muito além do bê-a-bá do &lt;a href=&quot;https://martinfowler.com/articles/is-tdd-dead/&quot;&gt;Test-driven Development&lt;/a&gt; (TDD). A falta de prática e experiência é um dos principais motivos de vermos tantos projetos com testes pouco úteis ou ausentes.&lt;/p&gt;

&lt;p&gt;O que melhor funcionou nos projetos em que já trabalhei foi enxergar as &lt;a href=&quot;http://muness.blogspot.com.br/2008/04/testing-declarative-code.html&quot;&gt;porções de código que não são declarativas&lt;/a&gt; e garantir que estas sejam testadas. &lt;strong&gt;Código Front-end sempre terá muitas porções declarativas&lt;/strong&gt; e não costumo escrever testes unitários para estas porções. Nunca tive pretenção de seguir TDD a risca.&lt;/p&gt;

&lt;p&gt;Em outras palavras, acredito apenas que código que possui diferentes fluxos deva ser testado. Simples assim. Seguindo esta prática, o código abaixo não teria testes:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a name=&quot;line-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CartItem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;quantity&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-2&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;a name=&quot;line-3&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;ui item&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;a name=&quot;line-4&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;ui tiny image&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;a name=&quot;line-5&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;img&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;alt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`Product &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;a name=&quot;line-6&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;/div&amp;gt;&lt;/span&gt;
&lt;a name=&quot;line-7&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;middle aligned content&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;a name=&quot;line-8&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;ui tiny header&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Product&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;/div&amp;gt;&lt;/span&gt;
&lt;a name=&quot;line-9&quot;&gt;&lt;/a&gt;        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Quantity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;quantity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;/div&amp;gt;&lt;/span&gt;
&lt;a name=&quot;line-10&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;/div&amp;gt;&lt;/span&gt;
&lt;a name=&quot;line-11&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;/div&amp;gt;&lt;/span&gt;
&lt;a name=&quot;line-12&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;a name=&quot;line-13&quot;&gt;&lt;/a&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Por outra lado, o código abaixo, apesar de parecer mais simples, possui a lógica relacionada a capacidade de um produto ser adicionado ao carrinho de compras. Este código deve ser testado.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a name=&quot;line-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AddToCartButton&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addToCart&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-2&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;disabled&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remaining&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;a name=&quot;line-3&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-4&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;a name=&quot;line-5&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;disabled&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;disabled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;disabled&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addToCart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;a name=&quot;line-6&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;nx&quot;&gt;Add&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cart&lt;/span&gt;
&lt;a name=&quot;line-7&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;/button&amp;gt;&lt;/span&gt;
&lt;a name=&quot;line-8&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;a name=&quot;line-9&quot;&gt;&lt;/a&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Existem diversas ferramentas para testar código Front-end. Por este exemplo se tratar de código React, uma das melhores alternativas da atualidade para escrita de testes unitários é o framework Jest com a biblioteca Enzyme. O Jest é o framework padrão do projeto &lt;a href=&quot;https://github.com/facebookincubator/create-react-app&quot;&gt;Create React App&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a name=&quot;line-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;lt;AddToCartButton /&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-2&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;with remaning stock&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-3&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addToCart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;jest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;a name=&quot;line-4&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wrapper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;shallow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AddToCartButton&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;123&amp;#39;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addToCart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addToCart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;a name=&quot;line-5&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-6&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;nx&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;should render a enable button&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-7&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;nx&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;disabled&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toBe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;a name=&quot;line-8&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;a name=&quot;line-9&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-10&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;nx&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;should call add to cart on click&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-11&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;nx&quot;&gt;wrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;simulate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;click&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;a name=&quot;line-12&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-13&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;nx&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addToCart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;123&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;a name=&quot;line-14&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;a name=&quot;line-15&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;a name=&quot;line-16&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-17&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;with no remaning stock&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-18&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addToCart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;jest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;a name=&quot;line-19&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wrapper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;shallow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AddToCartButton&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;123&amp;#39;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addToCart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addToCart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;a name=&quot;line-20&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-21&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;nx&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;should render a disabled button with&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-22&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;nx&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;disabled&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toBe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;a name=&quot;line-23&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;a name=&quot;line-24&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-25&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;nx&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;should call add to cart on click&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-26&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;nx&quot;&gt;wrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;simulate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;click&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;a name=&quot;line-27&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-28&quot;&gt;&lt;/a&gt;      &lt;span class=&quot;nx&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addToCart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;not&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toHaveBeenCalled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;a name=&quot;line-29&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;a name=&quot;line-30&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;a name=&quot;line-31&quot;&gt;&lt;/a&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note que o exemplo acima explora muito bem os dois possíveis fluxos de execução do nosso componente: 1) quando há items em estoque e 2) quando não há items em estoque. A partir destes fluxos, o botão pode estar habilitado ou inabilitado e a função &lt;code&gt;addToCart&lt;/code&gt; é chamada ou não a partir do clique do usuário.&lt;/p&gt;

              &lt;h2 id=&quot;Criando-uma-cultura-de-testes&quot;&gt;
                &lt;a name=&quot;Criando-uma-cultura-de-testes&quot; href=&quot;#Criando-uma-cultura-de-testes&quot;&gt;&lt;/a&gt;Criando uma cultura de testes
              &lt;/h2&gt;
            
&lt;p&gt;Escrever testes não deve ser difícil ou doloroso. O primeiro passo para incorporar o hábito de testar código em um projeto é &lt;strong&gt;escolher e configurar de maneira adequada as ferramentas que permitam sua escrita&lt;/strong&gt;. Todos os desenvolvedores devem prezar pela evolução e funcionamento do ecossistema de testes.&lt;/p&gt;

&lt;p&gt;A partir deste ponto, é importante revisar o código dos pares e promover tech talks para aprimorar o conhecimento e experiência de escrita de testes na equipe. Os testes devem ser executados de maneira automatizada a cada mudança de código.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So, if you are going to touch the code, for bug fixes or refactoring, then first write the unit tests. For bugs unit tests will help prove where the problem is, as you can duplicate it. — James Black on &lt;a href=&quot;http://stackoverflow.com/a/1541596&quot;&gt;Stack Overflow&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para projetos legados que não tenham testes, escrever &lt;strong&gt;testes antes de alterar qualquer porção de código é uma ótima regra&lt;/strong&gt; que pode e deve ser incorporada na equipe. Isto aumenta aos poucos a cobertura de testes do projeto e permite praticar refactoring.&lt;/p&gt;

              &lt;h2 id=&quot;Além-dos-testes-unitários&quot;&gt;
                &lt;a name=&quot;Além-dos-testes-unitários&quot; href=&quot;#Além-dos-testes-unitários&quot;&gt;&lt;/a&gt;Além dos testes unitários
              &lt;/h2&gt;
            
&lt;p&gt;&lt;a href=&quot;http://nightwatchjs.org/&quot;&gt;Testes automatizados de navegador&lt;/a&gt;, conhecidos como Smoke Tests são uma ótima alternativa para garantir que as principais funcionalidades da Aplicação estejam operando adequadamente. Smoke Tests inclusive servem muito bem para introduzir algum tipo de teste em projetos legados.&lt;/p&gt;

&lt;p&gt;Este artigo foca quase que apenas em testes unitários e funcionais. Porém, tratando-se de Desenvolvimento Front-end é importante destacar que existem também: 1) &lt;a href=&quot;https://github.com/addyosmani/psi&quot;&gt;Performance Tests&lt;/a&gt;, 2) &lt;a href=&quot;https://github.com/Huddle/PhantomCSS&quot;&gt;Visual/CSS Regression Tests&lt;/a&gt; e 3) &lt;a href=&quot;https://www.browserstack.com/&quot;&gt;Cross-Browser Testing&lt;/a&gt;.&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;A conclusão mais rasa é que você deve testar código se almeja trabalhar com sanidade e de maneira responsável em uma Aplicação Web. Além disto, aprender os conceitos e sobretudo praticar a escrita de testes unitários &lt;strong&gt;expande a maneira que você pensa a respeito de código&lt;/strong&gt; e o torna um profissional melhor.&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;*Artigo orinalmente postado no &lt;a href=&quot;https://medium.com/tableless/voc%C3%AA-%C3%A9-irrespons%C3%A1vel-por-n%C3%A3o-escrever-testes-de-front-end-70c2858b62df&quot;&gt;Medium&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Thu, 06 Apr 2017 00:00:00 +0000</pubDate>
        <link>http://jcemer.com/voce-e-irresponsavel-por-nao-escrever-testes-de-front-end.html</link>
        <guid isPermaLink="true">http://jcemer.com/voce-e-irresponsavel-por-nao-escrever-testes-de-front-end.html</guid>
      </item>
    
      <item>
        <title>CSS on Steroids: a era dos pós-processadores</title>
        <description>&lt;p&gt;No longínquo ano de 2013 escrevi o artigo &lt;a href=&quot;http://tableless.com.br/css-steroids&quot;&gt;CSS on Steroids&lt;/a&gt; que é muito sobre como escrever CSS de forma mais eficiente. Alguns anos se passaram e uma série de tecnologias nasceram, enquanto outras estagnaram.&lt;/p&gt;

&lt;p&gt;A premissa do artigo original é apresentar alguns dos problemas mais comuns em folhas de estilo e sugerir soluções apoiadas no uso de pré-processadores e outras ferramentas como os pós-processadores. O plano aqui é revisitar as soluções e analisar novas estratégias de escrita de código. Conhecer as principais funcionalidades dos pré-processadores de CSS é pre requisito para esta leitura.&lt;/p&gt;

&lt;p&gt;Os pós-processadores são utilitários difundidos e apoiados principalmente pela ferramenta &lt;a href=&quot;https://github.com/postcss/postcss&quot;&gt;PostCSS&lt;/a&gt;. A ferramenta permite a escrita de &lt;em&gt;plugins&lt;/em&gt; em JavaScript que podem ter acesso ao seu código CSS e aplicar transformações ou validações. Ao longo do artigo aprofundaremos mais o assunto e veremos alguns exemplos de &lt;em&gt;plugins&lt;/em&gt; e sua aplicação.&lt;/p&gt;

&lt;p&gt;O que é apresentado a seguir tem base em projetos que vivenciei e portanto são frutos de algumas das minhas experiências. Cada projeto e equipe constituem seu próprio contexto e, como sempre, algumas coisas (ou até mesmo tudo) podem não se aplicar em sua integridade.&lt;/p&gt;

              &lt;h2 id=&quot;Variáveis-de-código-cores-e-medidas&quot;&gt;
                &lt;a name=&quot;Variáveis-de-código-cores-e-medidas&quot; href=&quot;#Variáveis-de-código-cores-e-medidas&quot;&gt;&lt;/a&gt;Variáveis de código: cores e medidas
              &lt;/h2&gt;
            
&lt;p&gt;Medidas e cores normalmente são os maiores causadores de ruídos em uma folha de estilo. Interpretar as cores ou decifrar a relação entre medidas apenas batendo o olho no código não é tarefa fácil. As variáveis dos pré-processadores são de grande ajuda, veja abaixo um exemplo consolidando práticas apresentados no artigo original.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sass&quot; data-lang=&quot;sass&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a name=&quot;line-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;na&quot;&gt;$site-width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;960&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;px&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-2&quot;&gt;&lt;/a&gt;&lt;span class=&quot;na&quot;&gt;$site-gap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;px&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-3&quot;&gt;&lt;/a&gt;&lt;span class=&quot;na&quot;&gt;$speaker-list-width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;px&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-4&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-5&quot;&gt;&lt;/a&gt;&lt;span class=&quot;na&quot;&gt;$grey-color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;#3F4955&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-6&quot;&gt;&lt;/a&gt;&lt;span class=&quot;na&quot;&gt;$main-color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$grey-color&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-7&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-8&quot;&gt;&lt;/a&gt;&lt;span class=&quot;nt&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-9&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;na&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$site-width&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-10&quot;&gt;&lt;/a&gt;&lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;
&lt;a name=&quot;line-11&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-12&quot;&gt;&lt;/a&gt;&lt;span class=&quot;nc&quot;&gt;.header&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-13&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;na&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$site-width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$site-gap&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-14&quot;&gt;&lt;/a&gt;&lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;
&lt;a name=&quot;line-15&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-16&quot;&gt;&lt;/a&gt;&lt;span class=&quot;nc&quot;&gt;.speaker-list&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-17&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;na&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$speaker-list-width&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-18&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;na&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;px&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;solid&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$main-color&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-19&quot;&gt;&lt;/a&gt;&lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;
&lt;a name=&quot;line-20&quot;&gt;&lt;/a&gt;&lt;span class=&quot;nc&quot;&gt;.speaker-list__item&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-21&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;na&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$speaker-list-width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-22&quot;&gt;&lt;/a&gt;&lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Alguns editores já possuem &lt;em&gt;plugins&lt;/em&gt; para facilitar a interpretação das cores hexadecimais. Mas é importante &lt;strong&gt;ponderar a necessidade de cada variação de cor&lt;/strong&gt; ao consolidar arquivos de &lt;em&gt;layout&lt;/em&gt; vindos do Photoshop, Sketch e demais ferramentas. Um novo aliado é o utilitário de pós-processamento &lt;a href=&quot;https://github.com/SlexAxton/css-colorguard&quot;&gt;CSS Colorguard&lt;/a&gt; que identifica variações desnecessárias de uma mesma cor.&lt;/p&gt;

&lt;p&gt;De qualquer maneira, variáveis com cores ainda auxiliam muito na tarefa de manter o controle sobre as cores utilizadas no projeto. Possuir um único arquivo no projeto contendo todas as cores ajuda a construir um projeto mais enxuto e organizado, o que facilita alterar ou replicar componentes.&lt;/p&gt;

&lt;p&gt;A não ser que você esteja escrevendo o sucessor do Twitter Bootstrap, &lt;a href=&quot;https://github.com/twbs/bootstrap-sass/blob/3.2-stable/assets/stylesheets/bootstrap/_variables.scss#L91-L852&quot;&gt;arquivos imensos cheios de variáveis&lt;/a&gt; que tem seu valor acessado uma única vez e que são associadas a componentes e especificidades do &lt;em&gt;layout&lt;/em&gt; não fazem sentido. Arquivos como este apenas dão trabalho de manutenção e podem criar uma falsa impressão de flexibilidade ao projeto. Poder alterar as características de um componente é mais fácil quando existe &lt;strong&gt;um único arquivo para cada componente responsável por toda sua estilização&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Por outro lado, variáveis são úteis quando componentes do projeto estão relacionados e precisam compartilhar determinado valor. Lembrando que casos como estes devem ser evitados ao máximo por tornarem o código do projeto mais acoplado e dificultar seu reuso. Ainda, as variáveis podem ser utilizadas em escopos isolados de um componente para facilitar o entendimento de algum cálculo ou relação principalmente quando estiver lidando com medidas.&lt;/p&gt;

&lt;p&gt;Abra mão de variáveis como &lt;code&gt;$main-color&lt;/code&gt; e &lt;code&gt;$speaker-list-width&lt;/code&gt; que criam indireção com pouco benefício. Abuse de variáveis como &lt;code&gt;$dark-grey&lt;/code&gt;, &lt;code&gt;$soft-grey&lt;/code&gt; e &lt;code&gt;$grey&lt;/code&gt; que garantem identidade ao projeto e também &lt;code&gt;$width&lt;/code&gt; facilitam o entendimento de algum cálculo em um escopo isolado. O exemplo acima revisado fica dividido em dois arquivos como estes:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sass&quot; data-lang=&quot;sass&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a name=&quot;line-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;c1&quot;&gt;// file: colors.scss&lt;/span&gt;
&lt;a name=&quot;line-2&quot;&gt;&lt;/a&gt;&lt;span class=&quot;nv&quot;&gt;$grey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;#3F4955&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-3&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-4&quot;&gt;&lt;/a&gt;&lt;span class=&quot;c1&quot;&gt;// file: speaker-list.scss&lt;/span&gt;
&lt;a name=&quot;line-5&quot;&gt;&lt;/a&gt;&lt;span class=&quot;k&quot;&gt;@import&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;colors.scss&amp;#39;;&lt;/span&gt;
&lt;a name=&quot;line-6&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-7&quot;&gt;&lt;/a&gt;&lt;span class=&quot;nc&quot;&gt;.speaker-list&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-8&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;nv&quot;&gt;$width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;px&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-9&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-10&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;na&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$width&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-11&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;na&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$grey&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-12&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-13&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;k&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;__item&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-14&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;na&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-15&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;
&lt;a name=&quot;line-16&quot;&gt;&lt;/a&gt;&lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
              &lt;h2 id=&quot;Frameworks-e-mixins&quot;&gt;
                &lt;a name=&quot;Frameworks-e-mixins&quot; href=&quot;#Frameworks-e-mixins&quot;&gt;&lt;/a&gt;Frameworks e mixins
              &lt;/h2&gt;
            
&lt;p&gt;Os maiores representantes desta classe são o &lt;a href=&quot;http://compass-style.org/&quot;&gt;Compass&lt;/a&gt; e &lt;a href=&quot;http://bourbon.io/&quot;&gt;Bourbon&lt;/a&gt;. Esta dupla já solucionou muitos problemas no passado. Porém o próximo passo é nos livrarmos destas tecnologias.&lt;/p&gt;

&lt;p&gt;O motivo para nos livrarmos do Compass poderia ser o fato deste ser um &lt;a href=&quot;https://github.com/Compass/compass/graphs/contributors&quot;&gt;projeto abandonado&lt;/a&gt;, mas existem outros mais. O Compass é um projeto muito generalista ao tentar gerar &lt;em&gt;sprites&lt;/em&gt;, definir &lt;em&gt;resets&lt;/em&gt;, trazer consigo alguns utilitários, incluir fontes e images e ainda gerenciar &lt;em&gt;vendor prefixes&lt;/em&gt;. Existem soluções individuais muito melhores para cada um dos pontos que o projeto endereça:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sprites&lt;/strong&gt;: lembre-se que SVG está em alta, mas se mesmo assim precisar de sprites, vá de &lt;a href=&quot;https://github.com/lucasmazza/spriteful&quot;&gt;Spriteful&lt;/a&gt; ou &lt;a href=&quot;https://github.com/Ensighten/spritesmith&quot;&gt;spritesmith&lt;/a&gt;. Fazer uso do pós-processador &lt;a href=&quot;https://github.com/2createStudio/postcss-sprites&quot;&gt;postcss-sprites&lt;/a&gt; é uma ótima alternativa não invasiva que permite deixar de usar a técnica de &lt;em&gt;spriting&lt;/em&gt; facilmente no futuro quando não mais necessária.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CSS resets&lt;/strong&gt;: esta é fácil demais, basta rodar &lt;code&gt;npm install --save normalize.css&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mixins&lt;/strong&gt;: como Miller já apontou em &lt;a href=&quot;http://blog.millermedeiros.com/the-problem-with-css-pre-processors/&quot;&gt;The problem with CSS pre-processors&lt;/a&gt;, os &lt;em&gt;mixins&lt;/em&gt; muito bem podem ser classes utilitárias dentro do seu projeto. Classes utilitárias  também eliminam o uso de &lt;code&gt;@extend&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Vendor prefixes&lt;/strong&gt;: Algumas propriedades do CSS passam por uma fase de adaptação e especificação e por causa disto ganham um prefixo com base no fabricante do navegador. &lt;strong&gt;Apesar de não ser aconselhado fazer uso de propriedades em fase de experimentação&lt;/strong&gt;, muitos projetos aplicam gradientes até hoje da seguinte maneira &lt;code&gt;@include background(linear-gradient($blue, $light-blue));&lt;/code&gt;. Os navegadores atualmente lançam versões com um frequência incrível e é comum ter definições de projeto do tipo: daremos suporte para as duas últimas versões do Chrome. Soluções de pós-processamento como o &lt;a href=&quot;https://github.com/postcss/autoprefixer&quot;&gt;Autoprefixer&lt;/a&gt; são muito melhores pois não exigem estudar e lembrar de aplicar diferentes &lt;em&gt;mixins&lt;/em&gt; além de não tornarem seu projeto escravo de um &lt;em&gt;framework&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Assets&lt;/strong&gt;: o Compass possuía uma série de utilitários para cuida dos &lt;em&gt;assets&lt;/em&gt; permitindo determinar tamanho de imagens, adicioná-las à folha de estilo através de Data URI (apesar da técnica já ter sido &lt;a href=&quot;http://www.mobify.com/blog/base64-does-not-impact-data-uri-performance/&quot;&gt;envolvida em algumas polêmicas&lt;/a&gt;) dentre outras &lt;em&gt;features&lt;/em&gt;. Uma alternativa, se o projeto estiver utilizando a &lt;a href=&quot;https://webpack.github.io/&quot;&gt;ferramenta para &lt;em&gt;bundle&lt;/em&gt; Webpack&lt;/a&gt;, são os &lt;em&gt;loaders&lt;/em&gt; &lt;a href=&quot;https://github.com/webpack/css-loader&quot;&gt;css-loader&lt;/a&gt;, &lt;a href=&quot;https://github.com/webpack/file-loader&quot;&gt;file-loader&lt;/a&gt; e &lt;a href=&quot;https://github.com/webpack/url-loader&quot;&gt;url-loader&lt;/a&gt; que endereçam algumas destas &lt;em&gt;features&lt;/em&gt; e ainda garantem &lt;a href=&quot;http://www.adopsinsider.com/ad-ops-basics/what-is-a-cache-buster-and-how-does-it-work/&quot;&gt;&lt;em&gt;cache busting&lt;/em&gt;&lt;/a&gt;. Na categoria de pós-processadores, o &lt;a href=&quot;https://github.com/assetsjs/postcss-assets&quot;&gt;postcss-assets&lt;/a&gt; é uma boa alternativa para projetos que não utilizam Webpack.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Muitos dos argumentos que desencorajam o uso de Compass também se aplicam para o Bourbon. Em linhas gerais, fuja destas tecnologias. A excessão é que o Bourbon pode  prestar muito bem para prototipações e como substituto do Twitter Bootstrap quando em conjunto com a tríade &lt;a href=&quot;http://neat.bourbon.io/&quot;&gt;Neat&lt;/a&gt;, &lt;a href=&quot;http://bitters.bourbon.io/&quot;&gt;Bitters&lt;/a&gt; e &lt;a href=&quot;http://refills.bourbon.io/&quot;&gt;Refills&lt;/a&gt;.&lt;/p&gt;

              &lt;h2 id=&quot;Nesting-agrupando-regras&quot;&gt;
                &lt;a name=&quot;Nesting-agrupando-regras&quot; href=&quot;#Nesting-agrupando-regras&quot;&gt;&lt;/a&gt;Nesting: agrupando regras
              &lt;/h2&gt;
            
&lt;p&gt;Agrupar regras de CSS na minha opinião é a &lt;em&gt;feature&lt;/em&gt; mais interessante dos pré-processadores. Aplicar &lt;em&gt;media queries&lt;/em&gt; localizadas e facilitar o uso do &lt;a href=&quot;http://getbem.com/introduction/&quot;&gt;BEM&lt;/a&gt; são atualmente meus casos de uso favoritos.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sass&quot; data-lang=&quot;sass&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a name=&quot;line-1&quot;&gt;&lt;/a&gt;&lt;span class=&quot;nc&quot;&gt;.speaker-list&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-2&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;k&quot;&gt;@media&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;screen&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;min-width&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;1200px&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-3&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;na&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-4&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;
&lt;a name=&quot;line-5&quot;&gt;&lt;/a&gt;
&lt;a name=&quot;line-6&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;k&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;__item&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;
&lt;a name=&quot;line-7&quot;&gt;&lt;/a&gt;    &lt;span class=&quot;na&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$red&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;&lt;/span&gt;
&lt;a name=&quot;line-8&quot;&gt;&lt;/a&gt;  &lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;
&lt;a name=&quot;line-9&quot;&gt;&lt;/a&gt;&lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;O ponto do uso de &lt;em&gt;nesting&lt;/em&gt; continua sendo tomar cuidado e sempre ter em mente a folha de estilo gerada para &lt;a href=&quot;http://josh.github.io/css-explain/&quot;&gt;não extrapolar no peso dos seletores&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Utilitários de pós-processamento como &lt;a href=&quot;https://github.com/outpunk/postcss-modules&quot;&gt;postcss-modules&lt;/a&gt; e &lt;a href=&quot;https://github.com/gajus/react-css-modules&quot;&gt;React CSS Modules&lt;/a&gt; também permitem manter o escopo dos componentes em um projeto. Tratando especificamente de postcss-modules, seu uso exige que seu HTML tenha relação com o CSS gerado, em outras palavras, seu projeto &lt;a href=&quot;https://github.com/outpunk/postcss-modules-example/blob/master/html/index.ejs&quot;&gt;precisará no mínimo de uma &lt;em&gt;template engine&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;O React CSS Modules tem uma adoção mais simples para quem estiver em um projeto React e utilizando uma ferramenta de &lt;em&gt;bundle&lt;/em&gt;. De qualquer maneira, soluções mais avançadas como estas parecem promissoras e merecem atenção.&lt;/p&gt;

              &lt;h2 id=&quot;Indo-além-com-pós-processadores&quot;&gt;
                &lt;a name=&quot;Indo-além-com-pós-processadores&quot; href=&quot;#Indo-além-com-pós-processadores&quot;&gt;&lt;/a&gt;Indo além com pós-processadores
              &lt;/h2&gt;
            
&lt;p&gt;Já vimos uma &lt;a href=&quot;https://github.com/postcss/postcss&quot;&gt;série de pós-processadores&lt;/a&gt; que podem ser aplicados ao seu &lt;em&gt;workflow&lt;/em&gt;. O próximo passo, como você já deve imaginar é eliminar até mesmo os pré-processadores. O pacote &lt;a href=&quot;https://github.com/jonathantneal/precss&quot;&gt;PreCSS&lt;/a&gt; amarra uma série de outros pós-processadores que permitem substituir as principais &lt;em&gt;features&lt;/em&gt; dos pré-processadores e ainda oferecer mais.&lt;/p&gt;

&lt;p&gt;A grande vantagem dos pós-processadores é permitir facilmente escrever ou ativar novos &lt;em&gt;scripts&lt;/em&gt; para experimentar alguma especificação CSS ainda em fase de rascunho e ou atender um conjunto de funcionalidades limitadas do SASS que são realmente úteis para seu projeto e equipe.&lt;/p&gt;

              &lt;h2 id=&quot;Conclusão&quot;&gt;
                &lt;a name=&quot;Conclusão&quot; href=&quot;#Conclusão&quot;&gt;&lt;/a&gt;Conclusão
              &lt;/h2&gt;
            
&lt;p&gt;A experiência de reler o artigo original e ver o quanto a comunidade front-end evoluiu a maneira de utilizar e enxergar código CSS é incrível. A aposta em tecnologias mais específicas em desfavor das generalistas Compass, Bourbon e até mesmo SASS é uma grande tendência.&lt;/p&gt;

&lt;p&gt;O Compass já é um projeto declaradamente extinto e investir em um &lt;em&gt;workflow&lt;/em&gt; baseado unicamente em pós-processadores é a bola da vez. Minha aposta é que na próxima revisão eu não mais mencionarei pré-processadores.&lt;/p&gt;

&lt;p&gt;Qual a sua opinião? Gostou do artigo? Comente abaixo!&lt;/p&gt;
</description>
        <pubDate>Wed, 10 Feb 2016 00:00:00 +0000</pubDate>
        <link>http://jcemer.com/css-on-steroids-a-era-dos-pos-processadores.html</link>
        <guid isPermaLink="true">http://jcemer.com/css-on-steroids-a-era-dos-pos-processadores.html</guid>
      </item>
    
      <item>
        <title>O dilema do único na Web</title>
        <description>&lt;p&gt;As construções que fundamentam uma página Web são todas únicas. Cada página assume uma aba do navegador, com um endereço único, um &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; de um lado e outro &lt;code&gt;window&lt;/code&gt; do outro. É tudo global, meu amigo.&lt;/p&gt;

&lt;p&gt;A unicidade é tão absurda que JavaScript, HTML e CSS compartilham do mesmo fluxo de execução. Caso um demore a fazer seus cálculos, os demais sofrerão. Acontece.&lt;/p&gt;

&lt;p&gt;Na Web, nada se parte pela metade. Mesmo quando desafiamos com alguns &lt;em&gt;scripts&lt;/em&gt; postos a executar em modo assíncrono, além da garantia que irão executar um por vez, temos a garantia que o farão até terminar.&lt;/p&gt;

&lt;p&gt;Simples e fácil como parece. A plataforma Web joga fora toda a complexidade que a computação carregou ao longo de sua história e é única em como conquista adeptos.&lt;/p&gt;
</description>
        <pubDate>Tue, 09 Feb 2016 00:00:00 +0000</pubDate>
        <link>http://jcemer.com/o-dilema-do-unico-na-web.html</link>
        <guid isPermaLink="true">http://jcemer.com/o-dilema-do-unico-na-web.html</guid>
      </item>
    
      <item>
        <title>2016 e o estado do desenvolvimento front-end</title>
        <description>&lt;p&gt;Há algum tempo reflito e tenho intenção de escrever um texto a respeito das ferramentas e tecnologias utilizadas no desenvolvimento front-end. Mas no fundo, sempre batia uma preguiça e nada me motivava o suficiente a botar a bunda na cadeira e escrever. Eis que surge o artigo The Sad State of Web Development (que foi recentemente apagado) e cá estou pra retrucar.&lt;/p&gt;

&lt;p&gt;Vamos começar deixando algo bem claro: eu não considero o JavaScript uma linguagem tecnicamente extraordinária. Porém o ecossistema, liberdade e ubiquidade que a linguagem alcançou não tem precedentes. &lt;strong&gt;JavaScript é a linguagem mãe da Web&lt;/strong&gt;. Qualquer profissional que pensa em passar perto de desenvolvimento para a Web precisa respeitar e dominar JavaScript.&lt;/p&gt;

&lt;p&gt;A questão mais polêmica em volta do desenvolvimento &lt;em&gt;front-end&lt;/em&gt; parece residir no fato das tecnologias nascerem e morrerem com uma certa frequência. Isto gera uma insegurança a respeito de qual tecnologia adotar em um novo projeto. Sem falar que, aprender tanta coisa em um espaço tão curto de tempo incomoda muita gente. O que poucos observam é que Web é a plataforma que mais evolui nos últimos anos. Não há tecnologia que tenha evoluído tanto, de forma aberta, e em tantas frentes. Lembre-se que a Web é a única plataforma que funciona adequadamente no seu celular, tablet e &lt;em&gt;desktop&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Criar projetos que estejam alinhados com tamanha evolução de &lt;em&gt;hardware&lt;/em&gt; e usuários ávidos por experiências impecáveis exige o surgimento e amadurecimento de soluções e ferramentas mais inteligentes. Acreditar que um projeto de Web vai durar anos mantendo um visual grosseiro e sem (re)evoluções é apostar em interfaces como a do Hacker News.&lt;/p&gt;

&lt;p&gt;A medida que os projetos se tornam cada vez mais complexos, é uma tremenda burrice escrever código JavaScript sem nenhum padrão ou auxílio de tecnologias modernas. Mesmo no dia-a-dia, refatorar e aprimorar código adotando uma nova biblioteca ou &lt;em&gt;framework&lt;/em&gt; pode trazer grandes benefícios. As ferramentas e tecnologias utilizadas invariavelmente influenciarão na experiência do usuário. Pronto, é por isto que a cada dia alguns desenvolvedores reinventam a roda: &lt;strong&gt;para que ela gire melhor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ir contra a adoção de tantas novas tecnologias é nadar contra a maré. Reflita se não pode ser preguiça sua ou mesmo desinformação. Saber a dose certa do uso de novas tecnologias é um grande desafio, mas antes disto é preciso entendê-las e aprendê-las. &lt;strong&gt;Pra quem só conhece martelo, tudo parece prego&lt;/strong&gt;. Um 2016 de novos aprendizados para todos nós!&lt;/p&gt;
</description>
        <pubDate>Wed, 13 Jan 2016 00:00:00 +0000</pubDate>
        <link>http://jcemer.com/o-estado-do-desenvolvimento-front-end.html</link>
        <guid isPermaLink="true">http://jcemer.com/o-estado-do-desenvolvimento-front-end.html</guid>
      </item>
    
      <item>
        <title>Fluxo de execução assíncrono em JavaScript – Generators e Async Functions</title>
        <description></description>
        <pubDate>Tue, 05 Jan 2016 00:00:00 +0000</pubDate>
        <link>http://jcemer.com/generators-e-async-functions-fluxo-de-execucao-assincrono-em-javascript.html</link>
        <guid isPermaLink="true">http://jcemer.com/generators-e-async-functions-fluxo-de-execucao-assincrono-em-javascript.html</guid>
      </item>
    
      <item>
        <title>Screencast da apresentação Lapidando o Globo Play</title>
        <description>&lt;p&gt;A apresentação aborda os aspectos técnicos e de desenvolvimento do produto Globo Play para a Web. A palestra foi apresentada originalmente no evento &lt;a href=&quot;http://www.frontinfloripa.com.br&quot;&gt;Front in Floripa&lt;/a&gt; deste ano. Se preferir, os &lt;a href=&quot;http://www.slideshare.net/jeancarloemer/lapidando-o-globo-play&quot;&gt;slides também estão disponíveis&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;video-wrapper&quot;&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/RMAAuOcuVOE&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;Fique a vontade para tirar suas dúvidas ou contestar qualquer aspecto no espaço abaixo.&lt;/p&gt;
</description>
        <pubDate>Sun, 13 Dec 2015 00:00:00 +0000</pubDate>
        <link>http://jcemer.com/lapidando-o-globo-play.html</link>
        <guid isPermaLink="true">http://jcemer.com/lapidando-o-globo-play.html</guid>
      </item>
    
      <item>
        <title>Dicas para evoluir um front-end legado</title>
        <description>&lt;p&gt;Com a evolução das plataformas computacionais, os requisitos que as aplicações para a Internet devem atender têm se tornado mais e mais complexos. Em conformidade a isto, a disciplina de &lt;em&gt;front-end&lt;/em&gt; é a que mais tem sofrido mudanças na sua gama de técnicas e práticas. &lt;strong&gt;A lista de novos &lt;em&gt;frameworks&lt;/em&gt;, bibliotecas e modos de escrita de código de maneira geral cresce a cada dia.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Este artigo é focado em dicas gerais de como &lt;strong&gt;aplicar gradativamente&lt;/strong&gt; as mais adequadas técnicas e práticas para modernizar o &lt;em&gt;front-end&lt;/em&gt; de aplicações legadas.&lt;/p&gt;

              &lt;h2 id=&quot;Estude-o-projeto&quot;&gt;
                &lt;a name=&quot;Estude-o-projeto&quot; href=&quot;#Estude-o-projeto&quot;&gt;&lt;/a&gt;Estude o projeto
              &lt;/h2&gt;
            
&lt;p&gt;O projeto precisa ser estudado a fundo para que suas principais fraquezas sejam descobertas. Alto acoplamento, falta de organização, duplicação e código mal escrito (ou exclusivo para atender navegadores bem antigos) serão problemas facilmente encontrados em projetos legados.&lt;/p&gt;

&lt;p&gt;Procure seguir os principais fluxos de navegação e &lt;strong&gt;compreender bem o projeto&lt;/strong&gt; antes de aplicar qualquer mudança. Estudar bibliotecas e demais dependências é também importante nesta etapa.&lt;/p&gt;

              &lt;h2 id=&quot;Testes&quot;&gt;
                &lt;a name=&quot;Testes&quot; href=&quot;#Testes&quot;&gt;&lt;/a&gt;Testes
              &lt;/h2&gt;
            
&lt;p&gt;Uma suíte de testes é essencial para evoluir código legado. Caso seu projeto não possua nenhum tipo de teste, os funcionais são uma boa pedida para começar.  &lt;strong&gt;Cubra ao máximo com testes&lt;/strong&gt; uma funcionalidade antes de começar a mexer em seu código. Apenas assim há uma garantia (mas nunca de 100%) de que você não irá quebrar nada.&lt;/p&gt;

              &lt;h2 id=&quot;Dependências&quot;&gt;
                &lt;a name=&quot;Dependências&quot; href=&quot;#Dependências&quot;&gt;&lt;/a&gt;Dependências
              &lt;/h2&gt;
            
&lt;p&gt;Evoluir a versão das dependências de um projeto pode nem sempre ser uma tarefa fácil. Apesar disto, pode trazer muitos benefícios de perfomance e correção de &lt;em&gt;bugs&lt;/em&gt;. &lt;strong&gt;Investigue quais as mudanças nas versões das dependências que irá evoluir&lt;/strong&gt;. Mudar a versão da jQuery, por exemplo, não é uma boa ideia se sua aplicação não possui uma cobertura adequada de testes.&lt;/p&gt;

              &lt;h2 id=&quot;Separe-o-código-em-módulos&quot;&gt;
                &lt;a name=&quot;Separe-o-código-em-módulos&quot; href=&quot;#Separe-o-código-em-módulos&quot;&gt;&lt;/a&gt;Separe o código em módulos
              &lt;/h2&gt;
            
&lt;p&gt;O mais comum dos problemas de um código CSS e JavaScript legado é a falta de &lt;em&gt;separation of concerns&lt;/em&gt;. São várias as maneiras de modularizar seu código, mas a simples tarefa de dividir o código em diferentes arquivos é um ótimo começo. &lt;strong&gt;Durante este trabalho, será fácil identificar duplicações e criar novas abstrações.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ferramentas como o Asset Pipeline do Rails e gerenciadores de tarefas como Gulp e Grunt são essenciais para concatenar arquivos e executar tarefas de pré e pós processamento. Adotar e ou melhor configurar uma destas ferramentas para o projeto será o primeiro passo desta etapa.&lt;/p&gt;

              &lt;h2 id=&quot;Pare-de-referenciar-ids-do-HTML&quot;&gt;
                &lt;a name=&quot;Pare-de-referenciar-ids-do-HTML&quot; href=&quot;#Pare-de-referenciar-ids-do-HTML&quot;&gt;&lt;/a&gt;Pare de referenciar ids do HTML
              &lt;/h2&gt;
            
&lt;p&gt;Os &lt;em&gt;ids&lt;/em&gt; servem como alvos para âncoras e portanto não podem ser duplicadas em um documento. &lt;strong&gt;Referenciar &lt;em&gt;ids&lt;/em&gt; no CSS quebra completamente qualquer chance de reuso de código&lt;/strong&gt;. Altere todos os seletores do CSS que referenciam &lt;em&gt;ids&lt;/em&gt; para utilizarem classes.&lt;/p&gt;

&lt;p&gt;As mudanças no seu JavaScript devem ser ainda mais drásticas. Evite usar &lt;em&gt;ids&lt;/em&gt; ou classes (que servem para estilização) no seu código JavaScript. Os &lt;em&gt;data attributes&lt;/em&gt; são ótimos para adicionar comportamento e dar acesso ao DOM.&lt;/p&gt;

              &lt;h2 id=&quot;Implemente-um-sistema-de-escrita-de-CSS&quot;&gt;
                &lt;a name=&quot;Implemente-um-sistema-de-escrita-de-CSS&quot; href=&quot;#Implemente-um-sistema-de-escrita-de-CSS&quot;&gt;&lt;/a&gt;Implemente um sistema de escrita de CSS
              &lt;/h2&gt;
            
&lt;p&gt;Apesar de não ser um assunto tão novo, a maioria dos projetos legados não segue nenhum tipo de sistema de escrita de CSS. Além disto, seletores muito generalistas e os odiados &lt;em&gt;!important&lt;/em&gt; podem ser ervas daninhas que você terá que se livrar.&lt;/p&gt;

&lt;p&gt;Há um tempo &lt;a href=&quot;http://tableless.com.br/oocss-smacss-bem-dry-css-afinal-como-escrever-css&quot;&gt;escrevi um artigo sobre os sistemas de escrita de CSS mais populares&lt;/a&gt;. A dica final de escrita de código apresentada no artigo pode servir de inspiração.&lt;/p&gt;

              &lt;h2 id=&quot;Não-abandone-os-padrões-do-HTML&quot;&gt;
                &lt;a name=&quot;Não-abandone-os-padrões-do-HTML&quot; href=&quot;#Não-abandone-os-padrões-do-HTML&quot;&gt;&lt;/a&gt;Não abandone os padrões do HTML
              &lt;/h2&gt;
            
&lt;p&gt;Muitos &lt;em&gt;frameworks&lt;/em&gt; e bibliotecas modernas de &lt;em&gt;front-end&lt;/em&gt; pegam a responsabilidade de redefinir o fluxo da aplicação. E isto não é uma má ideia. Porém, é bastante difícil evoluir um código legado para utilizar AngularJS, por exemplo. Neste ponto, as dicas do &lt;a href=&quot;/revisitando-como-atribuir-comportamento-a-componentes.html&quot;&gt;artigo que escrevi sobre como atribuir comportamento a componentes devem ajudar&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Em resumo, aplicar alguns padrões simples e bibliotecas como o Backbone.js são uma melhor estratégia. Apenas considere utilizar um &lt;em&gt;framework&lt;/em&gt; quando seu código estiver em um estado mais maduro (e ainda assim, pense muito bem a respeito). &lt;strong&gt;Receber um HTML pronto do servidor e enviar dados utilizando formulários nunca será uma má ideia.&lt;/strong&gt; Alguns &lt;em&gt;frameworks&lt;/em&gt; privam você disto.&lt;/p&gt;

              &lt;h2 id=&quot;Componentes&quot;&gt;
                &lt;a name=&quot;Componentes&quot; href=&quot;#Componentes&quot;&gt;&lt;/a&gt;Componentes
              &lt;/h2&gt;
            
&lt;p&gt;Reconhecer quais componentes fazem parte do projeto e entender quais seus padrões visuais é uma tarefa árdua. &lt;strong&gt;O trabalho aqui é relacionar HTML, CSS, JS e demais recursos em uma única unidade&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Esta etapa poderá exigir que você inclua novas bibliotecas e ferramental de &lt;em&gt;build&lt;/em&gt; para o projeto. Não se preocupe, você já conhecerá o suficiente do projeto para fazer estas escolhas de forma acertada.&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;Evoluir projetos legados exige um plano de ação bem definido. Ao contrário do senso comum, sair reescrevendo tudo ou criar um projeto novo quase sempre é uma má ideia. &lt;strong&gt;O ideal é estabelecer pequenas interações&lt;/strong&gt;. Lembre-se de documentar e compartilhar seu plano de ação a medida que seu domínio sobre o projeto for aumentando.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Se cada vez você deixar um pouco melhor que antes, nunca vai degenerar - Juan Ibiapina.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr&gt;

&lt;p&gt;Ao mesmo tempo, não se preocupe, algumas vezes etapas intermediárias deixarão o código mais verboso e até mais confuso. &lt;strong&gt;Foque no resultado final, umas escoras e tapumes poderão ser necessários para fazer sua obra&lt;/strong&gt;.&lt;/p&gt;
</description>
        <pubDate>Tue, 18 Aug 2015 00:00:00 +0000</pubDate>
        <link>http://jcemer.com/dicas-para-evoluir-front-end-legado.html</link>
        <guid isPermaLink="true">http://jcemer.com/dicas-para-evoluir-front-end-legado.html</guid>
      </item>
    
  </channel>
</rss>
