Test-Driven Development

Summarized using AI

Nobody will Train You but You

Zach Briggs • April 29, 2013 • Portland, OR

In the presentation titled "Nobody Will Train You but You," Zach Briggs discusses the necessity for developers to take their learning into their own hands, particularly within the Rails community. He starts with an engaging premise, asking if attendees look forward to work or dread it, emphasizing the idea that the responsibility for improvement lies with the individual.

Key points covered in the talk include:

- Personal Journey: Zach shares his experience transitioning from a Direct Mail analytics role to becoming a junior developer after discovering Ruby on Rails. This dramatic shift illustrates that success in development comes from passion and proactive learning.
- The Limitations of On-the-Job Experience: He argues that many developers plateau due to a reliance on immediate work tasks rather than seeking deeper understanding and skills enhancement.
- Effective Learning Strategies: Zach recommends taking notes, making coding concepts personal, and utilizing resources like tutorials and screencasts as methods to truly learn rather than just perform tasks. He shares how writing down solutions helps solidify them in memory.
- Overcoming Knowledge Gaps: He discusses 'unknown unknowns'—aspects of coding that a developer might not even realize they don't know—and the importance of learning from mistakes and refactoring to avoid complications.
- Learning from Others: The value of studying other people's code and tutorials is emphasized as a critical way to grow as a developer. He highlights the importance of combining practical experience with known best practices.
- Adopting Good Practices: Zach notes that adopting structured approaches to coding, such as practicing Test-Driven Development (TDD) and understanding principles like Single Responsibility, enhances code maintainability and reduces future headaches.
- The Joy of Development: Finally, he conveys the idea that masterful developers are those who find joy in their work. He correlates fun with excellence in programming, suggesting that true skill comes from passion and creativity rather than solely effort.

In conclusion, Zach's talk is a powerful reminder to developers that improvement is a personal journey filled with practice, the adoption of solid coding principles, and the enthusiasm to continually learn and enjoy the craft. The main takeaway is that proactive engagement in one’s professional growth leads to greater programming joy and efficiency.

Nobody will Train You but You
Zach Briggs • April 29, 2013 • Portland, OR

Why do we all know a developer who has been pounding out unmaintainable code for a decade or more? Why do people "believe in TDD but I don't have time to write tests during crunch?" How is it that we have an entire industry based around rescuing teams from acutely awful Rails apps?
It's because on the job experience is a poor teacher; plateauing as soon as the developer is able to ship code that meets requirements. Schools teach Computer Science which is only tangentially related to being a developer and most kata's are approached incorrectly, giving no value at best, and reinforcing poor practices at worst. On top of all this, our pairs (for the lucky ones who pair program) probably have not shown us anything new in months.
This presentation will give specific, concrete steps on how to slowly and steadily improve our game through practice and hard work. I'll identify what skill Rails developers should be focusing on and walk the audience through how to target and eliminate these weaknesses so that nothing but white hot joy streams out of our fingers and into our apps. There's no magic here, no secrets, and no hacks; just you and me working our butts off until we suck a little less.

Help us caption & translate this video!

http://amara.org/v/FGb9/

RailsConf 2013

00:00:12.259 Thank you, we’re good. All right, imagine if you will, it’s Sunday night. You’re brushing your teeth, getting ready for bed. Are you looking forward to work the next morning? Is it even really work because you love it so much you'd be doing it anyways in your free time? Or did I just kind of bum you out by even invoking the concept of Sunday night?
00:00:37.200 This is 'Nobody Will Train You but You.' This talk will give you the tools to do what you love every single day for the rest of your life because you'll be so freaking awesome that people will line up to pay you money for it.
00:00:48.780 This is me on the internet. My name's Zach, and I work for Test Double. I started with them last week, so if you ever want to really spike out your anxiety level, start a new job with people who are way, way smarter than you, and then give a talk at a national conference the next week. It's been kind of amazing. Test Double focuses on building apps with a lot of user interactions, like Backbone, Ember, or Angular, and then taking those to build maintainable software. It’s an amazing concept.
00:01:28.979 A year ago though, I wasn’t a developer at all. I was doing direct mail analytics, which is approximately as exciting as it sounds. I was absolutely drowning in work. I Googled this Rails thing on May 2nd of 2012. It’s a framework that’s kind of popular; you might want to give it a shot. Within a couple of months, I was hired as a junior developer after shipping my first Rails app and almost immediately bumped up to 'developer flavor'—junior no more. I joined Test Double last week, and here I am today at RailsConf.
00:02:16.739 I’m not telling you this to brag, but I see a lot of people who seem to be waiting for something—maybe they're waiting for rescue or waiting for permission. Month after month, they look at these Sundays just strung out in front of them, and every single Sunday they just can’t stand going to work the following Monday.
00:02:30.540 I’m not sure if they think somebody's going to give them permission to do what they love, but it’s not going to come. You have to do this on your own. When I first started, I wasn’t very good at the whole Ruby thing. I was pretty notorious for using the heck out of Google, and was even accused of using 'Shadow Google', this parallel search engine that only I had access to because I could find these gems to do things almost better than anyone else.
00:02:57.360 But after about two months, I realized I wasn’t getting any better at all. I talked to one of my friends about this and asked them if maybe Stack Overflow was rotting my brain, but he didn’t buy it. He told me that I just needed more time and that I was being too impatient. After two months, I should expect to still kind of suck. It takes more and more conversations with the compiler to get better.
00:03:34.980 So we went back to pairing that afternoon. I don’t remember exactly what we were working on—maybe it was a Rails migration we wanted to do in a single transaction to avoid waiting multiple times for a large table. We went online to search for the syntax, and on his browser, there was just this big wall of visited links, almost like he had been there before.
00:04:06.659 If that was my browser, I would have seen the same thing—just walls of purple. So he obviously hadn’t had enough conversations with the compiler either. We did the migration, got back in the model, and finished up whatever we were working on. Neither one of us could remember what it was; it completely fled our brains. This struck me because we were not naturally getting better. Each one of these searches was expensive—it’s a context switch, and as programmers, we know how costly these context switches are.
00:04:51.720 It’s like being tapped on the shoulder and interrupted. It costs about 10 minutes per 10 minutes of pop. If you’re in a situation where you only have three hours of productive time during the day—pretty common—nine trips out to the web for some syntax you didn’t quite know costs you half of your day. That leaves an hour and a half left to work. I’m not good enough to get all my work done in an hour and a half—maybe you are. It doesn’t have to be that way, though.
00:05:35.280 Corey Haynes talks about making your searches your own after the fact. Every time I do a search, I write it down on an index card. I write the answer down on the other side, and when I have some free time, I review it—I make it my own. Typically, just the act of writing it down on paper has great features—it’s flexible, it’s visible in sunlight, and it has excellent battery life. But the act of writing it down seems to cement it into my brain in a way that typing it doesn’t.
00:05:54.600 In my previous position, we frequently dealt with business intelligence dashboarding. We had text files as inputs and eventually built a Backbone front end as an output. I had this collection of strings, and I didn't want the whole string, only a piece of it, so I had to learn regex. I took a break from being angry at regular expressions long enough to learn this recipe, which I was able to apply to various situations. Suddenly, there was a whole category of problems I didn’t have to go out to the web anymore; I could just adapt this.
00:06:35.760 Here's another one: We would have a hash, and we want a slightly different hash or radically different data structure. Now, I have each of those objects in my pocket. Anytime I hit this class of problems, I can adapt this. When looking at a blank screen, text editor, or a blank piece of paper, we can’t pretend we got it right. Do you know off the top of your head what the order of arguments is, or how to use each with object versus inject without looking it up? That’s important; just knowing it and being able to recall it quickly gives you a huge advantage.
00:07:03.539 Since I started doing this, I’m so much faster now. I can’t tell you how much faster. I’ve probably doubled my speed, maybe even more. I find myself being more creative too. I had a German teacher in high school who told me to think in German. When you’re fluent enough in a language to think about it, you can compose new sentences. Similarly, when you're fluent enough in Ruby and don’t have to keep going back to the web, you can start making these new connections and use lateral thinking, thinking outside of the box.
00:07:41.280 However, this only gets us so far. Each with object isn’t going to teach me about dependency injection. Regular expressions probably won’t teach me about composition. We need to find a way to know what we don’t know. Thank you Donald Rumsfeld for popularizing the concept of 'unknown unknowns'—this includes the stuff I know, the stuff I don’t know, and then the unknown unknowns.
00:08:08.220 In my case, the unknown unknowns are the dark matter—the interesting part of what we need to learn. An example of this for me was the law of Demeter—a dead simple concept that’s often misrepresented. I’d heard about it before, but it wasn’t until I began putting my code under test and trying to drive corner cases out of software that I really understood it. As I wrote new tests, I kept having to instantiate three other unrelated objects, which was a pain in the ass.
00:08:48.840 After about 20 minutes, it hit me—this shouldn’t suck so much. The way my code is structured is probably pretty bad, and if my tests are experiencing this annoyance, it means if those incidental objects change, other unrelated objects are just going to shatter at the same time. It was through that test pain that I gained a little wisdom; wisdom must be earned, not grown.
00:09:33.180 We don’t have to wait around on someone else’s schedule to earn more wisdom. It doesn’t take years of extra-curricular activities. We can go out and pick our own fights and advance beyond our years. We, as open-source developers, are lucky to have access to the collective knowledge available out there. If Google has all the world’s knowledge, then GitHub surely has its wisdom.
00:10:12.680 It’s fantastic to look at someone else’s source code and gain wisdom from it, but we can’t infer wisdom from a product any more than a pig can be inferred from a sausage. It is possible, however, to follow the process forward from a blank page to final draft and learn something along the way. Just because we’re looking at someone else's source code doesn’t mean we have any idea why those characters are laid out that way.
00:10:53.580 We need the microsteps, the minutia; it’s the only way we’re going to gain wisdom. We’re lucky in the Rails community to have these brilliant tutorials and books available to us to gain that wisdom. Michael Hartl is somewhere at this conference, and I went through his Ruby on Rails tutorial, which helped bootstrap me. Sandy Metz is also here; make sure to say hi to her. She has this amazing book on object-oriented design with Ruby.
00:11:12.300 We have these incredibly detailed tutorials out there. Some are available for free. I’ve recently been teaching myself more JavaScript after joining Test Double, and I feel lucky to be part of the Ruby community for the wealth of tutorials available. One of my favorites is 'Build an App with Corey Haynes,' a screencast series. There's also 'Objects on Rails' by Avi Grimm.
00:11:49.740 And the one I want to talk about today is 'Sucks Rocks,' part of the 'Destroy All Software' screencast series. Currently, subscriptions are suspended, but it is going to open up again at some point. This was the perfect tutorial for me—it’s super high in context. We’re not just building a bowling scorer with no inputs or outputs; we’re creating a web app that’s hitting an external API and serving JSON.
00:12:10.740 Every single piece of source code is typed out; nothing is just magically pasted on the screen. I hate that in tutorials. We see each bug being committed, and we witness the blind alleys and recover from them. Find somebody you trust, who has skills you want, and who inspires you—maybe that’s Gary Bernhardt or maybe it’s not.
00:12:35.460 The eight-part series on 'Sucks Rocks' has a runtime of about an hour and a half. I treated each episode like a kata, watching it, taking notes, and attempting to reproduce it character for character, going back through time and time again. After the fourth or fifth time watching an episode of someone else's screencast, you start to feel a little stalkery. You might start wondering, 'What do you think about a Gary Bernhardt tattoo?'
00:13:03.420 It took me 40 hours to fully memorize this tutorial—turns out he types kind of fast. That was time I wasn’t spending with my spouse, Mary, or doing billable side work. It was a measurable opportunity cost. I wasn't looking at other tutorials or teaching myself new things.
00:13:30.960 After hearing the phrase 'testing behavior versus testing implementation,' did you ever want to punch someone in the nose because it sounded so meaningless? I didn’t really get that concept at first—it wasn’t helpful. This is code that’s similar to what was in the original 'Sucks Rocks' app. It originally used 'Arbing' which is a Ruby Bing wrapper, but that API is long gone.
00:14:02.100 It’s been completely overhauled and then disappeared in favor of Windows Azure. So I just swapped it out for the Google gem. This is a fundamental component that makes the rest of the app run, and it was two lines of production code—zero lines of test code that changed when I swapped it out.
00:14:39.600 This, of course, is a subset of the single responsibility principle. We know it’s important because it has a lot of syllables, and the more syllables a principle or a law has, the more we have to pay attention to it. This is probably character for character out of the 'Sucks Rocks' app. It’s not super apparent at a glance, but at no point do we allow an Active Record object to leave the model and perform 'find by term'.
00:15:00.660 Typically, I would have structured my app differently. I would have written my tests first, but they would have just been a checkbox. I’d think, 'Oh, I’ll write my tests first,' and then just smear some more stuff on the model. However, when the tests were allowed to influence the design of the system, it ended up looking more like this.
00:15:31.620 I don’t think this structure had any transitions; it emerged naturally through TDD, and it was the first time I saw this truly occur in a Rails app. It was mind-blowing for me, like one of those Wizard of Oz moments. This wasn’t our planned outcome; it wasn’t some universal design approach. It just happened, and it was kind of awesome.
00:16:05.580 Notice that the third-party API is just sitting in the corner, keeping baby company. When it changes, it’s going to cause fewer breaks than the rest of the system. For example, think of something like Braintree in some of the Rails apps we’ve seen. Think of all the places in a user model that would have to change in an average app if a different payment processor was used.
00:16:35.100 On Friday, I had actually cargo culted this structure into a prototype JSON API backend I was building. My assumptions were way off to the point where I ended up rendering it all server-side. It took me 15 minutes to swap the structure of the application around from a JSON API into just a single template rendering because I could gather those components and plug them into something else.
00:17:05.520 This isn’t a universal solution for all of your problems, and this is also where I started to fight nil. The dreaded 'no method error undefined method each for nil:NilClass'—thank you, Ruby, for that. Typically, the origin of the nil isn’t even in that stack trace. That kind of garbage is what I expect from JavaScript; it's disappointing coming from Ruby.
00:17:31.560 Some of those nil errors start to sound like urban legends. I once saw a nil originate in one object, travel through two others, and back into a Rails backend, causing chaos. But I have to give props to Binding.pry, it can help track down a nil.
00:18:01.500 The kind of stuff happens; similar production code that I might have written back in January hits some kind of external API wrapper while I’m doing some work. It’s really common in Ruby to return nil when something isn’t found as a default behavior. If Active Record’s find doesn’t find something, we know it’s going to return nil.
00:18:32.520 This is how I would structure the code now—using a sentinel object. I was using this at work a few months ago, and my partner asked me, 'What the heck are you doing, Zach? That’s class.new? Exactly how much paint did you huff this morning?' I got kind of excited because Gale is awesome; I don’t get many opportunities to show her something new.
00:19:02.040 I told her that’s just an inner object since 'no score' is something that’s kind of okay to happen in our logic. We need something to represent that, but nils can be problematic. Almost on cue, 15 minutes later, we got a stack trace that said undefined method each for performance: no score. Holy crap, now that’s a stack trace we can work with!
00:19:31.920 Last week, I saw a stack trace like this in New Relic. Imagine a nil stack trace in New Relic. You probably don’t have to imagine that; you’ve probably pulled the app back down to get the database into the same state to use Binding.pry and protect your face.
00:20:06.840 When you encounter stack traces like this, you can look at the New Relic event console and think, 'Oh wow, I know what’s happening there,' and use it to diagnose and troubleshoot problems. I’ve had far fewer afternoons just lost to debugging.
00:20:40.920 I took the tools from that tutorial, the tools that Gary Bernhardt has in his brain, and through 40 hours of memorization—practicing over and over again, experimenting, and trying them in my projects, seeing where they worked or didn’t, and when I showed someone else, saying, 'Hey, this is so cool! Look at this.' I learned one, did one, and trained one.
00:21:07.920 The very first time I encountered these, I kind of made a copy of those tools for myself. I’m not arrogant enough to think I’m as good as him, or that my tools resemble his—but they’re mine, and that’s the point.
00:21:35.520 Since they're mine and they're not just things I'm mindlessly copying into an editor, I feel comfortable pulling them out when I see fit. And since it’s not dogma or a religion, I can put them away when they’re not the right tool for the job.
00:22:07.920 I still like the Rails generate scaffolds because quick demos are nice to have ready for someone. I still have my controllers talking directly to my models a lot of the time because that’s perfectly okay. Just because I know how to build a system that doesn’t do that doesn’t mean I can’t build systems that allow for it.
00:22:33.720 Memorizing a good tutorial made me a better developer. My code is much safer because I’m testing meaningful things. I’m writing tests that reflect reality, and since they’re not stapled directly to the production code, they’re less likely to shatter with minor changes. Writing tests like that means I had a test suite that was more reliable.
00:23:01.920 My code is more resilient; my tests don’t break as often, and the rest of the code suffers less as well. I’m a lot faster now because I know this stuff cold—these things spring to my fingertips without me having to think.
00:23:32.760 Writing down all of my Google searches is also faster. Remember that two-time speed increase when fluent in Ruby? It also fosters more creative lateral thinking—thinking outside of the box.
00:24:00.480 And I haven’t even told you the best part yet! The best part is every time I’m on the server side, starting a new project, or creating a new feature in an existing project, I have the skill and confidence to begin with a plain old Ruby object (PORO). I feel like I’m back on tryruby.org for the first time!
00:24:42.480 Can you remember your first time playing with Ruby? Maybe it wasn’t try Ruby, or maybe we have some Pickaxe babies in the crowd or Rails babies. This is programming; you’re not supposed to have that much fun!
00:25:19.560 Every time I do this, I’m having a blast! See, I just lied to you—these aren’t tools; these are toys. That’s Jim Wyrick up there, doing his Y Combinator keynote from RubyConf last year.
00:25:48.480 The code up on his slide isn’t production quality; in fact, I think your fingers would break if you tried to use it in production. But it’s just something he enjoys, and he’s sharing that enthusiasm. One time, I was watching a video from ConFreaks last December when my spouse, Mary, walked in, looked at the screen, looked at me, and asked, 'Is Santa Claus teaching you Ruby?'
00:26:19.740 Yeah, I guess so, kind of. The very best programmers—the ones who can work anywhere because their resumes are their name—the ones that don’t have to dread Sundays, because every day they’re doing what they love—those programmers didn’t get that way just from hard work; they got that way because they’re having so much fun they couldn’t bear to put down the keyboard.
00:27:00.240 My name is Zach. Have fun!
Explore all talks recorded at RailsConf 2013
+93