RailsConf 2019

From test && commit || revert to LIMBO

From test && commit || revert to LIMBO

by Shane Becker

In this talk from RailsConf 2019, Shane Becker discusses the concept of "Test && Commit || Revert" (TCR), exploring its origins, practical applications, and implications for software development. The talk is structured in three parts, starting with a technical overview of TCR, followed by a historical context that highlights the evolution of programming patterns and methodologies that led to TCR, and concluding with practical insights from Becker's own experiences implementing the concept.

Key Points Discussed:

  • Understanding TCR: TCR is a process where if tests pass, all changes are committed; if they fail, all changes are reverted. This mechanism emphasizes rapid feedback and encourages programmers to work in small increments.
  • Historical Context: Becker shares a brief history of influential concepts and figures in software development, such as Kent Beck, who contributed to Test-Driven Development (TDD) and the Agile Manifesto. The principles of TCR can be traced back to architectural patterns discussed in books like "A Pattern Language".
  • The Evolution of Programming: The talk reflects on how the TCR methodology is grounded in past programming practices and philosophies, asserting that many modern practices are derived from earlier ideas.
  • Implementation and Lessons Learned: Becker recounts practical experiences using TCR, identifying challenges such as reverts during coding sessions, which led to valuable lessons. Important takeaways include the significance of fast tests, the benefit of making small, incremental changes, and trusting the automation process.
  • Practical Application: He encourages attendees to implement TCR in real-world projects, emphasizing experimentation with TCR while remaining in a safe coding environment. Becker offers suggestions for improving tool integration and enhancing TCR practices.

Conclusions and Takeaways:

  • Becker asserts that TCR can potentially reshape the way programmers approach software development. It fosters a culture of safety in experimenting with code, while boosting efficiency and reducing the fear of failure in committing code changes.
  • The talk concludes with a call to action for developers to explore TCR, whether in toy projects or live applications, and to engage with the broader programming community about their experiences with this approach.

Overall, Shane Becker's presentation at RailsConf 2019 sheds light on an innovative approach to coding practices that combines history, theory, and practical application in a rapidly evolving field.

00:00:20.449 Unfortunately, in the time that I put this talk together, I didn't have the opportunity to dive into the concept of LIMBO too much with other people. LIMBO really does require collaboration; it's not a 'by yourself' thing. So, when I changed the title of the talk, I decided to take out LIMBO.
00:00:32.520 Since I'm not going anywhere related to it, the term 'from' doesn't make sense either. So now, I'm just left with 'test && commit || revert.' What I ended up discussing instead was software patterns—design patterns and architecture patterns.
00:00:38.070 Here’s the title of the talk: "Patterns and Tests and Commit or Revert." My name is Shane Becker. I go by Vegan Straightedge on the internet, and I look like this in most places. I used to look like that, and in most cases, I’m wearing a Cubs hat. Terrance Lee and I are sort of the blue hat Ruby crew. We once co-organized Cascadia Ruby in Seattle before moving it to Portland.
00:01:02.309 I also put on the best backyard storytelling conference in the universe, called FarmhouseConf, in Hollywood, California. I used to be the open source cheerleader for Engine Yard back in the day when they were a company. I worked with the open source teams on Rubinius and JRuby, primarily handling community outreach. Currently, I live in a small town called San Francisco, California, and I work for a company called Mode.
00:01:34.619 These are the company values which you can’t read from this distance, but if you talk to me, our CTO, or any coworker, we’ll tell you about them. We have plenty of inside jokes about goats, and an abundance of puns. Our team is diverse, with developers and engineers at various experience levels, interests, and areas of expertise. And of course, we are hiring! You can learn more about the company at mode.com.
00:02:11.430 Imagine you have some mountain data in a database, and you want to ask data-driven questions or obtain data-driven answers. If you have data scientists, analysts, or simply curious people willing to write a bit of SQL, they can get things done. Seriously! You should find our CTO, who is somewhere in this room; we’ll be at our table where the tables are. She is the best, and you should come work with us.
00:02:35.450 Now, on to the talk. It will have three parts: a technical overview of what 'test && commit || revert' means, then this weird, wild, and hopefully wonderful historical interlude. Does everyone know you’re in a talk on this track called Weird, Wild, and Wonderful? Great!
00:03:15.810 Here’s the TL;DR of the whole technical part of the talk: it boils down to 'test && commit || revert.' I’ve made it big so everyone in the back can see it. Let’s break this down, because these aren't Unix commands you can issue; 'test' isn’t a command, it’s an idea. So let’s turn these concepts into actual commands we can issue.
00:03:53.220 When we talk about the test part, you might be running Minitest and use rake tests, or perhaps you’re using RSpec that has to run in the context of Bundler. Maybe you created an alias for it, because like me, you hate typing. Now, the commit part in 'test && commit || revert' means commit all changes—don’t be picky. Just commit everything!
00:04:43.440 You could do a git commit -a -m 'All of the things.' And for those who don’t know, '-m' means you want to have the commit message inline in this command, instead of opening your editor to type a message. The '-a' option means add changes to files that you’ve already tracked in version control. Please note, this does not catch untracked files.
00:05:22.800 So I’m also going to talk about running 'git add .' which will add everything, and then 'git commit -a -m TCR' for the commit part of 'test && commit || revert.' Now, what does revert mean? It’s the opposite of committing all of that work. Chances are you’re using Git; if you’re still using Subversion, I apologize.
00:05:54.960 To be clear, it’s not a git revert in the sense of undoing a past commit; it’s about undoing all of your unsaved changes. There are at least two ways to do this in Git: you can run 'git reset --hard,' which is bold and daring, and those changes will be gone forever.
00:06:09.599 Alternatively, you can add all your files and stash them. The stash is like a last-in-first-out stack, so you can pull those changes back out later if you wish. But for our purposes, we will be bold and daring and let go of the past.
00:06:35.279 So we went from 'test && commit || revert' to 'TCR.' Now that it's just one little word, we can make it really big to see in this room. If you’re here only for the technical reenactment of a technical blog post, thank you for attending my TED talk. You’re free to go!
00:07:16.099 Now, I want to discuss the idea of TCR and explore where ideas come from. I’m already tired of saying 'test && commit || revert,' so I want you to create a mental alias: when I say TCR, I mean 'test && commit || revert.' So, what is TCR? In my opinion, TCR is five things.
00:07:50.510 First, it’s just a simple idea—which I think we should all purge from our language. It’s not a prescription of particular tools or technology; instead, it’s a combination of things that we already know. I bet everyone in this room has run tests, maybe written tests, committed code, and reverted code.
00:08:34.590 It’s also about automating that combination. Finally, maybe it helps to establish a new way of doing software development. We’ll see. I don't know; it's still in its infancy, like a zygote of an idea, and its future is unclear.
00:09:10.370 If TCR is 'just an idea,' then why now? Why didn't someone else come up with this before? To address those questions, I’ll share a brief and incomplete history of TCR. It’s important to note that no history is objective or complete. This section of my talk will cover thoughts that predate the idea of TCR.
00:09:46.520 Let’s start with a moment 100 years ago when Eisenhower took a road trip from DC to San Francisco that lasted 62 days. As an alternative start, I want to focus on Eugene, Oregon, at the University of Oregon in 1961 when the university published its so-called master plan.
00:10:22.110 This was not it; this is an Apple Maps image of the campus. On this master plan, they laid out decades of architectural development: the ultimate Gantt chart in waterfall development. They wanted to raze an 1800s cemetery to build new buildings.
00:10:58.720 Much to the community's credit, students, faculty, and staff pushed back and resisted this idea. They were able to stop it. In 1968, the university created a new science building called Klamath Hall, which is notably ugly and reflects a style of architecture called Brutalism.
00:11:32.750 Brutalist buildings often feature lots of concrete and rigid geometry, and while they had their boom in the '60s and '70s, in some ways, they remind me of the Jetsons—our parents' or grandparents' vision of what the future would be, a future that never really materialized.
00:11:59.080 These buildings are artifacts or relics. Every time I think of Brutalism, I recall a specific abandoned Soviet monument in Bulgaria. I won’t attempt to pronounce its name because I don't speak Bulgarian or Turkish, but it translates to 'I see,' which makes sense because it looks like Hoth.
00:12:26.250 This building's silhouette even looks beautiful in its context—especially since it’s abandoned and falling apart. In the right setting, Brutalist buildings can be appealing, yet when done poorly, they can feel inhumane. Picture the Buffalo New York City Court building; imagine working there every day. It has no windows and resembles a battleship.
00:12:57.950 Klamath Hall was none of those things when built: it was ugly and out of place compared to the rest of the campus, which featured red brick and trees that are typical for the Pacific Northwest. In 1970, one of those logging trucks killed a student, further traumatizing the community.
00:13:30.210 In a time of unrest and protests regarding development decisions, the community voiced their desire for a more participatory process. The university president enlisted a group of architects from UC Berkeley, referred to as the Christopher Alexander group. They were tasked with resolving the two significant problems: which buildings to build and how to decide them.
00:14:14.079 They published the results of their work in a book called 'The Oregon Experiment.' I highly recommend this book. It’s small—half an inch thick, about 180 pages—and it outlines principles like Organic Order, meaning the whole can only ever be expressed by a multitude of local actions.
00:14:59.340 Participation has to include users—students, faculty, and staff—who must decide what to build and when to build. This must be done piecemeal, with small iterations and patterns forming an agreed-upon vocabulary for building.
00:15:39.880 They published the book 'Timeless Way of Building,' which outlines the theory of this process, in addition to laying out a 'Pattern Language' that describes 250 patterns.
00:16:01.639 These patterns vary in scale—some are broad, like neighborhoods should be identifiable, while others are very specific, like there should be seating walls present. This highlights a broad scope of concepts to inform architectural decisions.
00:16:28.670 Now, let’s transition to the realm of making computers do things. In 1979, two individuals read 'A Pattern Language' and came to similar revelations independent of each other. One was Ward Cunningham, who received a draft copy, and the other was Kent Beck, who was fascinated by architecture. He often read the book at a local bookstore since he couldn’t afford to buy it.
00:17:06.570 In 1985, Kent Beck happened to be hired for a project that included Ward Cunningham, and together they accidentally invented or rediscovered pair programming. From there, they began discussing pattern languages and their connections to building software.
00:17:53.860 They created a website called the Portland Pattern Repository, which still exists as the first wiki. Ward Cunningham created it in 1994. This site eventually sparked a book called 'Design Patterns' by the Gang of Four, which is considered a seminal text in our industry.
00:18:31.569 Later, in 1997, Kent Beck published a book about patterns in Smalltalk. This book is a fundamental link leading to our discussion today. I borrowed this book from friends who introduced me to 'A Pattern Language.' When I first attempted to read it, I misinterpreted its purpose. Initially, I thought it was a web design book.
00:19:03.840 Eventually, I came across it again, thinking of it in relation to tiny houses, but still found myself unprepared. However, I made connections from this book from the 1970s directly to the one published in the late 1990s.
00:19:43.680 It's imperative to recognize the four decades of influence from these ideas and the connections formed by individuals throughout that time. Kent Beck is also credited with inventing test-driven development or TDD; when he explained it to me, he rediscovered TDD existed as far back as the sixties.
00:20:25.080 NASA used TDD for the Mercury missions, writing input and output tables as guides and developing code to fulfill those specifications. Extreme programming also stemmed from Kent Beck, combining these varied tools.
00:21:03.720 Then we saw the emergence of the Agile manifesto, a collection of the principles influenced by principles from the Oregon Experiment and the six principles it presented. So how did we transition from architectural design principles in the 1970s to 'test && commit || revert' in 2018? There were actors and thinkers hovering around the same idea.
00:21:40.560 Kent Beck, for an extended period, had been practicing tests and commits driven by habits of laziness and efficiency. In 2012, Sandy Metz published a book that should be on your must-read list, often referred to as 'pooter' because that’s how a little kid would pronounce 'computer.' It covers topics of refactoring, design patterns, and testing.
00:22:14.650 In 2017, Sandy Metz and Katrina Owen co-authored '99 Bottles of Ooh,' a fantastic book you should purchase. They describe a process close to manual TCR, suggesting to make a tiny change, run the test, commit if it passes, and revert if it fails; this aligns directly with TCR.
00:22:58.390 When I learned about TCR, I thought it resembled the methodology in '99 Bottles of Ooh.' Interestingly, Kent Beck wasn't the one to come up with the 'revert' part; that was a suggestion derived from Oslo Air at Code Camp, discussing tests and commits.
00:23:29.259 Oslo noticed the inherent logical symmetry: if you commit after a test and the test fails, you must have a reversion mechanism in place. The question of who invented TCR is less crucial than contemplating who discovered it.
00:24:12.090 It’s valid to give credit where it’s due, but a better question might be: who has been experimenting with these ideas? Katrina Owen may fit this role, as she applied manual TCR, Kent Beck named it, and Admin surrounded it with the revert concept. Ultimately, the point is that ideas are interconnected and not birthed in a vacuum.
00:24:50.469 We don't have instances that stand alone; every idea stands on the shoulders of giants. Everything is a remix, and we should recognize that cultural evolution allows us to build upon what came before. Some people, like Sandy, believe that the idea for TCR was simply timely.
00:25:29.290 Now, we enter the third section of the talk. Here are some lessons I've learned from my experiences with TCR. Improving tests is essential; if you're changing an implementation, TCR is great as it helps maintain successfully passing tests. If every change results in passing tests, commit it!
00:26:21.230 If a change fails, don’t hold onto those emotions connected to a sunk cost; when you throw out something that doesn’t work, you're discarding a bad practice, not a good one. However, if your test suite takes longer than a few seconds to run, don’t run the entire suite each time.
00:26:59.670 Instead, try running only the isolated tests—this will yield a much faster feedback loop. The takeaway here is to make your tests quick; quick tests enable smoother implementation of TCR. You can achieve this by ensuring your tests are fast or running isolated tests manually.
00:27:34.930 Fast tests are key, especially when refactoring. According to Martin Fowler's definition of refactoring, aim to change the internal structure of your code without altering its external behavior. This practice aligns perfectly with the TCR approach.
00:27:52.679 My first pairing session was with Morgan Fogerty, where we built a Fibonacci sequence in a small domain. The biggest lesson was that our commit history became less meaningful because every single commit was not useful. So we wondered: is the commit log really that important?
00:28:43.320 It's like reading old comic issues; while I don’t go back to read them, I appreciate their existence. So, we should probably always work on a branch, as many of us do, rather than on master. When merging a pull request, consider using a squash commit to tidy up the commit history.
00:29:35.050 While exploring TCR, we also discovered a reflex to quickly undo. Was that cheating? This led us to question our methods further. We occasionally got failure messages referring to line numbers from previous code that no longer existed, causing confusion.
00:30:01.620 These issues could likely be addressed through better tooling rather than discarding the idea of TCR entirely. Perhaps there are TCR-specific tools that could capture error states and help clarify failures. We also saw that making simultaneous changes to tests and implementations posed unique challenges.
00:30:53.330 In essence, TCR operates as the opposite of TDD—TDD encourages writing failing tests, while TCR results in reverting failing tests. To cope, a potential workaround emerged: write a test with hard-coded implementations to satisfy it, commit the test, and then adjust the implementation afterward.
00:31:38.600 During my collaboration with Evan Phoenix on a bug in Puma, we faced a series of commits and numerous reverts. We tested isolated changes to maintain speed, as Puma's features largely revolve around web server performance.
00:32:29.750 Before submitting our pull request, we ran the entire test suite to ensure everything worked seamlessly. That experience exemplified the utility of TCR in achieving tests that elucidated buggy behaviors.
00:33:21.220 Working with a team on a Rails and React project was also an enlightening experience. We aimed for speed and ended up completing 53 commits over the course of 86 minutes.
00:34:12.180 A curious outcome was the realization that individuals needing to track time retrospectively could analyze their commit logs. Every log entry indicates when the last save was made.
00:35:05.000 By remaining methodical, we even minimized our edits to single character modifications at times, which led to lower stakes when running TCR. This practice encouraged exploration due to reduced risk.
00:35:56.800 In conclusion, we learned that making small adjustments is essential. Small changes are generally safer and easier, costing less time when errors occur.
00:36:29.060 The importance of these small movements cannot be overstated; they offer safe grounds for iterations and growth, which ultimately allows you to scale down larger changes into manageable adjustments.
00:37:00.180 As I conclude my talk, I invite you to engage with these concepts further. Your action items for today include cleaning up your code comments. You don’t have to follow my instructions; you each have your own paths.
00:37:39.700 However, here are some book recommendations: 'The Oregon Experiment,' 'The Timeless Way of Building,' and 'A Pattern Language.' I suggest reading these texts to understand their significance better.
00:38:19.480 Lastly, try TCR on your toy projects or in your production codebase cautiously. Experiment with small refactors and test coverage improvements.
00:39:11.920 If you feel like you need support, reach out to me, and I would be more than happy to pair with you during the conference or remotely. And if you do try it, please tweet about your experience. Sharing these findings can elevate the conversation around TCR.
00:39:47.990 Finally, for those looking for extra credit, consider crafting tooling or creating a CLI for TCR. Thank you for your time! You have plenty of options, and I appreciate you choosing to engage in this wild and wonderful trek.
00:40:08.350 Here’s my contact information; I’ll be here to chat.