<?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: corgibytes</title>
    <description>The latest articles on DEV Community by corgibytes (@corgibytes).</description>
    <link>https://dev.to/corgibytes</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F7%2Fcorgibyteslogo.png</url>
      <title>DEV Community: corgibytes</title>
      <link>https://dev.to/corgibytes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/corgibytes"/>
    <language>en</language>
    <item>
      <title>Announcing MenderCon</title>
      <dc:creator>M. Scott Ford</dc:creator>
      <pubDate>Thu, 07 May 2020 19:38:16 +0000</pubDate>
      <link>https://dev.to/corgibytes/announcing-mendercon-kk5</link>
      <guid>https://dev.to/corgibytes/announcing-mendercon-kk5</guid>
      <description>&lt;p&gt;I recently announced on a few different social platforms that Corgibytes and Legacy Code Rocks are hosting a conference.&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;h2 id="qa"&gt;Q&amp;amp;A&lt;/h2&gt;

&lt;p&gt;Since I published the initial post, we’ve had a lot of interest, and with that interest has come some questions. In hopes that others might find it helpful, I’d like to take a few moments to answer most of those questions here.&lt;/p&gt;

&lt;h3 id="why-is-it-called-mendercon"&gt;Why is it called “MenderCon”?&lt;/h3&gt;

&lt;p&gt;The term &lt;em&gt;mender&lt;/em&gt; was coined by me and Andrea after I saw an ad for a Maker Fest event and I said “where’s the event for people who like to fix things?!”. That’s what I want this event to be. It’s an event for people who are passionate about mending software systems. I want to limit the use of the phrase “legacy code”. While we’re using that term to market the conference, I don’t want the phrase to be directly in the title. I’m also intentionally avoiding “virtual” in the event name. Again, that can be something that’s communicated when describing the event, but I don’t want it to be a defining feature. If the event happens again in the future, we might be able to run it as an in-person event. In that case, I don’t want to have to change the name.&lt;/p&gt;

&lt;h3 id="why-now"&gt;Why now?&lt;/h3&gt;

&lt;p&gt;I’ve been wanting to host a conference focused on modernizing software for years. It’s been on the Corgibytes’ wish list for at least 5 years. The logistics of an in-person conference seemed overwhelming, especially because we don’t really have anyone on our team with natural event organizing talents. Since we’re an all-remote company, more than one person has proposed over the years that we try to run an all-remote conference. But with so many great in-person conferences, I was nervous that an all-remote event would not be successful.&lt;/p&gt;

&lt;p&gt;Then COVID-19 hit. Now, all over the world, people are sheltering in place. Many in-person conferences have been canceled or indefinitely postponed. Many people are craving more opportunities for professional connection and learning. Many people are working from home for the first time.&lt;/p&gt;

&lt;p&gt;I figured if there was any time when an all-remote conference might have a chance it would be now, and frankly with all of the stress caused by the pandemic, I need something positive to look forward to. Organizing this event has been a welcome distraction from feeling helpless about the state of the world around me.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;And&lt;/em&gt; I think it’s incredibly important, especially right now, that we talk more intentionally about the long term maintenance and nurturing of software systems. There have been numerous reports of neglected systems being unable to adapt to the changes that are required of them, either in terms of functionality or load.&lt;/p&gt;

&lt;h3 id="whats-an-un-conference"&gt;What’s an un-conference?&lt;/h3&gt;

&lt;p&gt;Simply put, an un-conference is a conference that does not have a predetermined set of speakers or talks. The people who show up to the event are the ones who decide what gets talked about.&lt;/p&gt;

&lt;p&gt;This approach eliminates a fair bit of overhead for organizing the event. We don’t need to put out a call for proposals. We don’t need to go through proposals and decide who gets to speak. We don’t have to verify that the people who submitted proposals are still available, and we don’t have to notify everyone who didn’t get selected.&lt;/p&gt;

&lt;p&gt;The un-conference format also creates an opportunity to elevate voices who are not normally heard from. At a traditional conference, the list of speakers and topics is curated in some form by the organizers. This can often lead to the conference schedule being dominated by people who are well known or people who have gotten practice speaking in the past. While we welcome people with speaking experience and notoriety, it’s important to me that we create a space to where those who are not normally selected have a chance to speak. In an un-conference format, anyone who wants to speak gets to speak.&lt;/p&gt;

&lt;p&gt;So, by going with this format, there’s less work on the people organizing the event, and there’s an opportunity for new people to be heard. I call that a win-win.&lt;/p&gt;

&lt;h3 id="why-are-you-doing-it-this-way"&gt;Why are you doing it this way?&lt;/h3&gt;

&lt;p&gt;In addition to creating the opportunity to see some good talks, I wanted to create a space for other kinds of sessions, particularly ones that require some level of participation or discussion. With so many people working from home because of COVID-19, there are many who are craving more human interaction. I want to have the conference be a space for that. So don’t be surprised to see someone pitch a session that is simply titled something like “Let’s chat about the unique challenges of refactoring PHP”, and when you get in the room there are no slides, just someone who wants to facilitate a conversation.&lt;/p&gt;

&lt;h3 id="what-do-i-need-to-prepare-to-organize-a-session"&gt;What do I need to prepare to organize a session?&lt;/h3&gt;

&lt;p&gt;This depends on the kind of session that you want to run. On the simplest end, you can just prepare a topic or idea that you’d like to explore. That would be perfect for a purely discussion format. On the more complicated end, you can craft a slide deck and presentation or walk through a live coding demo. Those might work well if you plan on doing most or all of the talking during the session. I predict that many sessions are going to mix some elements of each of these approaches.&lt;/p&gt;

&lt;h3 id="is-that-the-same-thing-as-an-open-space"&gt;Is that the same thing as an Open Space?&lt;/h3&gt;

&lt;p&gt;I didn’t call MenderCon an Open Space, because I’m nervous about how closely we’re following the typical rules for an event that bears that description. There is a vibrant community that’s really passionate about Open Space events, and the people in that community take pride in making sure that Open Space events are done right. There were a few decisions that I made about the schedule that I felt would make it not fit the full spirit of an Open Space event, specifically, kicking the event off with a keynote and having dedicated networking time. If we were to follow the Open Space format strictly, then the keynote and networking time would be sessions like any others.&lt;/p&gt;

&lt;h3 id="what-do-i-do-if-i-want-to-speak-is-there-a-cfp"&gt;What do I do if I want to speak? Is there a CFP?&lt;/h3&gt;

&lt;p&gt;There is no CFP. If you want to speak, make sure you come to the “Pitch Session”. At the “Pitch Session” we’ll invite anyone who wants to organize a session up onto the virtual stage. There, they’ll briefly announce their session title along with a short description and the time that the session’s scheduled to happen.&lt;/p&gt;

&lt;h3 id="what-do-i-do-if-im-not-sure-which-session-to-attend"&gt;What do I do if I’m not sure which session to attend?&lt;/h3&gt;

&lt;p&gt;During each of the session rounds, there are going to be several different sessions going on at a time, and it may be difficult to decide which session is the best one for you. The Open Space community employs the “Rule of Two Feet” to specify that you can leave a session at any time and join a session at any time. If you feel you’re in the wrong session, then switch to a different one. Don’t feel obligated to stay in a session for the full time just because you were there when it started. And similarly, don’t be afraid to join a session after it’s started.&lt;/p&gt;

&lt;h3 id="is-there-a-website"&gt;Is there a website?&lt;/h3&gt;

&lt;p&gt;Not yet. :) We’ve purchased &lt;a href="http://mendercon.com" rel="noopener noreferrer"&gt;&lt;code class="highlighter-rouge"&gt;mendercon.com&lt;/code&gt;&lt;/a&gt;, but we haven’t published anything there just yet. Once it does, most if not all of the Q&amp;amp;A here will also be published there.&lt;/p&gt;

&lt;h3 id="is-there-a-code-of-conduct"&gt;Is there a code of conduct?&lt;/h3&gt;

&lt;p&gt;Yes! This event will governed by a code of conduct based on the &lt;a href="https://www.contributor-covenant.org/version/2/0/code_of_conduct/" rel="noopener noreferrer"&gt;Contributor Covenant, version 2.0&lt;/a&gt; (&lt;em&gt;shout out to Legacy Code Rocks podcast guest &lt;a href="https://where.coraline.codes/" rel="noopener noreferrer"&gt;Coraline Ada Ehmke&lt;/a&gt; for the awesome work on this resource&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;The finalized code of conduct will be available from website once we have it published. The only difference between the reference version will be the instructs for reporting behavior that violates the code of conduct.&lt;/p&gt;

&lt;h3 id="will-my-session-be-recorded"&gt;Will my session be recorded?&lt;/h3&gt;

&lt;p&gt;With the platform that we’re using, this is something that is decided when the session is created. If the session’s organizer would like it to be recorded, then we leave that decision up to them. We can imagine it being useful to have conversations that are not being recorded. I plan on recording the keynote and the pitch session.&lt;/p&gt;

&lt;h3 id="what-platform-are-you-using-why"&gt;What platform are you using? Why?&lt;/h3&gt;

&lt;p&gt;I was originally going to use a combination of Zoom and Trello. I was really nervous about the logistics of doing so, because I wanted for it to be very easy for people to create sessions, attend sessions, and then move from one session to another if they didn’t like the one they found themselves in. But I was determined to make it work.&lt;/p&gt;

&lt;p&gt;Then I learned about &lt;a href="https://hopin.to" rel="noopener noreferrer"&gt;Hopin&lt;/a&gt;, and I felt like it was built for exactly the kind of event that I wanted to run. There were even features that I would have had a very difficult time replicating by just using Zoom and Trello, such as virtual vendor booths and randomized 1-on-1 networking sessions.&lt;/p&gt;

&lt;h3 id="how-can-i-help"&gt;How can I help?&lt;/h3&gt;

&lt;p&gt;I’ve had a lot of people reach out and ask how they can help. I could use some help standing up a super simple website (see above), and I’d like to have people around on the day of the event who can help with any logistical challenges that may arise. We’ll create a dedicated channel in the &lt;a href="http://slack.legacycode.rocks" rel="noopener noreferrer"&gt;Legacy Code Rocks slack team&lt;/a&gt; to coordinate those efforts. I’d also appreciate support promoting the event. I know there are many fantastic menders out there who would have a good time attending MenderCon.&lt;/p&gt;

&lt;h3 id="anything-else"&gt;Anything else?&lt;/h3&gt;

&lt;p&gt;I’ve tried to answer all of the questions that I’ve gotten so far, but I’m sure there’s going to be more. If I missed something please ask in the comments below.&lt;/p&gt;

&lt;p&gt;Note: this content originally appeared on the &lt;a href="https://corgibytes.com/blog/2020/04/20/announcing-mendercon-2020/" rel="noopener noreferrer"&gt;Corgibytes blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>virtualconference</category>
      <category>legacycode</category>
      <category>techdebt</category>
    </item>
    <item>
      <title>The Tightrope Walker: A Metaphor</title>
      <dc:creator>M. Scott Ford</dc:creator>
      <pubDate>Wed, 24 Jul 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/corgibytes/the-tightrope-walker-a-metaphor-2abi</link>
      <guid>https://dev.to/corgibytes/the-tightrope-walker-a-metaphor-2abi</guid>
      <description>&lt;p&gt;&lt;em&gt;“How did it get this bad?! How could anyone on my team have thought this was okay?”-Anonymized Client&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Over the years, at Corgibytes, we’ve seen a bunch of projects in different states of disrepair. We approach each one of these projects with the assumption that every person who touched it did their best at the time with their given constraints. This is the embodiment of our first &lt;a href="http://corgibytes.com/about/"&gt;core value&lt;/a&gt; “Act With Empathy.”&lt;/p&gt;

&lt;p&gt;Assuming the best intentions is something that comes naturally for us but it’s not always easy for our clients to do the same. After working with us for a little bit, many of them are only just beginning to understand the rough state that their project is in. This often comes as a shock, especially to the less technical people who are involved with the project.&lt;/p&gt;

&lt;p&gt;On a call a few months ago, a client was in despair, trying to understand how any reasonable team could have made the series of decisions that got their project to its current state. For that project, there was virtually no documentation: nothing to describe how to set up a development environment; not a single passing test; and commit history comprised of epically large sets of changes with very terse change descriptions. The client was extremely frustrated and expressed dismay while wondering aloud how the project had gotten so bad.&lt;/p&gt;

&lt;p&gt;We often &lt;a href="https://corgibytes.com/blog/2017/03/14/point-inspection-metaphor/"&gt;use metaphors&lt;/a&gt; to help people, especially those who don’t code very often, understand the context of a given situation. Metaphors can be a valuable tool for communicating abstract concepts. In this situation, and in others since, the metaphor of a tightrope walker has helped explain the complex nature of risk. Here’s how it goes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nau1hMFC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://corgibytes.com/images/blog/Tightrope/walking-on-a-tight-rope.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nau1hMFC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://corgibytes.com/images/blog/Tightrope/walking-on-a-tight-rope.jpg" alt="Image of Tightrope Walker"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine someone learning to walk a tightrope for the first time. The rope is kept low to the ground. This significantly reduces the risk of falling. The person on the rope simply puts a foot on the ground to regain their balance and keeps moving along the rope. They keep going back and forth and, eventually, they don’t need to put their foot down anymore. So, they feel more comfortable with the idea of raising the rope higher and higher. They know this rope really well by now. They can travel back and forth very quickly, and the few times that they do start to fall, they are able to catch themselves very quickly. Then one day someone who hasn’t watched this progression shows up and exclaims, “Where is your safety net!? You’re going to get yourself killed!”&lt;/p&gt;

&lt;p&gt;I think this is similar to what happens to new teams that build a project from scratch. Early on in the project, the most pressing thing on the team’s collective mind is to ship the next release, which, in the context of the metaphor, can be thought of as getting to the other side of the tightrope. It’s okay if the team stumbles along the way. The project is very young and the risks are very low. They are able to recover quickly, learn from each mistake and keep going. They keep pushing out releases all the while amassing a larger system with more users, more features, more revenue, and more risk.&lt;/p&gt;

&lt;p&gt;The team has been working without any safety nets. No project documentation to describe how to set up a development environment. No description of how to deploy the application to production. No automated test suite. No formal manual test plan.&lt;/p&gt;

&lt;p&gt;Over time, someone on the team may have asked, “Why is there no safety net?” Perhaps it was the newest team member wondering why it was so hard to get started on the project. Or maybe it was one of the more junior team members who discovered a blog post about Test Driven Development. Or, maybe it was a tech lead who keeps hearing about DevOps from friends on other projects.&lt;/p&gt;

&lt;p&gt;Regardless of who asks the question, the answer is always the same; “We don’t have time to stop and build a safety net. We have to hurry up and get to the other side.” The team is feeling so much pressure to get their next release out the door, they feel they don’t have the time to slow down and build some safety into their process.&lt;/p&gt;

&lt;p&gt;I find that less technical team members rarely understand why the team wants to slow down for a little bit. They don’t effectively understand the risks that the team is trying to address. So, they pressure the team to just go back to doing things the way they were doing them. My hope is that this metaphor can help those who are trying to avert disaster while also helping explain how reasonable team members could work for so long with a net to catch their inevitable fall.&lt;/p&gt;

&lt;p&gt;Do you have any similar metaphors that help you explain this situation? Have you heard anyone else use a good one? Please share them in the comments and let’s keep the conversation going.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(This article originally appeared on the &lt;a href="https://corgibytes.com/blog/"&gt;Corgibytes blog&lt;/a&gt;)&lt;/em&gt;&lt;br&gt;
&lt;em&gt;(Header photo credit: ©zhukovvvlad – stock.adobe.com)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>metaphor</category>
      <category>devtips</category>
      <category>teamcommunication</category>
    </item>
    <item>
      <title>Nevertheless, Andrea Goulet Coded </title>
      <dc:creator>Andrea Goulet</dc:creator>
      <pubDate>Tue, 07 Mar 2017 19:46:55 +0000</pubDate>
      <link>https://dev.to/corgibytes/nevertheless-andrea-goulet-coded</link>
      <guid>https://dev.to/corgibytes/nevertheless-andrea-goulet-coded</guid>
      <description>

&lt;h2&gt;
  
  
  I began coding because...
&lt;/h2&gt;

&lt;p&gt;A good friend from high school started a software business and we reconnected at our class reunion. Scott had solved some interesting engineering problems but never made a dime from them. He asked if I'd come on board to be his CEO to help him build the business –Â thus, &lt;a href="http://corgibytes.com"&gt;Corgibytes&lt;/a&gt; was born. &lt;/p&gt;

&lt;p&gt;Scott noticed the way that I naturally solved problems. I would say things like "I'm not lazy, I'm efficient!" all the time when I was writing my marketing materials. Scott kept encouraging me to learn how to code because he thought I had some natural propensities to it, but I kept calling myself "non-technical" because I felt intimidated by the command line. It felt safe to stay in my self-created box. &lt;/p&gt;

&lt;p&gt;It wasn't until I heard Scott on a podcast after we'd run the business together for five years that my ideas were challenged. At this point, I'd coded our website by myself and was learning ruby and JavaScript. During the interview he called me "non-technical" and I got really frustrated. What did I have to do to prove that I was good enough? Scott, in his calm and Yoda-esque way, took a deep breath and said, "When you start calling yourself technical, I will too." That's when my coding journey really began, and I dove in with gusto to figure out what was getting in my way. &lt;/p&gt;

&lt;p&gt;It's been a long journey to feel comfortable calling myself technical. I even got inked up and have a JavaScript function tattooed on my wrist as a daily reminder that I can be whatever I want. &lt;/p&gt;

&lt;p&gt;For me, learning to code has taught me more about myself and has helped me feel challenged and empowered. I love learning and I'm so grateful to be surrounded by people who constantly challenge me to be my best. &lt;/p&gt;

&lt;h2&gt;
  
  
  I'm currently hacking on...
&lt;/h2&gt;

&lt;p&gt;My main job is making Corgibytes an amazing place to work. I love finding the right staff and the right clients and watching the magic happen. We're growing and my biggest focus right now is to make sure we always hold true to our five core values: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Act With Empathy &lt;/li&gt;
&lt;li&gt;Adopt a Growth Mindset &lt;/li&gt;
&lt;li&gt;Calm the Chaos&lt;/li&gt;
&lt;li&gt;Communication is Just As Important as Code&lt;/li&gt;
&lt;li&gt;Craftsmanship in Context &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm speaking at a bunch of conferences in the next few months, such as &lt;a href="https://2017.phillyemergingtech.com/"&gt;Emerging Technology for the Enterprise&lt;/a&gt;, &lt;a href="https://www.agilealliance.org/agile-alliance-technical-conference-2017/"&gt;The Agile Alliance Technical Conference&lt;/a&gt;, and &lt;a href="https://www.xp2017.org/"&gt;XP2017&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I launched &lt;a href="http://legacycode.rocks"&gt;Legacy Code Rocks&lt;/a&gt; about a year ago for folks who enjoy maintaining and modernizing software. There are about 250 people in our &lt;a href="http://slack.legacycode.rocks"&gt;Slack channel&lt;/a&gt; and I've been really having fun interviewing people for our &lt;a href="http://www.stitcher.com/podcast/corgibytes-2/legacy-code-rocks"&gt;podcast&lt;/a&gt;. As an extrovert, the podcast has been one of my favorite projects because I get to connect with new people all the time!    &lt;/p&gt;

&lt;p&gt;I have an open source project I started in October called &lt;a href="http://callmyreps.org"&gt;CallMyReps&lt;/a&gt;. The goal was to make it easier to connect with elected officials. But it's lost some traction now that some similar products have come out. &lt;/p&gt;

&lt;p&gt;I have another startup called &lt;a href="http://nagless.com"&gt;NagLess&lt;/a&gt; that makes it easy to collect timesheets so no one is the office nag. And another one that pairs people who LOVE making a home beautiful with folks like me who have a lot of "domestic debt". What's interesting there is that it's the same principle for software refactoring but the concepts are applied to physical things around the home. &lt;/p&gt;

&lt;p&gt;I'm even working on a book that shares my journey. It's called &lt;a href="https://becomingtechnicalbook.com/"&gt;&lt;em&gt;Becoming Technical: Build an Amazing Career in Tech Starting at Square Zero&lt;/em&gt;&lt;/a&gt; to help people like me, who don't have a traditional computer science background (and even those folks who do) become comfortable learning how to code and grow into a thought leader. &lt;/p&gt;

&lt;h2&gt;
  
  
  I'm excited about...
&lt;/h2&gt;

&lt;p&gt;The focus on diversity in tech over the past several years. When I first started attending software conferences, I was usually the only woman in the room. That's not the case today. I'm grateful to people who focus on sharing different perspectives, like Scott Hanselman and his podcast &lt;a href="http://www.hanselminutes.com/539/learning-to-love-legacy-code-with-andrea-goulet-from-corgibytes"&gt;Hanselminutes&lt;/a&gt;, Camille Ricketts over at &lt;a href="http://firstround.com/review/forget-technical-debt-heres-how-to-build-technical-wealth/"&gt;First Round Review&lt;/a&gt;, and Ben Halpern here at Dev.to. It takes an effort to make sure your community is diverse and I'm so thrilled that people are starting to see the value that diversity brings to the bottom line. While there is still a lot of work to do, I'm so grateful to all the folks who have encouraged me to keep going and share my perspective. Representation matters. If you don't see it, you can't be it. Seeing women software developers is really important for encouraging other women to get into the field. &lt;/p&gt;

&lt;h2&gt;
  
  
  My advice for other women who code is...
&lt;/h2&gt;

&lt;p&gt;Encourage your friends to stop using the words "non-technical" and be a mentor for the people who think they can't learn how to code. Try new things. Apply for jobs even if you don't meet all the criteria. Submit a talk to a conference and see what happens. As women, we're often in our own way because we don't try. If you put yourself out there, you may just be pleasantly surprised. &lt;/p&gt;


</description>
      <category>shecoded</category>
      <category>andreagoulet</category>
      <category>corgibytes</category>
      <category>diversity</category>
    </item>
    <item>
      <title>On Getting Old(er) in Tech</title>
      <dc:creator>Don Denoncourt</dc:creator>
      <pubDate>Tue, 10 Jan 2017 22:26:12 +0000</pubDate>
      <link>https://dev.to/corgibytes/on-getting-older-in-tech</link>
      <guid>https://dev.to/corgibytes/on-getting-older-in-tech</guid>
      <description>&lt;p&gt;After years of scoffing at talk of prejudice in the information technology field -- as a white male with good hair --, I'm starting to call prejudice against my being old(er). It's true: age discrimination is a real thing.&lt;/p&gt;

&lt;p&gt;Since 2008, the number of age discrimination complaints has grown to around &lt;a href="https://www.eeoc.gov/eeoc/statistics/enforcement/adea.cfm"&gt;25,000 a year&lt;/a&gt;. Some may argue that everywhere we turn these days, someone is complaining about something being unfair. Alright. Let's not just take complaints into account. But rather, let's look at the &lt;a href="http://www.smartinsights.com/manage-digital-transformation/average-age-tech-companys-employees-chartoftheday/"&gt;average age of IT workers&lt;/a&gt; at well-established companies. Facebook:  28. LinkedIn: 29. Google: 30.  To put that into perspective, the average age of all U.S. workers is 42. Well above the average age at these companies. Even Mark Zuckerberg once publicly said, &lt;a href="http://www.forbes.com/sites/stevenkotler/2015/02/14/is-silicon-valley-ageist-or-just-smart/#63f3a07dcdc5"&gt;at an event held at Stanford&lt;/a&gt;: “I want to stress the importance of being young and technical. Young people are just smarter.”&lt;/p&gt;

&lt;p&gt;By my clock, it's 3 till 60, so, yeah, I'm starting to get touchy about this topic. Having the insight that white -- mustache -- hair brings, I'm in a good position to debunk the younger is smarter philosophy. Allow me to point out what I've done throughout my decades of work -- yes, decades plural -- to stay employable, and share with those of you who are getting older (which is everyone), what you can do to avoid being put out to pasture once you pass 30.&lt;/p&gt;

&lt;h2&gt;
  
  
  No Country for Old Men?
&lt;/h2&gt;

&lt;p&gt;“Younger people are smarter. Balderdash. So that means companies shouldn't hire &lt;a href="https://www.sandimetz.com/"&gt;Sandi Metz&lt;/a&gt;, &lt;a href="https://twitter.com/KentBeck"&gt;Kent Beck&lt;/a&gt;, or &lt;a href="https://twitter.com/unclebobmartin"&gt;Uncle Bob Martin&lt;/a&gt;? All 30-year veterans. “They're just anomalies. Not in my experience.&lt;/p&gt;

&lt;p&gt;Six years ago, with the help of John Staler, I developed &lt;a href="http://www.kettlerusa.com/"&gt;kettlerusa.com&lt;/a&gt;. I did the Groovy and Grails front-end, and John did the RPG back-end. John is one of the best programmers I've ever worked with. Yet, John has been around for... quite a bit. Let me put John's age into perspective with a quick story: I'd regularly test checkout by buying kettlerusa.com's cheapest product: ping pong balls. I'd often forget to cancel my orders, which resulted in the delivery of numerous packets of ping pong balls to my house. Anyway, Captain Kangaroo was a popular children's TV series from 1955 to the mid-'70s. The Captain regularly had ping pong balls dropped on him as a &lt;a href="https://www.youtube.com/watch?v=N7H9jbrzrbA"&gt;prank by his moose friend&lt;/a&gt;. One day, I made a Captain Kangaroo reference to my growing stock of ping pong balls. I assumed John had watched the show. But, when I saw that he was confused about the reference, I described the sight gag to him. John responded: "Don, I grew up without a TV. It was the early â€˜50s." That's right, not only was John pre-Node.js, pre-Ruby, pre-Java, and pre-Internet, he was pre-television. Yet, you aren't going to find a better programmer -- RPG or otherwise. Not even including the self-proclaimed "smarter" 30-year-olds and younger.&lt;/p&gt;

&lt;p&gt;Yeah. OK. So he's RPG. Want an example where the programmer codes in something other than “antiquated RPG? How about HTML5, JavaScript, and C#? Then, read my blog post on &lt;a href="http://corgibytes.com/blog/makers/menders/software/2015/10/25/role-model/"&gt;Jim Stanicki&lt;/a&gt;, the guy that got me into this field back in the early â€˜80s.&lt;/p&gt;

&lt;h2&gt;
  
  
  20 Years of Experience Versus 1 Year 20 Times
&lt;/h2&gt;

&lt;p&gt;When I hear someone say they have 20 years of experience, I wonder if that's really true or if they merely had 1 year of experience 20 times. I've known too many developers that used the same techniques they learned in their first year of employment for the entire span of their career. I found this to be true in the IBM AS/400 RPG marketplace with 40- and 50-year-olds, but I've also found it to be true with 30-something Java developers. In the early 2000s, I traveled the country teaching Java seminars to RPG developers. I had expected that those RPG developers would be familiar with modern modular RPG programming techniques, but what I found was that most of them were still using old-school RPG. They had stopped enhancing their core skill set -- much less acquiring new ones. Then, between 2008 and 2010, I was training Java developers at Circuit City on Groovy and Grails. These folk were mostly late 20s and early 30s, and they were just fine sticking with good-old, write-everything-yourself, don't-bother-with-frameworks, Java.&lt;/p&gt;

&lt;p&gt;My point is certainly not that these younger developers were smarter. It's that many programmers let themselves grow stale. And the bigger problem is, after doing the same year's worth of experience ten times, many programmers forget how to learn. Not only can it be extremely hard to catch up with ten years of technology, it can be next to impossible if you've forgotten how to learn.&lt;/p&gt;

&lt;p&gt;If you plan on being in the IT field for more than 10 years, you need to be a lifelong learner. I've always been a lifelong learner. I've learned and developed with numerous programming languages, frameworks, and strategies. As a result, I've honed my learning skills. Case in point: I've been told that you can't learn a second language when you're in your 50s. I'm here to tell you: that is false. I started teaching myself Italian when I was 52. Now, I read and listen to novels written or spoken in Italian on a daily basis, and I'm way past “conversational Italian. And so, for me, learning another programming language or framework is a piece of cake.&lt;/p&gt;

&lt;h2&gt;
  
  
  Only as Good as Your Last Two Years of Accomplishments
&lt;/h2&gt;

&lt;p&gt;Kent Beck has suggested that, with consistent use of pair programming, the capabilities of programmers don't differ much after two years of experience. Understand that this is in an environment where techniques and skills are seamlessly shared. An environment where the secrets of veterans become common knowledge. My take-away, when I first heard this decades ago, was 1) pair and otherwise &lt;a href="http://corgibytes.com/blog/2016/08/30/quest-for-mediocrity/"&gt;compare myself to other developers&lt;/a&gt; as often as possible,  and 2) don't think that my decades of experience guarantees marketability or warrants higher salary.&lt;/p&gt;

&lt;p&gt;I often say that I'm only as good as what I've accomplished in the last two years. I could tell you about all my accomplishments over three decades, such as replacing the use of a System/3 punch card system with the AS/400, writing a Cobol debugger, or…. Ah, I'm boring you. What you do care about are things I did in the last two years. Things like: learning and developing with ElasticSearch, configuring multiple applications on AWS OpsWorks, setting up Docker for multiple client applications, converting Rails 2.x applications to Rails 4.2, upgrading Ruby 1.9 to 2.2, and making more effective use of Git and, more specifically, GitHub.&lt;/p&gt;

&lt;p&gt;Forget my age. I'd be willing to bet that my list of accomplishments in the last two years rivals any 20-to-30-year-old's. The perennial question then is: what am I going to say are my accomplishments two years from now?&lt;/p&gt;

&lt;h2&gt;
  
  
  How Developers Can Make Those Two Years Count
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Learn, adapt, and learn some more
&lt;/h3&gt;

&lt;p&gt;Treat this year as if it were your first year as a developer and assimilate everything you can. Reclaim the energy you had in your first year of coding. Regain the drive you had to prove to yourself and to your employers that you were “all that for this IT field. Resume reading about tech, playing with new techniques, and persuading others to teach you. Reacquire the excitement of collaborating on newfound knowledge with other developers. Be a lifelong learner and investigate all forms of learning, including:&lt;/p&gt;

&lt;h4&gt;
  
  
  Podcasts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;I like &lt;a href="http://www.greaterthancode.com"&gt;Greater Than Code&lt;/a&gt; and &lt;a href="http://bikeshed.fm/"&gt;The Bike Shed&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Webcasts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Ruby coders continue to love &lt;a href="http://railscasts.com/"&gt;RailsCasts&lt;/a&gt; and, I've lately been enjoying &lt;a href="https://www.rubytapas.com/"&gt;Ruby Tapas&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Magazines and newsletters
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;I subscribe to: &lt;a href="https://www.infoq.com/"&gt;InfoQ&lt;/a&gt;, &lt;a href="http://rubyweekly.com/"&gt;Ruby Weekly&lt;/a&gt;, &lt;a href="https://dzone.com/"&gt;DZone Daily Digest&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I also subscribe to &lt;a href="http://www.thoughtworks.com/radar"&gt;ThoughtWorks Radar&lt;/a&gt; to stay on top of what technologies are hot.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Online interactive courses
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;I was a Rails instructor for &lt;a href="https://careerfoundry.com"&gt;CareerFoundry&lt;/a&gt;, but there are hundreds of options available.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Conferences and seminars
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Try to get to one conference a year. Understand that you often learn more in conference hallways than you do in the sessions.&lt;/li&gt;
&lt;li&gt;If you can't get to conferences, take advantage of the fact that many sessions are available online. I recommend &lt;a href="http://confreaks.tv/conferences"&gt;confreaks.tv/conferences&lt;/a&gt; as it lists sessions from dozens of conferences.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Blogs
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Follow a few quality blogs -- like the &lt;a href="http://corgibytes.com/blog/"&gt;Corgibytes blog&lt;/a&gt; and &lt;a href="http://robots.thoughtbot.com"&gt;Giant Robots Smashing into Other Giant Robots&lt;/a&gt; -- where you're notified of new posts.&lt;/li&gt;
&lt;li&gt;Have your own blog and post regularly. Everyone comes up with solutions to problems or has an opinion that others would benefit from. Plus, writing a blog post solidifies your knowledge.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also take the time to discover and leverage what kind of learner you are. Do you learn best from books (that's me) or do you need a classroom environment? Are you an audio learner? Whatever your learning style, try to learn something new every day.&lt;/p&gt;

&lt;h3&gt;
  
  
  No work is an opportunity to learn
&lt;/h3&gt;

&lt;p&gt;Being between jobs is no excuse for not learning new technologies. You don't have to be employed to get experience. Do your own internet startup. Platform As A Service (PAAS) hosts, like Heroku and AWS, can be free or almost free. Come up with some goofy idea and flesh it out. Put it on GitHub as a public repository so others will see it. Do the whole cycle from backend database and maybe some NoSQL and a simple front-end. Later move that front-end to a single-page app like Ember or React or Angular. Add checkout with credit card processing.&lt;/p&gt;

&lt;p&gt;Here's a bad idea for a startup, but one that would give you loads of real-world experience: Virtual Lemonade. Create a site where someone can use their phone's current location to see what lemonade stands are available. That means you'll need Global Information System (GIS) enablement and a database of stands. You'll need server-side code and then client-side. And then, you'll need to provide the ability for kids to register their stand with your service. Maybe give them notifications of a traveller looking for a stand so they can say they are open. You may not become the next Zuckerberg, but you certainly will pick up a full gamut of marketable skills.&lt;/p&gt;

&lt;h3&gt;
  
  
  Be and look fit, but don't worry about looking younger
&lt;/h3&gt;

&lt;p&gt;I don't think, as some career counselors recommend, that you should try to look younger with hair dye or plastic surgery. What you should do is exude energy. To remain relevant in an industry that seems fixated on youth, it's crucial to be spirited. And an overweight 50-something wheezing smoker does not suggest vitality.&lt;/p&gt;

&lt;p&gt;A year or so ago, I was attending a two-week training session with about a dozen 20- or 30-something developers. The training was on the 22nd floor and, every day after we came back from group lunches, I'd always take the stairs. The first day or two, one or two of the kids would join me, but I got no repeats. It's pretty hard to be considered a has-been when they can't keep up with you.&lt;/p&gt;

&lt;p&gt;Don't go overboard just to prove a point. Be yourself. Only, your best self. Fitness can be as simple as a daily brisk walk. Maybe stuff in your earbuds and listen to a tech podcast on that walk. I watch webcasts while on the crosstrainer at the YMCA, and I listen to podcasts while unicycling. I prefer lunch workouts because it clears my head in the middle of the day, and I'm refreshed when I get back at it in the afternoon.&lt;/p&gt;

&lt;p&gt;I don't believe you should go to extremes to look younger. I could look younger simply by shaving my white mustache off (the hair on my head is full with only a few flecks of grey). But I earned those white hairs and wrinkles; they're badges of experience. I once had someone say to me: “The eighties called, they want their mustache back. “Well, I quipped, “This mustache is from the eighties, so I'm keeping it.”&lt;/p&gt;

&lt;h3&gt;
  
  
  Be interesting
&lt;/h3&gt;

&lt;p&gt;I don't care what age you are, if you're a couch potato, I guarantee that you will elicit boredom in an interview. Be interesting... to yourself. Everyone benefits from hobbies. It doesn't matter if others think your hobby or passion is odd or a bit off. For example: I keep bees and ride a unicycle. I also know civil war reenactors -- which you'd have to pay me to do --, but I find these people fascinating. I'm sure, if you don't already have a hobby, you have interests that you just haven't turned into hobbies. Having a hobby is essentially a fun form of lifelong learning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Be upfront about your age
&lt;/h3&gt;

&lt;p&gt;I feel that you should provide clear indication to potential employers what your general age is so you can weed out age-discriminatory employers. Do you want to work in an environment where they look at you as dead weight or one that values your energy and experience? Here are the first two sentences from my cover letter to Corgibytes: “Your team is looking for someone with â€˜7+ years software development experience' and a â€˜Polyglot programmer with skills in 5+ programming languages and 2+ frameworks.' How about 7+ years of C/C++, 7+ years of Java, 2+ years of PHP, and then 3+ years of Ruby (not to mention 7+ years of RPG and Cobol, otherwise, you could do the math and guess my age). So I gave a tongue-in-cheek account of my age in the first paragraph.&lt;/p&gt;

&lt;h3&gt;
  
  
  Take a cut in salary for new opportunities
&lt;/h3&gt;

&lt;p&gt;I have taken big cuts in salary three or four times in my career. I'm talking 10-20 thousand dollars a year. And not because I was out of work. I left existing jobs because I did not see myself growing technically in those positions. I've also turned down big salary jobs because I felt they'd stifle my technical growth. Some of my job changes ended up, arguably, being bad choices as they ended up being dead ends, but I make sure that I always walk away from a project with accumulated and marketable knowledge.&lt;/p&gt;

&lt;p&gt;I've seen too many people lock themselves into technologies (like Lotus Notes and Domino) and find themselves unmarketable after spending 10 years in that industry. Even if you have a high-paying salary, don't let the tech world pass you by. Be sure to be up on the latest technologies. And, if you can't do that at your current position, maybe it's time to move on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Be Forever Young
&lt;/h2&gt;

&lt;p&gt;As I mentioned earlier, yes, age discrimination is here and real. Our bodies get old and some -- like Zuckerberg -- will use that against us. But the biggest mistake would be to compound that by letting our minds and spirit get old as well. That is where we can stay "young."&lt;/p&gt;

&lt;p&gt;Bob Dylan said it best:&lt;/p&gt;

&lt;p&gt;"&lt;em&gt;May you build a ladder to the stars&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;And climb on every rung&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;May you stay forever young&lt;/em&gt;"  &lt;/p&gt;

&lt;p&gt;"&lt;em&gt;May you grow up to be righteous&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;May you grow up to be true&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;May you always know the truth&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;And see the lights surrounding you&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;May you always be courageous&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Stand upright and be strong&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;May you stay forever young&lt;/em&gt;"  &lt;/p&gt;

&lt;p&gt;"&lt;em&gt;Forever young, forever young&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;May you stay forever young&lt;/em&gt;"  &lt;/p&gt;

&lt;p&gt;Note that when Bob Dylan released his 33rd album, &lt;em&gt;Together Through Life&lt;/em&gt; (which climbed to number one in Britain), he was &lt;strong&gt;68&lt;/strong&gt; years old.&lt;/p&gt;

</description>
      <category>developers</category>
      <category>careeradvice</category>
      <category>skills</category>
    </item>
    <item>
      <title>Developer Differences: Makers vs Menders</title>
      <dc:creator>Andrea Goulet</dc:creator>
      <pubDate>Fri, 30 Dec 2016 21:45:45 +0000</pubDate>
      <link>https://dev.to/corgibytes/developer-differences-makers-vs-menders</link>
      <guid>https://dev.to/corgibytes/developer-differences-makers-vs-menders</guid>
      <description>&lt;p&gt;When you think of a developer what comes to mind? A brogrammer living in San Francisco working 23 hours a day on the next Facebook? If so, you wouldn't be alone. Like so many industries, software development is rife with stereotypes. And one that is particularly pervasive is the idea that all developers, if given the chance, would opt for a complete rewrite of an application.&lt;/p&gt;

&lt;p&gt;While it's true that there are many software developers who do enjoy starting with a clean slate, there is also a group who loves working on making existing applications better. Rather than starting from scratch and building an 80% solution, these developers are ideal for taking over a project once it's become stable, and nurturing it for a long time. Neither developer is better. Both are needed in the software world. You just need to understand when to use each one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Makers Enjoy Initial Development &amp;amp; MVPs
&lt;/h2&gt;

&lt;p&gt;To demonstrate how these developers are different, let's look at the typical product lifecycle. When a project begins, there is a burst of development that must occur for a project to get off the ground. For developers that identify as "makers", this is an ideal state. They love a blank canvas. So much so, that these types of projects, are often referred to as Greenfield projects. For developers who enjoy testing the viability of an idea, working on projects like these can feel like a little slice of heaven. Anything seems possible. The sky is blue, dotted with white puffy clouds, and the grass, in their mind, is always greener.&lt;/p&gt;

&lt;p&gt;Once the project has the desired feature set, it's time to introduce it to market. Often this is done as a Minimum Viable Product (MVP). The app is still small, and the mental model is generally not too complex. At this point, the market will decide what happens next. Either the app will gain traction, and grow its user base, or it will fade into obscurity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Menders Prefer Working on Apps that Are Stable and Growing
&lt;/h2&gt;

&lt;p&gt;At this point, the tasks for the developer shift. Instead of thinking big and implementing architecture, they'll need to focus on things like security, scalability, performance, bug fixes, and feature enhancements. The work becomes more detailed than it was at the beginning of a project and to the frustration of many a product owner, the developer's interest begins to wane. To makers, the fine details and craftsmanship required at this phase aren't as fun.&lt;/p&gt;

&lt;p&gt;But there is a group of developers whose talents and interests are well suited for these types of tasks. They haven't had a name until now, but we like to call them "menders". Menders love refactoring, or editing code to enhance clarity. Bug fixes genuinely excite them and they get a little giddy about testing. These are all qualities that may not be as useful at the beginning of a project, but as your app grows and becomes more complex, these are definitely traits that you'll want on your team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Makers : New Construction :: Menders : Remodeling
&lt;/h2&gt;

&lt;p&gt;Another way to think of the maker mender difference is to think about the difference between new construction and remodeling. With new construction, you're often starting with a cleared piece of land, similar to that blank text editor that makers like so much. Mending, on the other hand, is more like the show "This Old House". There's often a very good reason that the existing structure should stay, but to update it requires digging in, knocking down walls, and sometimes dealing with the unexpected things you find.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation Tactics for Makers and Menders
&lt;/h2&gt;

&lt;p&gt;Like with any mix of personalities, diversity is typically a good thing. Most likely, you'll want to have a mix of makers and menders on your team. The key is knowing how to motivate them so you'll get the best performance. Makers are like rabbits –Â they burst with speed for a short period of time. Menders are more like the tortoise. In their world, slow and steady improvements wins the race.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let Makers Experiment and Give Them a Deadline
&lt;/h3&gt;

&lt;p&gt;Nothing bores a maker more than repetition. So keep your makers engaged by tasking them with experiments. Allow them freedom to look into the future and employ design thinking. Need a prototype to prove a concept? Call on a maker. They'll enjoy standing something up quickly. Makers are also likely to thrive at hackathons where there's high energy for a short period of time. And if you're in a crunch and on a deadline, makers will step up to the challenge as they are often motivated by time pressure. Crossing over a big deadline gives them a sense of accomplishment, so sprints are a good project management tool for these folks. Just don't expect them to stay put on one project for too long. Makers love exploring new ideas and will get bored easily if their project is too tedious.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Give Menders a Series of Small Wins Throughout the Day
&lt;/h3&gt;

&lt;p&gt;The blue-sky thinking and deadline driven project management that motivates a maker is often stress inducing for a mender. What they may lack in excitability, they make up for in consistency. A mender is an ideal person to tackle technical debt, fix bugs, fine tune features, create a style guide, and monitor support tickets. Unlike their maker friends, menders do best when their work is steady and relatively predictable. Have a problem that no one has been able to solve yet? Share it with a mender. They'll enjoy the challenge of digging in really deep and figuring out what's going on. Just be careful not to micromanage your menders, as that will annoy them to no end. Instead, develop a long backlog of tasks and give your menders autonomy as to what gets done and when. If there is a priority or deadline, communicate it well in advance to allow for unkown unknowns to surface.&lt;/p&gt;

&lt;p&gt;So how about you? Are you a maker? Mender? Something in between? What motivates you to develop your best software?&lt;/p&gt;

</description>
      <category>developers</category>
      <category>menders</category>
      <category>makers</category>
    </item>
    <item>
      <title>Embracing the Red Bar: Safely Refactoring Tests</title>
      <dc:creator>M. Scott Ford</dc:creator>
      <pubDate>Mon, 05 Dec 2016 22:18:56 +0000</pubDate>
      <link>https://dev.to/corgibytes/embracing-the-red-bar-safely-refactoring-tests</link>
      <guid>https://dev.to/corgibytes/embracing-the-red-bar-safely-refactoring-tests</guid>
      <description>&lt;p&gt;Do you ever refactor your test code? If not, I hope you consider making this part of your normal practice. Test code is still code and should adhere to the same high standards as the code that's running directly in production.&lt;/p&gt;

&lt;p&gt;As important as it is, refactoring your test code is actually a little risky. It's very likely that you could turn a perfectly valid test into one that always passes, regardless of whether or not the code that it covers is correct. Let's explore a technique for protecting against that possibility.&lt;/p&gt;

&lt;p&gt;But before I dive into the nitty-gritty, let me tell you where I discovered this technique and why I feel it should be part of everyone's refactoring practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backstory
&lt;/h2&gt;

&lt;p&gt;I first read about "Refactoring Against the Red Bar" years ago while subscribed to a blog that was published by Michael Feathers. The article is &lt;a href="http://butunclebob.com/ArticleS.MichaelFeathers.RefactoringAgainstTheRedBar"&gt;still available&lt;/a&gt;, which is good, because it turns out that Michael Feathers isn't the originator of this idea either. He discovered it while talking with Elizabeth Keogh at the XP2005 conference, and his article points his readers to an article that &lt;a href="http://sirenian.livejournal.com/21808.html"&gt;she wrote about the technique&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm often guilty of assuming that because I've read something once, that everyone else already knows about it. And that happens with this technique as well. I was at the first &lt;a href="http://www.mobprogrammingconference.com/"&gt;Mob Programming conference held by Agile New England in Cambridge, MA&lt;/a&gt;, and I was participating in a mob where one of the members suggested refactoring the tests. I mentioned the risk of invalidating the tests by doing that and that we should refactor against the red bar to defend against it. The initial response was a mixture of blank stares and confused looks. Once I described the technique and demonstrated its merits by navigating the mob, people were very excited, and several asked why they'd never encountered the technique before. I mentioned its origin, and I was encouraged by the rest of the mob to promote the idea further.&lt;/p&gt;

&lt;p&gt;That lead to both this article and a talk that I'll be presenting at &lt;a href="http://agiledc.org/2016-schedule/"&gt;Agile DC 2016&lt;/a&gt;. And, that's also why I'm rehashing someone else's idea: it's a really good one, and more people need to hear about it. A big thanks to Elizabeth and Michael for their earlier work on this technique.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes TDD Work So Well?
&lt;/h2&gt;

&lt;p&gt;The short answer is that when you strictly follow the &lt;a href="http://martinfowler.com/bliki/TestDrivenDevelopment.html"&gt;TDD steps&lt;/a&gt;, you're guaranteed that your tests will fail if the implementation breaks. And that's the bedrock that makes it so safe to continue refactoring your code.&lt;/p&gt;

&lt;p&gt;In case that's not super clear:&lt;/p&gt;

&lt;p&gt;There are three simple steps to TDD which we continue to repeat until our application does everything that we want it to do.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write a failing test&lt;/li&gt;
&lt;li&gt;Write the &lt;em&gt;simplest production code possible&lt;/em&gt; that will make it pass&lt;/li&gt;
&lt;li&gt;Refactor production code to make the implementation clean&lt;/li&gt;
&lt;li&gt;Do we need more tests? If 'yes' then start back at 1, if 'no' then we're done&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I kind of lied about there being only 3 steps. There's an important bit that the typical TDD process description glosses over. What often gets left out is a check step that I've included above as step number four.&lt;/p&gt;

&lt;p&gt;I find that to be a very important addition to the process. If you don't know that step is coming, you sometimes try to violate the most important clause of step 2: &lt;em&gt;the simplest production code possible&lt;/em&gt;. And I think this is worth demonstrating with a simple example.&lt;/p&gt;

&lt;h3&gt;
  
  
  TDD example: &lt;code&gt;Calculator.Add()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;My favorite kata to use to demonstrate this concept is building a simple calculator using TDD and starting with the addition function. Although, I'm using &lt;code&gt;ruby&lt;/code&gt; for the code samples, please remember that this technique is not language specific. I'll intentionally avoid any &lt;code&gt;ruby&lt;/code&gt; features that might not read well for those less familiar with the language.&lt;/p&gt;

&lt;p&gt;Here's what our first failing test might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;'additon'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;specify&lt;/span&gt; &lt;span class="s1"&gt;'adding two numbers that result in 4'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&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;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, what would be the simplest way to make that test pass? How about this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reaction I often hear at this point is: "But that's not complete. It's not going to work for 2+5!" That's when I remind people about the implicit step 4 that I outlined above: &lt;em&gt;Do we need more tests?&lt;/em&gt; It sounds like the answer is a resounding yes. At least if we want this calculator to be able to do more that just claim that any two numbers result in 4 when added together.&lt;/p&gt;

&lt;p&gt;Here's what the tests might look like now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;'additon'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;specify&lt;/span&gt; &lt;span class="s1"&gt;'adding two numbers that result in 4'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&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;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;specify&lt;/span&gt; &lt;span class="s1"&gt;'adding two numbers that result in 5'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&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="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&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="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now we have a failing test which confirms the objection to the original implementation: just returning 4 isn't good enough.&lt;/p&gt;

&lt;p&gt;So what's the easiest way to make &lt;em&gt;just the new test&lt;/em&gt; pass? Well, that would be to return 5.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that will cause our new test to pass. But we've got a problem. Our previous test is now failing.&lt;/p&gt;

&lt;p&gt;So what's the easiest way to make them both pass? That would be to actually do the work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we have two tests that are working together to force our implementation to work the way we want it to. And it's by only having both tests that we're able to &lt;em&gt;safely&lt;/em&gt; refactor.&lt;/p&gt;

&lt;p&gt;That's how TDD is able to guarantee that our test suite is a complete description of our production code. But that guarantee gets invalidated as soon as we just simply refactor our test code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Is It Dangerous to Blindly Refactor Test Code?
&lt;/h2&gt;

&lt;p&gt;Strictly speaking refactoring should never result in a change in behavior. That would violate the definition of refactoring: &lt;a href="http://refactoring.com"&gt;&lt;em&gt;changing an implementation without changing its behavior&lt;/em&gt;&lt;/a&gt;. But mistakes sometimes happen, especially if you're working without an automated refactoring tool and you're applying the refactoring by hand. And keep in mind that a bug in your refactoring tool isn't likely, but &lt;a href="http://jbazuzicode.blogspot.com/2016/05/extract-method-introduces-bug-in-this.html"&gt;it's not impossible&lt;/a&gt;, either.&lt;/p&gt;

&lt;p&gt;Let's look at a hypothetical refactoring scenario where we attempt to remove some duplication in our test suite.&lt;/p&gt;

&lt;p&gt;We'll start with the test suite that we finished with earlier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;'additon'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;specify&lt;/span&gt; &lt;span class="s1"&gt;'adding two numbers that result in 4'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&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;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;specify&lt;/span&gt; &lt;span class="s1"&gt;'adding two numbers that result in 5'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&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="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&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="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's refactor this to remove some of the duplication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;'additon'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;left: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;right: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;result: &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;left: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;right: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;result: &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;specify&lt;/span&gt; &lt;span class="s2"&gt;"adding two numbers that result in &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:result&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:left&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:right&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we were to run that, it'll pass. But did you catch the mistake that was made during the refactoring? The assertion has been removed by accident. The code should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;'additon'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;left: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;right: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;result: &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;left: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;right: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;result: &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;specify&lt;/span&gt; &lt;span class="s2"&gt;"adding two numbers that result in &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:result&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:left&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:right&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:result&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How Do We Defend Against Breaking Our Tests When We Refactor Them?
&lt;/h2&gt;

&lt;p&gt;When we refactor our production code, it's the safety provided by our test suite that lets us safely refactor our production code. So how can we get that same safety when we need to refactor our test code? To do that, we have to break our production code in a way that will cause the tests we want to refactor to fail. If they don't fail, then we've got a problem. Either we didn't break the production code correctly, or our tests didn't work in the first place. If we can't force our tests to fail, then they're not doing us any good and that would need to be addressed before continuing any further.&lt;/p&gt;

&lt;p&gt;Once those tests fail correctly, we can refactor them. And after every tiny refactoring we do, the tests should &lt;em&gt;still fail&lt;/em&gt;. If any of those tests start to pass, then we've made a mistake in our refactoring somewhere. That's what would have happened with the mistake that was introduced in the example above.&lt;/p&gt;

&lt;p&gt;After we're done refactoring our tests, we can revert the changes we made to break our production code, and that should cause all of our refactored tests to start passing. If any of our tests still fail, then we've also made a mistake in our refactoring. But this time, instead of creating a test that always passes, we've created one that always fails.&lt;/p&gt;

&lt;p&gt;Before we walk through a couple of examples, let's simplify the workflow a little bit for review.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Break our production code to cause our test to fail&lt;/li&gt;
&lt;li&gt;Refactor our test code&lt;/li&gt;
&lt;li&gt;Ensure that our tests still fail&lt;/li&gt;
&lt;li&gt;Revert changes to production code&lt;/li&gt;
&lt;li&gt;Verify that tests once again pass&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  A red bar refactoring example
&lt;/h3&gt;

&lt;p&gt;Let's start with the example code that we created in the TDD example above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;'additon'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;specify&lt;/span&gt; &lt;span class="s1"&gt;'adding two numbers that result in 4'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&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;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;specify&lt;/span&gt; &lt;span class="s1"&gt;'adding two numbers that result in 5'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&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="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&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="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here's the production code that makes those tests pass:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Time to refactor our tests. There's a little bit of duplication in there. Here's what I see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;Calculator&lt;/code&gt; class is instantiated by every test&lt;/li&gt;
&lt;li&gt;Each test just calls &lt;code&gt;add&lt;/code&gt; with different parameters and expects a different result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's tackle just the first one while refactoring against the red bar.&lt;/p&gt;

&lt;p&gt;The first step is to force the tests we're changing to fail by intentionally breaking the production code. This should do that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We verify that by running our test suite and making sure that the tests that we want to change are failing. It's okay if more tests are failing, too. But it's super important that all of the tests that you intend to refactor are failing. If the tests that you want to refactor are not failing, then you need to keep changing your production code until they do. And if you're unable to make those tests fail, then you need to jump down to the "What if something goes wrong?" section.&lt;/p&gt;

&lt;p&gt;Now, we can safely extract the instantiation of the &lt;code&gt;Calculator&lt;/code&gt; class, which might look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;'additon'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:calculator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;specify&lt;/span&gt; &lt;span class="s1"&gt;'adding two numbers that result in 4'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&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;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;specify&lt;/span&gt; &lt;span class="s1"&gt;'adding two numbers that result in 5'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&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="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&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="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the creation logic for building a proper &lt;code&gt;Calculator&lt;/code&gt; instance has been factored out into one spot.&lt;/p&gt;

&lt;p&gt;We need to re-run our test suite to make sure that we didn't make a mistake. Remember, though, we're actually expecting the tests to fail.&lt;/p&gt;

&lt;p&gt;In this case, our tests still fail in the way we expected them to. So we can now proceed by restoring the original implementation of our production code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we run our test suite to make sure that everything is passing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What If Something Goes Wrong?
&lt;/h2&gt;

&lt;p&gt;There are a few points during the red bar refactoring process where you might encounter a surprise. I mentioned these earlier, but I'm reiterating them for easy reference.&lt;/p&gt;

&lt;h3&gt;
  
  
  I'm changing my production code, but I can't make my tests fail!
&lt;/h3&gt;

&lt;p&gt;If you encounter this issue, then you already have a test that's producing a false positive. You've got a couple of options at this point.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Delete the test and treat the production code as untested, legacy code&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A test that always passes is providing just as much value as one that's always failing. At best, reading it will give you an indication about the test authors' original intent, but it's essentially documentation that's drifted out of sync with your implementation. Deleting the test is a perfectly acceptable option in this scenario. Your test suite will be no weaker without the false positive test than it was. Now that you've discovered the false positive, it's best to go ahead and write something that covers the production code the test was intending to run.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Review change history and try to restore a working version of the test&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Take a peek at the tests history in your change control system if you have that available. If you discover that you're looking at the first version of the test that was committed, then this test has &lt;em&gt;always&lt;/em&gt; been a false positive, and you'll need to follow the previous option instead. If there is history for the test that you're working on, then attempt to revert those changes while your production code is still modified to simulate a failure. If the older version of the test fails, then you can revert your production code modifications, and see if the test passes. If so, then you've found a valid version of the test. If that version still has some refactoring that you'd like to do, then you can go ahead and start the process over again.&lt;/p&gt;

&lt;h3&gt;
  
  
  I refactored my test, and the production code is broken, but now the test is passing!
&lt;/h3&gt;

&lt;p&gt;In this scenario, you've broken your test. The easiest way to see this is to remove a critical assertion that would otherwise force the test to fail, or perhaps a subtle change has been made to the way the test setup process was running. Revert the changes that you've made to your test and try again.&lt;/p&gt;

&lt;h3&gt;
  
  
  I've successfully refactored my test, and I've reverted my changes to the production code, but now the test is still failing!
&lt;/h3&gt;

&lt;p&gt;Take a close look at the reason that the test is failing. I've seen this scenario happen most often because of an invalid type reference or syntax error. Since you're refactoring against the red bar, those things can sometimes slip into your test as you're refactoring. In this case, fixing that error should make your tests pass again, but you'll want to repeat your production code changes to double-check that you haven't accidentally introduced a false positive while trying to get the test to pass again.&lt;/p&gt;

&lt;p&gt;It's also possible that you've added an assertion that the production code can't make pass or the test setup is different than it used to be, and the logic that used to be running no longer applies. If this is the case, then you'll need to revert the changes that you've made to your test and start over.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Have We Learned?
&lt;/h2&gt;

&lt;p&gt;Following this simple technique is a great way to safely ensure that your tests suite still correctly tests your production code while you're refactoring your test code. This is a practice that I follow anytime that I modify a test, and I've been doing so successfully for several years now. It's practically second nature at this point.&lt;/p&gt;

&lt;p&gt;I'd love to hear from others who are using this technique, and I'd also enjoy hearing from people who are starting to work this technique into their practice. Are there any challenges that you're encountering? Figured anything out that others should know about? Let me know!&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>tdd</category>
      <category>techniques</category>
    </item>
    <item>
      <title>KonMari Your Code; Refactor Your Life</title>
      <dc:creator>Andrea Goulet</dc:creator>
      <pubDate>Mon, 05 Dec 2016 22:08:11 +0000</pubDate>
      <link>https://dev.to/corgibytes/konmari-your-code-refactor-your-life</link>
      <guid>https://dev.to/corgibytes/konmari-your-code-refactor-your-life</guid>
      <description>&lt;p&gt;Is your code difficult to work with? Chances are, it's time to get rid of code you don't need. That can be a scary prospect, but the rewards can be well worth the effort.&lt;/p&gt;

&lt;p&gt;Recently, I was inspired by &lt;a href="http://tidyingup.com/" rel="noopener noreferrer"&gt;KonMari&lt;/a&gt;, a technique for decluttering physical spaces, to help me visualize how to refactor codebases to make them easier to work with.&lt;/p&gt;

&lt;p&gt;Last summer, as I bounced my three-month-old daughter on my knee while visiting my in-laws, a half-joke slipped through the clutch between my brain and my mouth.&lt;/p&gt;

&lt;p&gt;“It would just be easier if we LIVED here.”&lt;/p&gt;

&lt;p&gt;And to my surprise, my mother-in-law replied, “You know that's an option, right? We would love that.   &lt;/p&gt;

&lt;p&gt;Thus began the great merging. Scott and I were both starting our careers on the speaker circuit, and the increased travel required us to lean on his parents for child care more and more. Luckily, Ann and Steve, Scott's parents, wanted to be a significant part of our children's lives and, after careful consideration, we decided to take them up on the offer.&lt;/p&gt;

&lt;p&gt;We discovered that merging two households together is significantly more effort than moving from a full house into an empty one. The biggest challenge is handling all the STUFF. We were trying to squeeze the belongings of a 1700 square-foot house into two bedrooms, one for us, and one for the kids.&lt;/p&gt;

&lt;p&gt;Around the time of the move, I stumbled on a book by Marie Kondo, &lt;a href="https://www.amazon.com/gp/product/1607747308?ref_=smi_se_mit_rcol_smi_2628204422&amp;amp;%2AVersion%2A=1&amp;amp;%2Aentries%2A=0&amp;amp;pldnCmp=rcol&amp;amp;pldnCrt=my-impact&amp;amp;pldnSite=1" rel="noopener noreferrer"&gt;The Life Changing Magic of Tidying Up&lt;/a&gt;. The advice in this book, although brief, was profound. Kondo described her method, which she called KonMari, for helping clients eliminate clutter and create physical environments that are a joy to live in. Her advice is simple: “Effective tidying involves only two essential actions: discarding and deciding where to store things. Of the two, discarding must come first.”&lt;/p&gt;

&lt;p&gt;As I went through the process of decluttering and organizing my house, I couldn't help but see the process as a metaphor to working with codebases in the digital world. One of the biggest impediments to a productive development team is a cluttered codebase, just like how clutter inhibits joy in our living spaces.&lt;/p&gt;

&lt;p&gt;To Kondo, the biggest hurdle her clients face is overcoming the psychological objections to discarding things. I find that to be true with code too. Often, I'll find myself with a “maybe I'll need this later attitude when I'm working with a piece of code. There's a battle going on in my brain. Should I delete something because it will make the codebase as a whole better? Or should I keep it because that's easier in the moment?&lt;/p&gt;

&lt;p&gt;I'll also find that I go to refactor a piece of code and that ends up leading me down a long rabbit hole that I never intended to go down. The same thing happens with my physical space, especially now that I have constraints. I'll decide that I want to organize a bin in my closet, but in order to do that properly, I have to remove the contents of pretty much the entire closet. Stuff gets strewn across the bed and in strange little piles on the floor while I'm trying to evaluate the system as a whole. What I anticipated was a ten-minute project ends up taking up an entire afternoon. This is fine when I plan for it, but when I get caught off guard by my own expectations, my initial feeling of empowerment quickly fades into feeling deflated.&lt;/p&gt;

&lt;p&gt;The key to decluttering effectively lies in getting past the psychological hurdle of deleting. This is as true with physical objects as it is with digital ones. With KonMari, this takes place in two distinct phases: purging and maintaining. In the purging phase, you look at all of your objects in phases: clothing, books, papers, etc. Each item must pass a litmus test, not as to whether it should be deleted, but whether or not it should be kept. In Kondo's words, “The best way to choose what to keep and what to throw away is to take each item in one's hand and ask: â€˜Does this spark joy?' If it does, keep it. If not, dispose of it. This is not only the simplest but also the most accurate yardstick by which to judge.”&lt;/p&gt;

&lt;p&gt;Looking at my living space systemically, while armed with a simple litmus test for each item I needed to evaluate, proved to be an incredibly powerful way to move through what I thought would be the intractable problem of merging two houses together. KonMari became a powerful metaphor for me as I approached my work at Corgibytes, too. Legacy code is often seen as difficult to work with because it's unorganized and cluttered. I found myself searching for ways to apply the KonMari philosophy to my work with modernizing codebases, too.&lt;/p&gt;

&lt;p&gt;I've found myself searching for a mantra to use as a litmus test for determining whether or not a piece of code should be kept. While I've tested out several in my mind, I have yet to find the right correlation to “does it spark joy? I find myself thinking often of usefulness: Is this helpful? Does it contribute to code quality? Does it follow S.O.L.I.D principles? But I have yet to find a question that is as emotive and profound as sparking joy. I'd be very interested in hearing what other developers use throughout the course of their work.&lt;/p&gt;

&lt;p&gt;As for systems, the most helpful one I've found is from &lt;a href="http://approvaltests.com/" rel="noopener noreferrer"&gt;Llewellyn Falco&lt;/a&gt; and &lt;a href="http://mobprogramming.org/" rel="noopener noreferrer"&gt;Woody Zuill&lt;/a&gt; with their &lt;a href="https://www.youtube.com/watch?v=aWiwDdx_rdo" rel="noopener noreferrer"&gt;Practical Refactoring&lt;/a&gt; method. To me, it has the elegance and simplicity that I enjoyed so much about KonMari. Here's a quick visualization:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdcw8nzsfg%2Fimage%2Fupload%2Fv1480976057%2Fpractical-refactoring_qlu01x.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fres.cloudinary.com%2Fdcw8nzsfg%2Fimage%2Fupload%2Fv1480976057%2Fpractical-refactoring_qlu01x.gif" alt="Practical Refactoring"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Remove Clutter
&lt;/h2&gt;

&lt;p&gt;Organizing is so much easier when you have fewer things to manage. This is true in the physical world as well as the digital. Too often, we're afraid to delete code, but it's a necessary part of maintaining a healthy codebase, just like taking out the trash is a healthy part of maintaining a clean house. In my opinion, there are simply not enough code deletion tools out there. The world could really benefit from more minds thinking about how to safely remove dead code.&lt;/p&gt;

&lt;p&gt;That being said, using one of the automated tools that do exist, such as Living Social's &lt;a href="https://techblog.livingsocial.com/blog/2013/12/17/coverband-production-ruby-code-coverage/" rel="noopener noreferrer"&gt;CoverBand&lt;/a&gt;, to help identify and remove dead code is a good first step. Additionally, as a codebase continues to change, developers should not be afraid to delete dead code as it becomes obsolete. Utilizing test-driven development, peer code reviews, and other recommended development practices can help ensure that a codebase doesn't become littered with new obsolete code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Split Long Methods
&lt;/h2&gt;

&lt;p&gt;I've talked previously about how &lt;a href="http://corgibytes.com/blog/2016/04/15/inception-layers/" rel="noopener noreferrer"&gt;inception layers&lt;/a&gt; make it difficult to context switch. When refactoring code,  I often find that I need to keep a mental model of long methods, or actions in the code, in my head to try to figure out what the heck a block of code is doing. By splitting up long methods, developers need to spend less mental energy trying to parse out the meaning of code. Refactoring long methods can be simplified using  an &lt;a href="http://corgibytes.com/blog/2016/08/09/IDE-vs-Text-Editor/" rel="noopener noreferrer"&gt;IDE&lt;/a&gt;. JetBrains' products have a particularly useful “extract method feature that helps automate this task and ensure accuracy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Split Long Methods (again)
&lt;/h2&gt;

&lt;p&gt;After taking a first pass at splitting up long methods, it makes sense to take a second pass over the newly-created methods. It's likely that some of them are still a bit unwieldy. Plan extra time for these steps. Chances are you have a lot of room for improvement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Extract Classes
&lt;/h2&gt;

&lt;p&gt;Now that we've reorganized and simplified our methods, or actions, we want to make sure that the classes, or categories, we're using still make sense. If we're using the analogy of organizing a closet, this step would be looking at all of the things we own and putting them in labeled bins of related items. The size and contents of each bin may be up for debate, but what is most important is that the bins are clearly and logically labeled. This helps us make sure that when we want to reference, or find, an object later, it will be easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Create Abstraction
&lt;/h2&gt;

&lt;p&gt;Next up, it's time to look at the codebase as a whole and examine what elements can be lifted out of the details into a broader layer to make it even easier to reference. If I were organizing my closet, I might look at all of my bins and see that I could arrange things on shelves in broader categories like craft supplies, tools, files, seasonal decorations, etc. With my closet, this helps give me specific reference points for where I can find an object. We do the same thing in code with abstract classes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Add New Features
&lt;/h2&gt;

&lt;p&gt;Yay! Our code is organized and easier to work with. This means that adding new features will be much easier. I think of this step as me actually using the contents of my closet to do a project, let's say making a quilt for my kids. There are things I'll need to pull out of the closet and things I'll need to buy. I'll use all of them together to create something useful and new. At this stage, it's useful to remember that cleaning up after yourself is a critical part of good coding practices. It's not just organizing something once and then going back to bad habits. Hopefully, every time you do a project, you're finding small ways to keep your space tidy and a joy to work with.  &lt;/p&gt;

&lt;p&gt;It's worth taking the time to review Llewellyn and Woody's in-depth &lt;a href="https://www.youtube.com/watch?v=aWiwDdx_rdo" rel="noopener noreferrer"&gt;two-hour workshop&lt;/a&gt; where they dive into the details of this method. I love this because it maps brilliantly to the philosophy of KonMari. One of my favorite quotes is when Llewellyn says, “Code excellence is more about discipline than it is about brilliance.”&lt;/p&gt;

&lt;p&gt;The key takeaway, for both physical and digital spaces is that we need to be disciplined and make deleting and organizing code a regular priority. Ignoring clutter only compounds it and makes a seemingly intractable problem even worse. Armed with a simple set of rules and making an effort is worth it. When you KonMari your code, you can transform frustration into joy.&lt;/p&gt;

</description>
      <category>softwareremodeling</category>
      <category>refactoring</category>
      <category>codebases</category>
    </item>
    <item>
      <title>Setting up a Minimal, Yet Useful JavaScript Dev Environment </title>
      <dc:creator>Kamil Ogórek</dc:creator>
      <pubDate>Mon, 21 Nov 2016 21:25:48 +0000</pubDate>
      <link>https://dev.to/corgibytes/setting-up-a-minimal-yet-useful-javascript-dev-environment</link>
      <guid>https://dev.to/corgibytes/setting-up-a-minimal-yet-useful-javascript-dev-environment</guid>
      <description>&lt;p&gt;In an era of omnipresent frameworks, libraries and tooling, it may be hard to decide what tool to use and when.&lt;/p&gt;

&lt;p&gt;I know from experience, that the first thing you do, once you decide to write a module or CLI tool, is set up an environment. Some people love it, some hate it. But no matter on which side you are, you'll most likely end up spending way too much time doing it, polishing every aspect of the setup.&lt;/p&gt;

&lt;p&gt;Sure, you could use webpack, eslint, jasmine or even TypeScript to get great compile error messages. The truth is though, most of the time, as developers, we can get by with tools that require almost no configuration. These "out-of-the-box" tools are usually perfectly acceptable, and will help us jump straight to solving the problem, while providing an almost instant feedback loop.&lt;/p&gt;

&lt;p&gt;When talking about the minimal setup, things that come to mind are testing, linting, watching changes and making sure that you won't break anything before committing changes.&lt;/p&gt;

&lt;p&gt;Here's a step-by-step to help you go from having nothing, to being productive in five minutes or less (depending on NPM's mood).&lt;/p&gt;

&lt;h2&gt;
  
  
  Init Node.js project and GIT repository
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a directory and cd into it (#protip – $_ holds argument of your last command)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;awesome-module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Initialize Node.js project with default settings&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;npm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--yes&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Create initial folders and files&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;lib&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;touch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;index.js&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;lib/meaningOfLife.js&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;test/index.test.js&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;test/meaningOfLife.test.js&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Initialize GIT repository and create initial commit&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-A&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-am&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Awesome Module, day one"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Install tools
&lt;/h2&gt;

&lt;p&gt;Here, we'll use four simple modules, each having a single purpose. &lt;a href="https://github.com/avajs/ava"&gt;Ava&lt;/a&gt; for testing, &lt;a href="https://github.com/feross/standard"&gt;Standard&lt;/a&gt; for linting, &lt;a href="https://github.com/kimmobrunfeldt/chokidar-cli"&gt;Chokidar-cli&lt;/a&gt; for file watching and &lt;a href="https://github.com/nlf/precommit-hook"&gt;Precommit-hook&lt;/a&gt; for automatically running npm scripts.&lt;/p&gt;

&lt;p&gt;Why those tools? Because they don't require any configuration and take the cognitive load from your brain. One less thing to think and worry about.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm i --save-dev ava standard chokidar-cli precommit-hook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember to create a &lt;code&gt;.gitignore&lt;/code&gt; file and add &lt;code&gt;node_modules&lt;/code&gt; to it! We don't want it in our repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up tools
&lt;/h2&gt;

&lt;p&gt;Open &lt;code&gt;package.json&lt;/code&gt; and add those scripts to your file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"scripts": {
  "test": "ava",
  "lint": "standard",
  "dev": "chokidar '**/*.js' -c 'standard &amp;amp;&amp;amp; ava'"
},
"pre-commit": ["test", "lint"],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aaaand you are done! Once you run &lt;code&gt;npm run dev&lt;/code&gt; you'll get all of your JS files linted by Standard.js and tests run by Ava. There's nothing more to it, and you can start working right away.&lt;/p&gt;

&lt;p&gt;The same goes for creating GIT commits. You won't be able to do so, unless all of your tests are green and linter is happy.&lt;/p&gt;

&lt;p&gt;Two things worth noting:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You don't have to install &lt;code&gt;standard&lt;/code&gt; or &lt;code&gt;ava&lt;/code&gt; globally, as they are run from within the &lt;code&gt;node&lt;/code&gt; context.&lt;/li&gt;
&lt;li&gt;Because we use &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; instead of &lt;code&gt;;&lt;/code&gt; here in the &lt;code&gt;dev&lt;/code&gt; script, tests won't be triggered unless you pass linter rules. It makes the feedback loop even faster.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Working with the setup
&lt;/h2&gt;

&lt;p&gt;Because the environment assumes you'll work in TDD style (and you probably should!), once you run your &lt;code&gt;dev&lt;/code&gt; script, you can create tests and they will be added to the test suite, without any need for restarting a watcher or rebuilding anything.&lt;/p&gt;

&lt;p&gt;Let's create the first test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// test/meaningOfLife.test.js
const test = require('ava')
const meaningOfLife = require('../lib/meaningOfLife')

test('Real meaning of life', (t) =&amp;gt; {
  t.is(meaningOfLife(), 42)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you save the file, you'll get instantly notified that one of your tests is failing. Let's fix it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// lib/meaningOfLife.js
module.exports = () =&amp;gt; 42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we are back to green! It's as simple as that. Let's create another module that'll multiply a numeric parameter, unit test this module and see whether it'll work nicely with our “meaning of life” (note that it's already an integration test, not unit!).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// lib/multiply.js
module.exports = (number) =&amp;gt; {
  if (typeof number !== 'number') throw new TypeError('Only numbers can be multiplied!')
  return number * 2
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// test/multiply.test.js
const test = require('ava')
const multiply = require('../lib/multiply')

test('Can multiply numbers', (t) =&amp;gt; {
  t.is(multiply(10), 20)
})

test('Throws when you try to multiply non-number value', (t) =&amp;gt; {
  t.throws(() =&amp;gt; multiply('ohai!'), 'Only numbers can be multiplied!')
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, to test it all together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// test/index.test.js
const test = require('ava')
const awesomeModule = require('../index')

test('Works nicely together', (t) =&amp;gt; {
  t.is(awesomeModule(), 84)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// index.js
const meaningOfLife = require('./lib/meaningOfLife')
const multiply = require('./lib/multiply')

module.exports = () =&amp;gt; multiply(meaningOfLife())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works! In just a few minutes, we got everything up and running.&lt;/p&gt;

&lt;p&gt;We, as developers, are often charmed by shiny new tools. We seem to forget that those things should make our work easier, faster and less error prone. The simplest solutions are more than enough, more often than we think. Instead of spending an enormous amount of time on the setup, we should spend it on writing the software itself. And following these steps will allow you to do just that.&lt;/p&gt;

&lt;p&gt;Once your project starts to grow, you may find yourself in need of something more complex. In most cases, however, it just won't happen. And those tools will suit your needs quite well for a long, long time.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>environment</category>
      <category>tools</category>
    </item>
  </channel>
</rss>
