<?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: Christian Baer</title>
    <description>The latest articles on DEV Community by Christian Baer (@donut87).</description>
    <link>https://dev.to/donut87</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%2F14226%2Faecdb417-8e07-4c86-93a7-e8a6ef6a1b3a.jpeg</url>
      <title>DEV Community: Christian Baer</title>
      <link>https://dev.to/donut87</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/donut87"/>
    <language>en</language>
    <item>
      <title>Band Audition during a pandemic</title>
      <dc:creator>Christian Baer</dc:creator>
      <pubDate>Mon, 04 Oct 2021 14:57:17 +0000</pubDate>
      <link>https://dev.to/donut87/band-audition-during-a-pandemic-4159</link>
      <guid>https://dev.to/donut87/band-audition-during-a-pandemic-4159</guid>
      <description>&lt;h1&gt;
  
  
  Problem
&lt;/h1&gt;

&lt;p&gt;As many many people we as a band faced issues with the Corona pandemic. Since this is a hobby project for all of us and we did not even had a gig yet, the problem is much smaller for us than for professional or semi professional bands. But still, we faced the situation, that we could no longer meet in our rehearsal room and make music together, which we usually quite enjoy. Also we were on track on getting our first songs together for playing small gigs on stage in 2020.&lt;/p&gt;

&lt;p&gt;We are a band of 5 people with 3 of us working in IT, so we pretty early set out to find a solution to our problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;We briefly discussed, meeting anyway, as we were pretty sure, no one would be prosecuting us. Everyone was kind of relieved, that no one really wanted to opt for this path. This proved to be the first "Corona character test" for all of us, I guess.&lt;/p&gt;

&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;h3&gt;
  
  
  What we wanted
&lt;/h3&gt;

&lt;p&gt;An easy to use solution for all of us (vocals, guitar, guitar, drums, bass) to make music together online.&lt;/p&gt;

&lt;p&gt;The solution had to be easy to use, because (as said earlier) we are 3 out of 5 working in IT and driving around giving IT support and installing everything was out of the question. Everybody had to be able to do the setup with minimal to no help.&lt;/p&gt;

&lt;h3&gt;
  
  
  First ideas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Skype&lt;/li&gt;
&lt;li&gt;discord&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these platforms match the easy-to-use criteria, but are not good for playing together and there is a simple reason: latency.&lt;/p&gt;

&lt;h4&gt;
  
  
  Latency
&lt;/h4&gt;

&lt;p&gt;Playing together means, that everybody has to listen to everybody else. Even the drummer! So if the signal needs 300ms to travel from dummer to everybody else, everybody reacts to that and it then needs another 300ms to travel back to the drummer, rehearsing is not going to work.&lt;br&gt;
So, latency is a key factor in music.&lt;br&gt;
But the major platforms for online communication use 'high' latency for a reason. This way, background noises, feedback, echo and stuff like that can be filtered much easier and synchronizing all participants gets possible. Also ~300ms is fine for meetings and 1:1 talks. Just not for music.&lt;/p&gt;

&lt;p&gt;There had to be another way. We couldn't probably be the first ones looking into this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Possible Softwares
&lt;/h3&gt;

&lt;p&gt;We weren't. There are plenty of softwares, that promise you online distributed rehearsal, instrument teaching, recording and jamming. A few that pop up early in any online search are Ninjam (complex), JamKazam (closed source), Bandlab (commercial), eJamming (register first on website), Jamulus (FOSS, but seemed very basic)&lt;/p&gt;

&lt;h3&gt;
  
  
  Our Hardware
&lt;/h3&gt;

&lt;p&gt;Since we already talked about latency, let's not forget, that the internet is not the only thing to add latency. Computer Hardware does too. It's not 300ms, but a few ms here and there add up and you are out of sync.&lt;br&gt;
Our bassist had a setup using a Scarlett Focusrite 2i2 and somehow managed to get this with ALSA &lt;/p&gt;

&lt;p&gt;So our Journey began :-)&lt;/p&gt;

&lt;h4&gt;
  
  
  Mid March
&lt;/h4&gt;

&lt;p&gt;After having a look over various possible solutions (and grabbing our gear from our rehearsal room) we opted for JamKazam. JamKazam has a central server, that the people behind JamKazam fully own. Which was fine for us, as we got the idea, that this was not easy and better left to people who know their stuff.&lt;br&gt;
Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure Audio input with gear latency measurement&lt;/li&gt;
&lt;li&gt;Text chat&lt;/li&gt;
&lt;li&gt;Audio chat

&lt;ul&gt;
&lt;li&gt;nice for communication between songs&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Video Chat

&lt;ul&gt;
&lt;li&gt;Seeing each other is nice!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Set volume and balance for each participating musician

&lt;ul&gt;
&lt;li&gt;really handy to have distribute instruments to left and right&lt;/li&gt;
&lt;li&gt;adjust volume of everybody to your needs (tune out singer 😉)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Insert audio track file

&lt;ul&gt;
&lt;li&gt;This would be the key killer feature, but we didn't know that at first&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;It seemed to offer all we needed and was easy enough to use. If only that was the whole truth.&lt;/p&gt;

&lt;p&gt;To test JamKazam the 3 IT guys registered, and tried to start a session. Keep in mind, this was the beginning of the restrictions and it seemed musicians from all over the world were trying to find solutions and lots of them tried to start a session with the very same tool. With some frustration we gave up and met again a week later to try again. This time it kind worked for us 3. Latency was around 40 to 60ms. We could work with that!&lt;/p&gt;

&lt;p&gt;Our drummer did not even get to register through the Client software, as no connection to the server could be established. We figured, through various screen sharing session via Skype and even VNC, that his router was configured very strictly. Not necessarily a bad thing, but he lost his admin password. So we had to start without him.&lt;/p&gt;

&lt;h4&gt;
  
  
  April
&lt;/h4&gt;

&lt;p&gt;Being short of a drummer, we were glad about the audio track, as all our songs are well written down using GuitarPro. Exporting the drum tracks as wav file was easy and so rehearsal could start.&lt;/p&gt;

&lt;p&gt;If it wasn't for latency again 🙈. This time from our singer. His situation at that point was a WiFi bridge and a rather shitty ISP. So latency was between 300 and 1200ms. We kind of tuned him out...&lt;/p&gt;

&lt;p&gt;It was not much, but we still had some hope, that this would all be over soon.&lt;/p&gt;

&lt;h4&gt;
  
  
  May
&lt;/h4&gt;

&lt;p&gt;It was not over soon...&lt;/p&gt;

&lt;p&gt;To solve at least the WiFi bridge problem, we bought a &lt;a href="https://smile.amazon.de/dp/B00EOTHDWQ/"&gt;long CAT-6 network cable&lt;/a&gt;. This had to go through the garden into the main house. He lives in a the renovated garage, so they even dug up the ground and buried the cable. So latency was better. Still not perfect, but better most of the times.&lt;br&gt;
We were still lacking a drummer, but we could not do anything about that.&lt;/p&gt;

&lt;h4&gt;
  
  
  June
&lt;/h4&gt;

&lt;p&gt;Not much rehearsing going on. We had more important things to do. Hard to believe, but getting married was more important for on of our guitarists (groom) and the bassist (best man).&lt;/p&gt;

&lt;h4&gt;
  
  
  July through September/October
&lt;/h4&gt;

&lt;p&gt;Since we live and rehearse in Berlin, we got to see each other again over the summer on our rehearsal room. We once again had a drummer!&lt;/p&gt;

&lt;h4&gt;
  
  
  November
&lt;/h4&gt;

&lt;p&gt;Covid struck again. The anticipated 2nd wave was there and we were once again at home. One major thing improved compared to spring:&lt;br&gt;
Our drummer did reset his router and was able to register.&lt;/p&gt;

&lt;p&gt;Unfortunately, connecting his e-drum set to a computer proved to be a challenge. So we were back with JamKazam, no drummer and a slightly lacking vocalist. But even that improved, as he switched ISPs.&lt;/p&gt;

&lt;p&gt;Unfortunately, JamKazam got worse with every update and updates came weekly.&lt;/p&gt;

&lt;p&gt;Some of us had to reconfigure the audio setup each week and the chat microfon of our guitarist and bassist was not usable anymore.&lt;/p&gt;

&lt;p&gt;Nevertheless we carried on, using discord in parallel for chatting.&lt;/p&gt;

&lt;p&gt;Lesson learned: Mute your discord mic, or your band colleagues will hear your "unplugged" sound next to your real sound, with some latency.&lt;/p&gt;

&lt;h4&gt;
  
  
  December
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Drummer finally joins, JamKazam gets worse
&lt;/h5&gt;

&lt;p&gt;JamKazam still did not get much better, but our drummer geared up and was able to join us in our weekly sessions. We had live drums. Oh the glory and joy. Ask his neighbours. Turns out, even an e-drum can make too much noise.&lt;/p&gt;

&lt;p&gt;Now that we finally felt, we had a more or less stable solution at hand, an announcement from JamKazam came in. Beginning in 2021 they will start charging money for using JamKazam. We looked at the plans they offered. Between the 4 plans free, silver ($4.99/month and person), gold ($9.99/month and person) and platinum ($19.99/month and person) the gold option would have been the one to continue the way we rehearsed through the year.&lt;/p&gt;

&lt;p&gt;As I said, we are 3 people working in IT and two of us are software developers. So paying for software is fine. As long as it is worth it. Since not all of us got through the pandemic without losing jobs/income we even would be able to distribute the 50$ among the others. Paying for a service is really not the problem. Paying 50$ for a service that got worse every time on the other hand, was not in our interest.&lt;/p&gt;

&lt;h5&gt;
  
  
  The Search for another tool
&lt;/h5&gt;

&lt;p&gt;So it was time to revisit the list of alternatives. If only we had saved that list somewhere. So back to zero and search the internet once again.&lt;/p&gt;

&lt;p&gt;Online search was faster this time, because we had a better idea of what we were looking for and the tool of our choosing was &lt;a href="https://jamulus.io/"&gt;Jamulus&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Features and perks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure Audio input

&lt;ul&gt;
&lt;li&gt;more basic than JamKazam, but still good enough&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Set volume and balance for each participating musician&lt;/li&gt;
&lt;li&gt;Overall Latency measurement

&lt;ul&gt;
&lt;li&gt;ping to server&lt;/li&gt;
&lt;li&gt;overall latency&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Multiple open servers available&lt;/li&gt;
&lt;li&gt;Text chat&lt;/li&gt;
&lt;li&gt;Configure buffer size

&lt;ul&gt;
&lt;li&gt;So you can decide what is more important quality or speed.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;FOSS (GPL 2.0)

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/corrados/jamulus"&gt;Repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;Audio chat is a missing feature, but since we had to work around that before, it wasn't a big issue. Also uploading a wav file and playing it to everyone does not work, but our drummer has joined the online party so, this was also not a big issue.&lt;/p&gt;

&lt;h5&gt;
  
  
  Testing on a public server
&lt;/h5&gt;

&lt;p&gt;Public servers are public. So anyone can join. For a quick test this was fine, as there are empty servers out there, if you are lucky. Along the way some people joined, but we quickly muted them and as soon as they got, that we were not trying to jam with strangers on the internet, we could try this out.&lt;/p&gt;

&lt;p&gt;Unfortunately the connection of our bassist was so bad, Jamulus seemed to be unusable. The issue was already visible with JamKazam, but got worse with Jamulus. Best guess: Jamulus server did more compression because of slow internet connection.&lt;/p&gt;

&lt;h5&gt;
  
  
  Private server and a faster connection
&lt;/h5&gt;

&lt;p&gt;Switching ISPs did the trick again. Ping and bandwith improved massively for our bassist and we had our last rehearsal with JamKazam on 29th of December. After that we had to have a new solution.&lt;/p&gt;

&lt;p&gt;So we decided against one of us hosting this at home, configuring port forwarding, sharing his current IP address with the band, and everybody connecting after copying the address in the to Jamulus client. It should be easy to use 😉. Only other solution was to rent a server. Since renting real hardware in some data center is expensive (we were kind of on a 50$/€ budget), we decided to try out a vServer, which are very cheap compared to bare metal servers. Having a budget of 50€ meant we could choose from a variety of providers and basically all plans. To not jeopardize the mission by being cheap, we opted for a 4 core vServer with 8GB RAM from 1&amp;amp;1/ionos for 16€/month. Turns out, these are some Intel Xeon Gold 5120 CPUs working there and it is of course a vmware machine.&lt;/p&gt;

&lt;h5&gt;
  
  
  Installing Jamulus
&lt;/h5&gt;

&lt;p&gt;Installing Jamulus is actually pretty easy, if you are familiar with linux and/or docker. You can install this directly to the system or just start up a &lt;a href="https://hub.docker.com/r/grundic/jamulus"&gt;docker container&lt;/a&gt;. Since starting up a docker container is fairly easy, I tested this. It also comes with a nice &lt;a href="https://github.com/grundic/jamulus-docker"&gt;docker-compose&lt;/a&gt; file. The result was a little bit astonishing. Connecting to my server was easy enough after configuring the 1&amp;amp;1 firewall to open port 22124 and there it said overall latency 60ms with 25ms on my behalf (network plus hardware latency). Not bad!&lt;br&gt;
Reading through the documentation of how to run your own server and the &lt;a href="https://jamulus.io/wiki/Installation-for-Linux"&gt;Linux how-to page&lt;/a&gt;, I decided to opt for a low-latency-kernel. Result: 50ms! Down 10ms.&lt;/p&gt;

&lt;h5&gt;
  
  
  First real band rehearsal with Jamulus and private server
&lt;/h5&gt;

&lt;p&gt;Although the Jamulus wiki clearly states "Close every application, that deals with sound or internet!", we met at discord and Jamulus and started playing. Worked like a charm.&lt;/p&gt;

&lt;p&gt;The vServer is vastly oversized. I had htop open the whole time and the load average did not even make it over 0.5 and not even 600MB RAM were used. So we might scale down to half the size, which will reduce costs by half.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lessons learned
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Jamming, rehearsing event teaching instruments is possible.&lt;/li&gt;
&lt;li&gt;Good internet connection is a must have&lt;/li&gt;
&lt;li&gt;Quality gear makes your life easier&lt;/li&gt;
&lt;li&gt;Do not give up!&lt;/li&gt;
&lt;li&gt;It is still much more fun in person&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>One assert per test - What is that about?</title>
      <dc:creator>Christian Baer</dc:creator>
      <pubDate>Wed, 16 May 2018 15:23:25 +0000</pubDate>
      <link>https://dev.to/donut87/one-assert-per-test---what-is-that-about-4l75</link>
      <guid>https://dev.to/donut87/one-assert-per-test---what-is-that-about-4l75</guid>
      <description>

&lt;p&gt;A colleague outside my team asked me and other colleagues to review a merge request. Although we try to hone our reviewing skills, it doesn't happen all too often that we invite colleagues outside of our specific teams to review. This was one of the cases and I appreciated the opportunity to give my two cents.&lt;/p&gt;

&lt;p&gt;I was in the middle of my review when the colleague came by and asked for a first impression. I had looked briefly into the sources so my answer was brief as well: "I don't like your unit tests". When he inquired further why I didn't like them my answer was "Because they are shit." I know it sounds harsh - I am not a mean person, but I'm blunt and tend to exaggerate. Thankfully my colleague knows that and we agreed to talk again when I've had enough time to figure out why I didn't like the tests.&lt;/p&gt;

&lt;p&gt;I sat down and took some time to figure out what bothered me and I want to share it with you.&lt;/p&gt;

&lt;h1&gt;
  
  
  More Than One Assert Per Test
&lt;/h1&gt;

&lt;p&gt;One thing that was clear to me when I looked at the code, was the use of more that one assert per unit test. I'm not a fan of rules without reason so I had to have a closer look to make sure that it wasn't gut feeling. This is a broadly discussed topic, but I want to add my two cents.&lt;/p&gt;

&lt;p&gt;One reason that seems to come up every time the internet discusses this topic is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You won't see if there is something wrong with the second assert if the first one fails.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://programmaticallyspeaking.com/one-assertion-per-test-please.html"&gt;See here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although the argument is true, I find it to be weak and tend not to use it. I don't consider it a problem.&lt;br&gt;
I have a different gripe with it, and I've drawn two examples that I want to share with you to illustrate.&lt;br&gt;
For privacy and brevity I simplified the tests, but let the essence intact.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testIfRegistryGetsValuesCorrectly&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Registry&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Registry&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// Imagine some setup code here.&lt;/span&gt;
  &lt;span class="c1"&gt;// originally there was a before-each method&lt;/span&gt;

  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEntryByKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RandOMstRIng"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEntryByKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"randomstring"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEntryByKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"   rand   oms.tri ng"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEntryByKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"randomstring"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEntryByKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"randomst37ring"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEntryByKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"randomstring"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The test works fine and meets the requirements. Cut out all non-characters of the key and make it lowercase before you ask for the value. Everything seems fine.&lt;br&gt;
The problem becomes clear when you touch the tested method and break the 'testIfRegistryGetsValuesCorrectly' test.&lt;/p&gt;

&lt;p&gt;As a developer working on the implementation, you're not going to find out what doesn't work any more. At least not at first sight.&lt;br&gt;
You will understand that the test broke, this is what the name tells you.&lt;/p&gt;

&lt;p&gt;I suggested refactoring the test to the below code.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testIfRegistryIgnoresCases&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Registry&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Registry&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// Imagine some setup code here.&lt;/span&gt;
  &lt;span class="c1"&gt;// originally there was a before-each method&lt;/span&gt;

  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEntryByKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RandOMstRIng"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEntryByKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"randomstring"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testIfRegistryIgnoresNonCharacters&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Registry&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Registry&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// Imagine some setup code here.&lt;/span&gt;
  &lt;span class="c1"&gt;// originally there was a before-each method&lt;/span&gt;

  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEntryByKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" 3  ra8nd   oms.tri ng"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEntryByKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"randomstring"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With these changes in place, you will understand the problematic behavior with a quick glance.&lt;br&gt;
Dots are now allowed? You know what to do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You broke one well defined test&lt;/li&gt;
&lt;li&gt;You fix the test according to new requirements&lt;/li&gt;
&lt;li&gt;You &lt;em&gt;rename&lt;/em&gt; the test&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Explicit Naming
&lt;/h1&gt;

&lt;p&gt;Before continuing I'd like to present a second example to illustrate. Mind you: I simplified the tests, but let the essence intact.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testConstructorOneWorksCorrectly&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;SpecialObjectClass&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SpecialObjectClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"someID"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"attribute1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"attribute2"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getID&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"someID"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFirstAttribute&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"attribute1"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSecondAttribute&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"attribute2"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testConstructorTwoWorksCorrectly&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;SpecialObjectClass&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SpecialObjectClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"someID"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"attribute1:attribute2"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getID&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"someID"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFirstAttribute&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"attribute1"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSecondAttribute&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"attribute2"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testConstructorTwoWorksCorrectlyWithoutSecondParameter&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;SpecialObjectClass&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SpecialObjectClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"someID"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"attribute1"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getID&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"someID"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFirstAttribute&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"attribute1"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSecondAttribute&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"attribute1"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The problem with the above example is similar, but not as obvious. The complex logic lies in the second and optional third parameter. The ID parameter ("someID") is trivial and distracts more than it helps in each of the test cases. If something breaks in the handling of the ID parameter the three unit tests will break for the same reason.&lt;/p&gt;

&lt;p&gt;I have two problems with that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It violates the idea behind a unit test, which is to test single isolated units&lt;/li&gt;
&lt;li&gt;It confuses the poor developer changing the tested code in the future. (Who could also be the author itself after a couple of months)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I suggested to refactor to the following form:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testConstructorSetsID&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;SpecialObjectClass&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SpecialObjectClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"someID"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"attribute1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"attribute2"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getID&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"someID"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testConstructorSetsBothAttributes&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;SpecialObjectClass&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SpecialObjectClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"someID"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"attribute1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"attribute2"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFirstAttribute&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"attribute1"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSecondAttribute&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"attribute2"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testConstructorTwoSplitsAttributesAtTheColon&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;SpecialObjectClass&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SpecialObjectClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"someID"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"attribute1:attribute2"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFirstAttribute&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"attribute1"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSecondAttribute&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"attribute2"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testConstructorTwoSetsSecondAttributeSameValueAsTheFirstIfNotGiven&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;SpecialObjectClass&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SpecialObjectClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"someID"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"attribute1"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFirstAttribute&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"attribute1"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSecondAttribute&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"attribute1"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;My naming here may not be perfect, but it gets the point across. And as you may have noticed, the &lt;em&gt;one&lt;/em&gt; word that was present in &lt;em&gt;all&lt;/em&gt; the unit tests is now gone: "&lt;em&gt;Correctly&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;This was my small epiphany. &lt;br&gt;
As a word, "Correctly" should never be part of a test case's name. It does not provide any information at all.&lt;/p&gt;

&lt;p&gt;Having found out my two gripes with the tests, I came up with a pattern for myself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;test case with multiple assertions -&amp;gt; look out for this dangerous word ("&lt;em&gt;Correctly&lt;/em&gt;") and change test case accordingly&lt;/li&gt;
&lt;li&gt;dangerous word in the title -&amp;gt; look at the assertions to figure out what this test does and change the name&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That was my learning of the day: There are words that should not be part of any test case's name, and it's: "Correctly".&lt;/p&gt;

&lt;p&gt;There might be more. Look out for them!&lt;/p&gt;

&lt;p&gt;P.S.: The colleague that I spoke of in this article, was asked to proofread the article. Besides helping a lot with proper English, he also added a thought of his own. "As developers we often think about naming, and sometimes we seem to miss the most obvious points - or we tend to become lazy."&lt;/p&gt;


</description>
      <category>unittests</category>
      <category>review</category>
      <category>codequalitity</category>
      <category>collaboration</category>
    </item>
    <item>
      <title>Cooking: A Perfect Hobby for Programmers</title>
      <dc:creator>Christian Baer</dc:creator>
      <pubDate>Mon, 25 Dec 2017 10:23:44 +0000</pubDate>
      <link>https://dev.to/donut87/coking-a-perfect-hobby-for-programmers-15j6</link>
      <guid>https://dev.to/donut87/coking-a-perfect-hobby-for-programmers-15j6</guid>
      <description>&lt;p&gt;Everybody needs a hobby. It takes your mind off of work and can help you develop your creativity or just relax to get creative again. Side projects are fine, but then again it is programming and this is what you are doing all day anyway. Here are some reasons why I think cooking is a great hobby for programmers.&lt;/p&gt;

&lt;p&gt;The most important reason is not specific to programmers: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You get food!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The basic idea of cooking is, to make/prepare your own food, which is a very fine thing. Of course, there are the days when we just want to eat and order something delivered to our homes, have some takeaway or eat that microwave stuff. That is ok, but nothing beats self-prepared food. You know exactly what you put in and will enjoy the meal because you put effort into it. It just tastes a little bit better.&lt;br&gt;
Let us move on to the more programmer specific reasons: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A recipe is an algorithm.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Follow it and you will get exactly what the author intended. Make a mistake and it might be edible (just a little bit burned) or you can throw that whole thing away (you used salt instead of sugar). Didn’t we all forget those semicolons at the beginning? Didn’t we all at some point wrote something like &lt;code&gt;if (i = 1)&lt;/code&gt; and wondered for hours why the code did not work as the textbook said? We all got past that and learned to avoid those mistakes. You will eventually learn to cut your vegetables all beforehand and not ‘on the fly’. Which takes me to the next reason: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There is so much you can learn.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Part of being a programmer/software developer is the continuously learning. This is one of the reasons why I like being a programmer. I learn something new every day and I can utilize my knowledge. The same thing happens when you cook. You look at different recipes and learn from them. If you find some good books (or web pages) where there is an explanation not only about the what to do but also on why you are doing this, you can learn all the more. You get to understand why a little bit of citric acid let your apples stay fresh and keeps them from getting brown. As you begin to understand more and more you can go on to the experimenting. This would be the next very good reason:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can tinker around with recipes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As I mentioned earlier, recipes are algorithms. So why not change them and see what happens. This is best done alone. When you are cooking for your family holiday dinner, (much like fixing bugs in the live environment) you better stick to the plan! In other scenarios experimenting is great. Again, at the start, it is much like when you started coding. Start with some small improvements. You got no lemons in the house but limes? See what happens, when you switch it! The recipe states an amount of sugar? Go for the dark honey and see what it does! &lt;br&gt;
My last point: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You are able to share your findings.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is not like there is a GitHub for cooking, but there are other sites. Go into the comments of recipes and share your small changes. Share your traditional family recipes with the world (you know, the famous cookies from grandma, the world needs to know) and get feedback.&lt;/p&gt;

&lt;p&gt;I think the idea is why cooking is a great hobby is clear. You prepare your own food, you can follow algorithms, get creative over time and share your experiences. Basically, everything programmers like without touching a keyboard.&lt;/p&gt;

</description>
      <category>hobbies</category>
      <category>cooking</category>
      <category>programmers</category>
    </item>
    <item>
      <title>Don't let programmers alone</title>
      <dc:creator>Christian Baer</dc:creator>
      <pubDate>Wed, 04 Oct 2017 16:25:00 +0000</pubDate>
      <link>https://dev.to/donut87/dont-let-programmers-alone-bhh</link>
      <guid>https://dev.to/donut87/dont-let-programmers-alone-bhh</guid>
      <description>

&lt;p&gt;Recently I discovered a small piece of code that looked like this:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function isElementSpecial(htmlElementToBeChecked) {
  var result
  if(document.querySelector(htmlElementToBeChecked).classList.contains('special')) {
    result = true
  } else {
    result = false
  }
  return result
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I cringed.&lt;br&gt;
My first thought after my initial shock was: 'What on earth was this developer thinking while writing this?' I had to look at this a couple of times to make sure that the above code really only does one thing. Checking that an HTML element has the class &lt;code&gt;special&lt;/code&gt;. &lt;br&gt;
Since I had no time to investigate the how and why this code came to life, I did what every programmer would have done and quickly condensed the code to its essential core.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function isElementSpecial(htmlElementToBeChecked) {
  return document.querySelector(htmlElementToBeChecked).classList.contains('special')
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Since I know whom amongst my colleagues did write this code, I was tempted to ask him straight away why he was writing a simple check in such a complicated manner. Luckily he had already gone home. So I had some minutes to think about what went wrong.&lt;br&gt;
Some facts&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The code is from our front-end test system&lt;/li&gt;
&lt;li&gt;The responsible colleague is a senior programmer with some experience in that field&lt;/li&gt;
&lt;li&gt;He built our testing framework on top of CasperJS by himself&lt;/li&gt;
&lt;li&gt;He has his hands full with keeping our front-end tests stable&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Look at point 3. He built this by &lt;strong&gt;himself&lt;/strong&gt;!&lt;br&gt;
There was no one to review, question or criticize his code.&lt;br&gt;
In my opinion, this could have been prevented by someone reviewing his changes in regular and short intervals. &lt;br&gt;
We as programmers build complex (and often large) systems. Having a complete in-depth knowledge of all lines of code is impossible, even if one single person wrote them all. Consequently, it is only natural to forget about that one line or method you wanted to refactor or rewrite. Also, there is a higher risk of getting attached to your code. Why this is a bad idea is excellently explained &lt;a href="https://dev.to/lpasqualis/12-reasons-to-avoid-individual-code-ownership"&gt;here&lt;/a&gt;.&lt;br&gt;
There are only two methods known to me to reduce all of this. The first one is pair programming and the second one is code reviews. If for whatever reason pair programming is not an option (e.g. distributed team), that leaves only code review.&lt;br&gt;
There are many good 'manuals' for the dos and don'ts of good code reviews (e.g. &lt;a href="https://dev.to/samjarman/giving-and-receiving-great-code-reviews"&gt;This&lt;/a&gt;).&lt;br&gt;
At my workplace, we do team code review, although most of our code is done while pairing. Every morning we ask ourselves 'do we have something to show the team' and then the projector is turned on and we have a good half an hour of looking at code diffs and asking questions. This often enough reveals useless comments, ambiguous variable/method names and other code styling issues. We also have a general idea of the code that our team produces and our bus factor is increased drastically.&lt;br&gt;
In short: Do code reviews and do them often. There is a high chance of making your code understandable, increasing the bus factor and reducing the attachment to the code.&lt;/p&gt;


</description>
      <category>codereview</category>
      <category>collaboration</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Hi, I'm Christian</title>
      <dc:creator>Christian Baer</dc:creator>
      <pubDate>Thu, 30 Mar 2017 09:17:03 +0000</pubDate>
      <link>https://dev.to/donut87/hi-im-christian</link>
      <guid>https://dev.to/donut87/hi-im-christian</guid>
      <description>&lt;p&gt;I have been coding for about 10 years.&lt;/p&gt;

&lt;p&gt;You can find me on GitHub as &lt;a href="https://github.com/donut87" rel="noopener noreferrer"&gt;donut87&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I live in Berlin.&lt;/p&gt;

&lt;p&gt;I mostly program in these languages: Java.&lt;/p&gt;

&lt;p&gt;I am currently learning more about Clean Code.&lt;/p&gt;

&lt;p&gt;Nice to meet you.&lt;/p&gt;

</description>
      <category>introduction</category>
    </item>
  </channel>
</rss>
