<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Patryk</title>
    <description>The latest articles on DEV Community by Patryk (@patryktech).</description>
    <link>https://dev.to/patryktech</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F156397%2F11b5bc0e-1ae4-4ebf-a5cf-0a4aa3cdeef3.png</url>
      <title>DEV Community: Patryk</title>
      <link>https://dev.to/patryktech</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/patryktech"/>
    <language>en</language>
    <item>
      <title>Please port your TCP applications to UDP</title>
      <dc:creator>Patryk</dc:creator>
      <pubDate>Tue, 10 Mar 2020 13:49:53 +0000</pubDate>
      <link>https://dev.to/patryktech/please-port-your-tcp-applications-to-udp-mba</link>
      <guid>https://dev.to/patryktech/please-port-your-tcp-applications-to-udp-mba</guid>
      <description>&lt;p&gt;Handshakes are being deprecated due to the current coronavirus epidemic.&lt;/p&gt;

</description>
      <category>jokes</category>
    </item>
    <item>
      <title>Emulating Unicorns</title>
      <dc:creator>Patryk</dc:creator>
      <pubDate>Tue, 03 Mar 2020 11:07:48 +0000</pubDate>
      <link>https://dev.to/patryktech/emulating-unicorns-59oc</link>
      <guid>https://dev.to/patryktech/emulating-unicorns-59oc</guid>
      <description>&lt;p&gt;I'm sure most of you are familiar with the term &lt;em&gt;Unicorn&lt;/em&gt; - a startup that reaches a valuation of $1 billion USD.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2Nd9Izc8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lzuglej75ti6c39uithv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2Nd9Izc8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lzuglej75ti6c39uithv.png" alt="Unicorn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Those companies often offer great working conditions, and manage to recruit the top talent, meaning they have really smart engineers, and processes that work really well to develop, test, and deploy quality software. Oftentimes, they also publish their best practices on the internet for everyone to learn from.&lt;/p&gt;

&lt;p&gt;If you are a novice, self-taught, part of a small team, etc. those practices are a great fountain of knowledge, and I encourage you to look at the way the unicorns do things, and emulating their processes in your own projects.&lt;/p&gt;

&lt;p&gt;Of course, not &lt;em&gt;everything&lt;/em&gt; they do should be emulated - Netflix' &lt;em&gt;Chaos Engineering&lt;/em&gt; may be too risky for you, and microservices are probably overkill.&lt;/p&gt;

&lt;p&gt;Today I will introduce you to two practices I have borrowed from leading internet companies.&lt;/p&gt;

&lt;h2&gt;
  
  
  AirBnB JavaScript Style Guide
&lt;/h2&gt;

&lt;p&gt;Like any good programmer, I am lazy. This doesn't meant that I don't like &lt;em&gt;writing&lt;/em&gt; code or work... I simply don't want to spend ten minutes thinking about how to structure said code. Thankfully, the folks at AirBnB have published a &lt;a href="https://github.com/airbnb/javascript"&gt;style guide&lt;/a&gt; that I have discovered when I started working with the Quasar framework. Using ESLint with the AirBnB rules improved my code a lot... It is now consistent, and I don't need to rack my brain about every decision - when to put a semi-colon, whether to use a trailing comma in an object, list, etc.&lt;/p&gt;

&lt;p&gt;Of course, there are other style guides out there, and you may have your own preferences. If you don't already use a linter for your JavaScript code, do start. Gloss over the style guide, refer to it when your linter complains, and you'll see - writing in a consistent style will soon become second nature. Remember to be adaptable; if you join a company that has its own style, use that, and if you dislike some rules, feel free to change them (or use another set of linter rules).&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular Commit Messages
&lt;/h2&gt;

&lt;p&gt;I have used the word "consistent" twice in the previous section. To be honest, I really like consistency, and this tip is in the same vein. Sometimes I help people online with various questions, open their repository, and see all their commits look as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fixed bug&lt;/li&gt;
&lt;li&gt;refactored some code&lt;/li&gt;
&lt;li&gt;changed some stuffs&lt;/li&gt;
&lt;li&gt;added some stuff&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course, we all continuously learn, and I have certainly been guilty of this myself in the past. Then I have read the &lt;a href="https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit"&gt;Angular Commit Message Rules&lt;/a&gt;. Like the AirBnB JS style guide, this has helped me write more consistent commit messages, making my &lt;code&gt;git log&lt;/code&gt; much clearer, more readable, and also allowing you to easily write parsers to generate &lt;code&gt;CHANGELOG&lt;/code&gt;s.&lt;/p&gt;

&lt;h3&gt;
  
  
  Commit Message Rules
&lt;/h3&gt;

&lt;p&gt;I encourage you to read the original document, but the TL;DR is that a commit message should have a header, consisting of a mandatory type, optional scope, and subject, followed by a body and a footer (which are not marked as explicitly mandatory, and I often skip them).&lt;/p&gt;

&lt;h4&gt;
  
  
  Header
&lt;/h4&gt;

&lt;p&gt;The document defines some mandatory types (build, ci, docs, feat, fix, perf, refactor, style, test). Depending on your project, you can always use a different list. I mostly use feat, fix, docs, build, and test.&lt;/p&gt;

&lt;p&gt;The optional scope includes animations, common, core, http, router, etc. As this is for the Angular library, this makes sense, but it does not for my personal projects. As I often use monorepos with Docker, Django, and a VueJS framework, my scopes are often docker, back-end, and front-end.&lt;/p&gt;

&lt;p&gt;The subject should use present-tense (change, not &lt;em&gt;changed&lt;/em&gt;), and not use capitalization or periods. Personally, I don't mind that style at all, and emulate it. If you prefer something else, feel free to start with a capital letter and end with a period - just make sure that you stay consistent. Consistency makes codebases easier to work with, and onboarding more pleasant.&lt;/p&gt;

&lt;p&gt;Some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;feat(front-end): add component Foo&lt;/li&gt;
&lt;li&gt;fix(docker): rename network mynte to mynet&lt;/li&gt;
&lt;li&gt;test: add unit tests for component Foo&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;This was a brief overview, so follow the links and read the original documents - they offer far more details than this post.&lt;/p&gt;

&lt;p&gt;As always, be pragmatic. Take best practices and apply what makes sense to your projects. If you disagree with some rules, make your own. If you work with others, communicate with them, and write your own linter rules or commit message guidelines so the entire team is on the same page. If you join a new company that has its own established practices, follow those. If they don't have any, maybe borrow them from a unicorn, and become the office hero for a little while.&lt;/p&gt;




&lt;p&gt;What about you, have you taken inspiration from any other projects and improved the way you work?&lt;/p&gt;

</description>
      <category>bestpractices</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I had a problem, so I decided to use multithreading</title>
      <dc:creator>Patryk</dc:creator>
      <pubDate>Thu, 20 Feb 2020 10:50:46 +0000</pubDate>
      <link>https://dev.to/patryktech/i-had-a-problem-so-i-decided-to-use-multithreading-431n</link>
      <guid>https://dev.to/patryktech/i-had-a-problem-so-i-decided-to-use-multithreading-431n</guid>
      <description>&lt;p&gt;I had a problem, so I decided to use multithreading.&lt;/p&gt;

&lt;p&gt;I Now two have problems.&lt;/p&gt;

</description>
      <category>jokes</category>
    </item>
    <item>
      <title>Read the Tests, Luke!</title>
      <dc:creator>Patryk</dc:creator>
      <pubDate>Fri, 07 Feb 2020 14:01:25 +0000</pubDate>
      <link>https://dev.to/patryktech/read-the-tests-luke-2m0f</link>
      <guid>https://dev.to/patryktech/read-the-tests-luke-2m0f</guid>
      <description>&lt;p&gt;This is the second installment in my &lt;em&gt;Testing&lt;/em&gt; series. It will not be a big wall of text with a lot of theory - this one comes with exemples from my personal experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;If you use an open-source library, or work on an open-source project, sometimes it will not be documented at all, and the author will tell you to just read the source code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vynGLmQU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ezu4pq1a9v3o4ws57s63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vynGLmQU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ezu4pq1a9v3o4ws57s63.png" alt="Use the source?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sometimes, the documentation is good - just out of date. Other times, it will be incomplete, and in some cases, it may be awesome, and tell you everything you need to know (but still not cover the way the library works internally).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reading the tests will often teach you more quicker than reading the source code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Writing software requires both theory and practice. In order to become good at it, you should write &lt;em&gt;a lot&lt;/em&gt; of code, and you need to make mistakes that you can learn from. That is the practice bit.&lt;/p&gt;

&lt;p&gt;You also need to &lt;em&gt;read&lt;/em&gt; a lot of code, in books, but ideally, also in open-source projects. That will give you theory, and show you how other people solve problems.&lt;/p&gt;

&lt;p&gt;The problem with this is that oftentimes, projects are mature, and have a &lt;em&gt;massive&lt;/em&gt; codebase, which means you may not know where to start. My recommendation: always start by &lt;em&gt;running&lt;/em&gt; the test suite, then &lt;em&gt;read&lt;/em&gt; the tests. It will often teach you more &lt;em&gt;quicker&lt;/em&gt; than reading the source code, or sometimes even the documentation.&lt;/p&gt;

&lt;p&gt;Also, reading tests will help you see how others write tests, what they test, and may help you think about your own testing strategies.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Example 1: polyquack
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--leZoXi6j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://patryk-media.gitlab.io/polyquack/logo/polyquack.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--leZoXi6j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://patryk-media.gitlab.io/polyquack/logo/polyquack.svg" alt="polyquack"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gitlab.com/patryk-media/polyquack"&gt;polyquack&lt;/a&gt; is a Python library for translations that I have written  so I could use it in &lt;a href="https://gitlab.com/patryk-media/polyquack-django"&gt;polyquack-django&lt;/a&gt; - an extension to help write translatable websites with Django. &lt;code&gt;polyquack-django&lt;/code&gt; solves some pain points that I didn't like with other translation packages, mostly in that it extends  PostgreSQL &lt;code&gt;JSONField&lt;/code&gt;s to make translations dynamic, unlike some packages that need to create new tables, or columns for each language.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;polyquack&lt;/code&gt; has a &lt;em&gt;pluralization&lt;/em&gt; function, and the &lt;a href="https://patryk-media.gitlab.io/polyquack/docs/pluralization_rules/"&gt;pluralization rules&lt;/a&gt; are briefly covered in the documentation, but it doesn't really explain everything that happens behind the scenes (note that it's an alpha stage project, so I am sure the documentation will be improved in the future).&lt;/p&gt;

&lt;p&gt;So, how &lt;em&gt;does&lt;/em&gt; it work? If you use the &lt;code&gt;Pluralizable&lt;/code&gt; class, there is a function that takes a language code and a count, and returns the proper string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This is an example using a special Pluralizable class defined in the package.
&lt;/span&gt;
&lt;span class="n"&gt;song_forms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"song"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"songs"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s"&gt;"pl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"piosenka"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"piosenki"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"piosenek"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;song&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pluralization&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pluralizable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;song_forms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# prints "I am listening to a song"
&lt;/span&gt;&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;f"I am listening to a &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pluralize_by_language&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="s"&gt;""" prints:
0 piosenek
1 piosenka
2 piosenki
3 piosenki
5 piosenek
10 piosenek
"""&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;f"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pluralize_by_language&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'pl'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Internally, there is an indexed dict that returns a function based on the rule number (and languages are tied to rule numbers). The function takes one argument (a count), and returns the correct plural form. All well and good, now how does the code look?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IXZrjRAz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/waxvrepz8lpfxsua7hxm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IXZrjRAz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/waxvrepz8lpfxsua7hxm.png" alt="Pluralization rules code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A lot of lambda functions with an argument &lt;code&gt;c&lt;/code&gt; (our count), and many conditionals. Some might argue that it's hard to read, but I personally find it quite elegant. Admittedly, it needs to be properly documented, and the comment at the top tells us to look at the tests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VdPX9RRl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d4vzt14uvfyx9irolzvj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VdPX9RRl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d4vzt14uvfyx9irolzvj.png" alt="Pluralization rules tests"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right away, we can see that we simply call the &lt;code&gt;pluralization.get_form_from_rule()&lt;/code&gt; function with two arguments (the rule number, and a count), and it returns the form number (&lt;code&gt;0&lt;/code&gt; to &lt;code&gt;n-1&lt;/code&gt;, with different languages having a different number &lt;code&gt;n&lt;/code&gt; of forms). The test function names tell us what rule we are testing, and the counts, and describe the rules - same as the documentation.&lt;/p&gt;

&lt;p&gt;It makes the actual dict really easy to comprehend, IMHO.&lt;/p&gt;

&lt;p&gt;(The complete test suite can be found &lt;a href="https://gitlab.com/patryk-media/polyquack/-/blob/master/tests/test_pluralization.py"&gt;here&lt;/a&gt; if you're interested - I learned a lot about grammar rules in various languages while writing this library and found it fascinating.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 2
&lt;/h3&gt;

&lt;p&gt;This is more of an anecdote than code example. Some time ago, I was tasked with writing a Java app to decrypt a &lt;em&gt;Google Pay&lt;/em&gt; payload using Google's &lt;em&gt;Tink&lt;/em&gt; library.&lt;/p&gt;

&lt;p&gt;I couldn't find any practical examples of what I needed to do, or even the functions I needed to use in the documentation. I simply opened &lt;a href="https://github.com/google/tink/tree/master/java/src/test/java/com/google/crypto/tink"&gt;the &lt;code&gt;tink/java/src/test/&lt;/code&gt; folder&lt;/a&gt;, finally found a working example, used that as a basis for my own code, and it worked.&lt;/p&gt;

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

&lt;p&gt;Hopefully, you have seen another benefit of writing tests with your code. It helps document the code (for developers, not necessarily for end-users), and can make it easy to understand how the code &lt;em&gt;works&lt;/em&gt; internally, or how to &lt;em&gt;use it&lt;/em&gt; in practice.&lt;/p&gt;

&lt;p&gt;Have you ever refered to tests to understand a piece of code before it finally clicked?&lt;/p&gt;

&lt;p&gt;Will you start writing tests to document your code, not just to ensure it works?&lt;/p&gt;

</description>
      <category>testing</category>
    </item>
    <item>
      <title>Testing Web Apps: Types of Testing</title>
      <dc:creator>Patryk</dc:creator>
      <pubDate>Thu, 06 Feb 2020 13:34:29 +0000</pubDate>
      <link>https://dev.to/patryktech/testing-web-apps-types-of-testing-179</link>
      <guid>https://dev.to/patryktech/testing-web-apps-types-of-testing-179</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;If I told you I am passionate about &lt;em&gt;software testing&lt;/em&gt;, you may think I need to get a new hobby. That said, if you never tried writing automated tests, you are truly missing out on a discipline that makes writing software better in every way.&lt;/p&gt;

&lt;p&gt;This post is first in a series that will cover the basics of testing, particularly in relation to web-apps, on the front-end (JavaScript) and back-end (python). If you use a different stack, most of the theory will still apply. If you use JavaScript (Node.js based stack) for the back-end, you can use the many of the same tools for front-end and back-end.&lt;/p&gt;

&lt;p&gt;This part contains a &lt;em&gt;lot&lt;/em&gt; of theory. I still encourage you to read through it - once I add practical examples, it will all make sense. For now, we will cover two types of testing - &lt;em&gt;manual testing&lt;/em&gt; vs &lt;em&gt;automated testing&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Testing?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Code without tests is broken by design.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;~ Jacob Kaplan-Moss&lt;/p&gt;


&lt;/blockquote&gt;

&lt;p&gt;As developers, we often want to deliver software as fast as possible. If we're honest and good developers or engineers, we also want to deliver software that isn't buggy. Writing software isn't just about taking an issue from the issue tracker, writing some code, and closing the issue. If we don't test the code we write, then our customers will have to test it for us, meaning that they will find bugs. That is not fun for your customers, and based on the severity of the bugs they find, they may be put off from using your services altogether.&lt;/p&gt;

&lt;p&gt;That is why we should always test &lt;em&gt;before&lt;/em&gt; we release software... Catching bugs earlier is always cheaper.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manual vs Automated Testing
&lt;/h2&gt;

&lt;p&gt;There are two very common approaches to testing: &lt;em&gt;Manual&lt;/em&gt;, and &lt;em&gt;Automated&lt;/em&gt;. Let us describe them, in case you are not familiar with them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manual Testing
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Manual testing&lt;/em&gt; means that we do everything by hand. We load our website into our browser, click around it, and make sure that it acts as we expect it to.&lt;/p&gt;

&lt;p&gt;It is &lt;em&gt;still an important part&lt;/em&gt; of testing. (Also, it's a very &lt;strong&gt;fun&lt;/strong&gt; part! Who doesn't like seeing first-hand the results of their labor?)&lt;/p&gt;

&lt;p&gt;It used to be very common for companies to spend weeks, or even months working on some feature(s), then passing it off to a QA (Quality Assurance) team for approval. QA engineers had a list of tasks they had to execute manually, and, if they didn't find any bugs, they approved the release. Many companies still do that, but there is a much better way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automated Testing
&lt;/h3&gt;

&lt;p&gt;Strange as it may sound, &lt;em&gt;automated testing&lt;/em&gt; means we write code that tests our code. Many technological companies have now implemented automated testing into their workflow and, to be honest, you probably do not want to work for a company that has not.&lt;/p&gt;

&lt;p&gt;A comparison of manual and automated testing follows, so you can see the benefits for yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparison of Manual and Automated Testing
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Manual testing&lt;/th&gt;
&lt;th&gt;Automated testing&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Protects from user errors&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fast to execute&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Does not add lead time&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prevents repetitive work&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integrates into CI/CD pipelines&lt;/td&gt;
&lt;td&gt;❔&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integrates into TDD&lt;/td&gt;
&lt;td&gt;❔&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prevents regressions&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Is easy to implement&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Protection from user errors
&lt;/h4&gt;

&lt;p&gt;Humans are not as good at repetitive tasks as machines are.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gOx59CAW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pnct87lsb1dm2l8vb0jv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gOx59CAW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pnct87lsb1dm2l8vb0jv.jpg" alt="PEBKAC"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While I have much respect for QA Engineers, they may easily miss a step when running through the app. When you use &lt;em&gt;automated testing&lt;/em&gt;, a machine will run through your tests exactly as you programmed it to. For that reason, test results are more predictable and repeatable.&lt;/p&gt;

&lt;h4&gt;
  
  
  Rapidity of execution
&lt;/h4&gt;

&lt;p&gt;How long would it take you to run 102 tests manually using the interactive python REPL shell?&lt;/p&gt;

&lt;p&gt;In one of my projects, 102 &lt;em&gt;automated tests&lt;/em&gt; run in under a second (disclaimer: that's only the &lt;code&gt;pytest&lt;/code&gt; run - it takes &lt;code&gt;tox&lt;/code&gt; a bit more to set everything up, but it's still &lt;em&gt;really&lt;/em&gt; fast.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zSgovCaF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/v34ricmkujhiztblf8q9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zSgovCaF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/v34ricmkujhiztblf8q9.png" alt="Rapidity"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, not all tests are created equal. Unit tests, integration tests, end-to-end tests, smoke tests... there are many types of tests (that will be covered in a later article), and some of them are slower than others.&lt;/p&gt;

&lt;p&gt;Still - automated testing is generally much &lt;em&gt;much&lt;/em&gt; faster than manual testing.&lt;/p&gt;

&lt;h4&gt;
  
  
  Lead time
&lt;/h4&gt;

&lt;p&gt;On the flip side, a common complaint about &lt;em&gt;automated tests&lt;/em&gt; is that they are time consuming to write whereas &lt;em&gt;manual testing&lt;/em&gt; does not get in the way of releasing software.&lt;/p&gt;

&lt;p&gt;It &lt;em&gt;is&lt;/em&gt; true that writing tests takes a bit more time when writing the code. That said, the amount of manual testing you have to do to ensure there are no regressions (i.e., you implement a new feature, and accidentally break an existing feature that was previously working) grows rapidly, which brings us to...&lt;/p&gt;

&lt;h4&gt;
  
  
  Repetitive work
&lt;/h4&gt;

&lt;p&gt;Remember when I said manual testing was fun? The fun occasionally does get old. If you have to repeat tests manually, it gets really tedious. Worse, if you spend 10 hours a week on manual testing (and you are not a QA engineer, but a developer), that is 10 hours less you have for programming.&lt;/p&gt;

&lt;p&gt;On the other hand, the computer can repeat tasks essentially forever. It is great at it, and its time is generally much cheaper than an engineer's.&lt;/p&gt;

&lt;h4&gt;
  
  
  Integration with CI/CD Pipelines
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Continuous Integration (CI)&lt;/em&gt; is the practice of merging all developers' working copies to a shared mainline (e.g. the &lt;em&gt;master&lt;/em&gt; branch) often - usually several times a day. It makes your merges much smaller, meaning that if there are conflicts in the code of different developers, you will catch the conflict sooner, meaning it is cheaper to fix. Imagine spending a month working on a feature, only to realize that it is incompatible with the work your colleague has done during the same month - you may just have wasted one man-month of work.&lt;/p&gt;

&lt;p&gt;On the other hand, with &lt;em&gt;CI&lt;/em&gt;, you make small incremental merges, with incomplete features.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Continuous Delivery (CD)&lt;/em&gt; is an approach that ensures that software can be reliably released at any time. It uses a &lt;em&gt;deployment pipeline&lt;/em&gt; - a set of validations the software must pass in order to be released.&lt;/p&gt;

&lt;p&gt;Automated testing helps tremendously - you can configure pipelines to run your tests every time you push to your &lt;code&gt;git&lt;/code&gt; repository on GitLab, GitHub, etc. It is good practice to also run manual tests on your software before releasing it to production... You can use a &lt;em&gt;Continuous Deployment&lt;/em&gt; pipeline to build a &lt;em&gt;Staging&lt;/em&gt; version of your website, and run automated and / or manual tests against it.&lt;/p&gt;

&lt;p&gt;That said, manual testing does not fully integrate into &lt;em&gt;CI/CD Pipelines&lt;/em&gt; since those are &lt;em&gt;meant to be&lt;/em&gt; automated.&lt;/p&gt;

&lt;h4&gt;
  
  
  Integration with TDD
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Test-driven Development (TDD)&lt;/em&gt; is a development technique where you write tests first, watch them fail, write the minimal amount of code you need to make the tests pass, then refactor the code.&lt;/p&gt;

&lt;p&gt;I originally was going to say you can't do &lt;em&gt;TDD&lt;/em&gt; with manual testing, as I have never heard of anyone doing that... But I guess, in a way, we all &lt;em&gt;sort of&lt;/em&gt; do it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define the functionality your website should have.&lt;/li&gt;
&lt;li&gt;Create a basic HTML file (or Vue.js, React, Angular, etc. project).&lt;/li&gt;
&lt;li&gt;Open it in your browser.&lt;/li&gt;
&lt;li&gt;Add some functionality, reload the browser, and test if it works as expected.&lt;/li&gt;
&lt;li&gt;Repeat until your website is feature-complete.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, &lt;em&gt;theoretically&lt;/em&gt;, I guess you can integrate &lt;em&gt;TDD&lt;/em&gt; and &lt;em&gt;manual testing&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That said, &lt;em&gt;most&lt;/em&gt; people who claim to practice &lt;em&gt;TDD&lt;/em&gt; do it with &lt;em&gt;automated&lt;/em&gt; tests. A practical example of &lt;em&gt;TDD&lt;/em&gt; will follow later in this series.&lt;/p&gt;

&lt;h4&gt;
  
  
  Preventing regressions
&lt;/h4&gt;

&lt;p&gt;A &lt;em&gt;software regression&lt;/em&gt; is a bug that breaks functionality that worked previously, e.g. something that works in versions 1.0-1.5, but break in version 1.6.&lt;/p&gt;

&lt;p&gt;When using &lt;em&gt;manual testing&lt;/em&gt;, you typically focus on testing &lt;em&gt;new&lt;/em&gt; functionality, and the most crucial features that were known to work previously. It is very time-consuming to test &lt;em&gt;all&lt;/em&gt; functionality manually, so it is very easy to miss a bug that suddenly appears.&lt;/p&gt;

&lt;p&gt;With &lt;em&gt;automated testing&lt;/em&gt;, if you introduce a new bug, a test should fail, and you should be aware of it before you release. If your tests fail to detect it, you write new tests to cover the case at the same time you fix the bug - then you can be sure the bug will not reappear.&lt;/p&gt;

&lt;h4&gt;
  
  
  Difficulty
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Manual testing&lt;/em&gt; is obviously easy. As long as you can use a computer, you can test your website's functionality (although testing all edge cases may prove much more difficult than you expected).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Automated testing&lt;/em&gt; is honestly very difficult to get right. You need to learn the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test tools&lt;/li&gt;
&lt;li&gt;How to write tests that...

&lt;ul&gt;
&lt;li&gt;Test the right thing&lt;/li&gt;
&lt;li&gt;Pass for the right reasons&lt;/li&gt;
&lt;li&gt;Fail for the right reasons&lt;/li&gt;
&lt;li&gt;Do not break when you write new code&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion (part 1)
&lt;/h2&gt;

&lt;p&gt;Hopefully, the difficulty will not put you off from adding automated testing to your arsenal - like all things, you will get better at it with practice.&lt;/p&gt;

&lt;p&gt;Stay tuned for the next installments in this series, we still have plenty of things to cover, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test tools&lt;/li&gt;
&lt;li&gt;Types of tests (unit tests, integration tests, smoke tests, end-to-end tests, regression tests, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;TDD&lt;/em&gt; in detail&lt;/li&gt;
&lt;li&gt;What to test&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I further hope that by the time this series is complete, you will be as passionate about testing as I am 😄.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Continuous_delivery"&gt;&lt;em&gt;Continuous Delivery&lt;/em&gt; page on &lt;em&gt;Wikipedia&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Continuous_integration"&gt;&lt;em&gt;Continuous Integration&lt;/em&gt; page on &lt;em&gt;Wikipedia&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>testing</category>
      <category>javascript</category>
      <category>python</category>
    </item>
  </channel>
</rss>
