The ultimate software development tool

Best practices on project management, issue tracking and support

Tag: coding

How to build a code review culture: An Interview with Derek Prior

We’ve interviewed Derek Prior, a Developer at Thoughtbot and host of The Bikeshed Podcast. We discuss how to build a code review culture, diving into the benefits of code reviews, the essential elements to make them effective and how to handle conflict if it arises.

Content and Timings

  • Introduction (0:00)
  • Code Reviews Vs. Pair Programming (0:26)
  • Benefits of Code Reviews (1:10)
  • What to cover in a Code Review (4:48)
  • Code Review Author and Reviewer Best Practice (6:47)
  • Handling Conflict in Code Reviews (10:21)
  • Recommended Resources (12:45)

Transcript

Introduction

Derrick:

Derek Prior is a developer for Thoughtbot in Boston. He co-hosts a web development podcast called, “The Bike Shed”. He speaks about development practices at conferences, including the talk, “Cultivating a Code Review Culture”. Derek, thank you so much for taking time to join us today. Do you have a bit to share about yourself?

Derek:

I’ve been speaking at conferences and meet-ups lately about code reviews, like you said. It’s something that I’ve had a lot of experience with over the last 10 years or so.

Code Reviews Vs. Pair Programming

Derrick:

Some people mean different things when they use the term “code review”, like “pair programming”. What do you mean by code reviews?

Derek:

There’s this term, and it’s not my term, called, “modern code review”, and that’s what I’m talking about. What that means… The definition of that is basically, asynchronous or tool-driven, generally like, lightweight reviews. Most of the people I work with that means a GitHub pull request. That’s typically what I’m talking about. Pair programming is great, and has a lot of the same benefits. But when I’m doing pair programming, I still like to have another person to review the code… I still like to have that other person, also review the code.

The reason for that is in pair programming, you’re kind of building up a solution with your pair, as you go. I really like to see at the end, if that holds up for another developer who might have to work on this next week kind of thing. Like, does this make sense to somebody who wasn’t there all along the way.

“It’s much more helpful to focus on the cultural benefits of code reviews”

Benefits of Code Reviews

Derrick:

Why are code reviews important?

Derek:

Everybody here, when they hear about this, everybody’s natural reaction is to say that they catch bugs. That is true. If I have code reviewed that’s going to have less bugs, than code that isn’t reviewed. But I think that that puts too much importance on the “finding bugs” part. Microsoft actually did a study of this, Microsoft Research, in 2013. Where they found that people consistently said the number one benefit from code reviews is finding defects in code.

But then when they looked at actual data collected in their code review tools, and talked to people after they did code reviews, what they actually found was that people got way more benefit, way more cultural benefits, out of sharing knowledge with each other, or keeping up with what everybody’s doing, and knowing what’s going on in that other part of the code base. Finding a really interesting alternative solution to a problem that they hadn’t thought of, just by getting somebody else’s viewpoint.

Those are the much more important things. I feel like they’re much more interesting than finding defects. Finding defects is actually, frankly, really hard. A lot of times I’ll talk to people about code reviews, and they’ll say, “Well we did code reviews, but we still had all these bugs. They weren’t helping us catch the bugs”, and yeah, they’re not going to catch all the bugs. By saying, ‘The chief thing we get out of code reviews is “defects finding”’, what we’re really doing is setting ourselves up for those situations where people say, “But you did a code review on this, and there’s still a bug.” Right?

It’s hard to find all the bugs, because when you’re doing one of these lightweight code reviews, you’re really just looking at a slice of a change. You’re looking at the diff, and to know exactly how that’s really going to impact your system, you have to know the entire system. You can catch edge cases where, “Oh, you didn’t check to see if this was nil”, or whatever the case may be. Knowing exactly where this is going to screw up your data, is hard to know, without knowing the whole system. Code review is great for some defect tracking, or defect finding, but it’s not a panacea. Instead, I think it’s much more helpful to focus on the cultural benefits of code reviews.

Derrick:

How should you work code reviews into your workflow?

Derek:

What we typically do at Thoughtbot is, when I finish up a PR, I will paste it into Slack, or whatever. We’ll paste that in and say, “Can I get a review for this please?” If it’s not urgent, that’s basically all that happens, right? If it’s urgent, I will ping somebody directly. Ping a couple people directly and say, “Hey, this is a production fix, can you take a look at this?” Generally, that’s enough, with the way we work, to get your code reviewed within the next few hours. Which is, generally sufficient.

You can move on to something else. You can review somebody else’s code in that time. You can kind of trade, if somebody else is coming up and finishing something up. You can be, “Oh yeah, I’ll take a look at that. You take a look at this one for me.” That kind of thing. We take a really, lightweight approach to it.

When you think about it, there’s a lot of natural breaks throughout your day that you can work these in to right? For me, I come in in the morning, “are there any PRs outstanding I can look at?” Then I get started. Then, right before lunch, or in the afternoon, if I’m going to take a coffee walk around Boston Common or something, I’ll look then. Either before or after. There’s plenty of times I find, that I can just work these in naturally. There’s no need to schedule them.

I’ve worked with teams that try to schedule them, or try to say, “This person is going to be the one, that’s going to be chiefly doing code reviews this week”, and I’ve never seen that work particularly well. I just try to say, “Keep it lightweight, friendly”, things like that. People are really surprised, or skeptical, to hear that this works. The biggest thing that makes this work is, keeping small, discrete, pull requests, that are going to be much easier reviewed, and providing some excellent context. That’s the “why” you’re making this change, not necessarily the “what”. Ultimately, the big secret to this is that, most of these code reviews only take me five minutes. It’s not a big commitment.

What to cover in a Code Review

Derrick:

What type of things should a code review cover?

Derek:

It’s really important that each person involved in the code review, doesn’t operate from a central checklist, but rather just looks at things that interest them about a change right? Or interests you overall. Maybe you just got finished reading this great book on design patterns. You’re looking for a way to apply this one design pattern. That’s what you’re going to look for. Great. Fine. That’s valuable. You’re going to teach somebody something.

Or maybe you’re really interested in web security, and you’re going to take a look at things from that perspective. Or accessibility, you’re going to take a look at things from that perspective. That’s where having a good blend, on your team, of people who are interested in different things, really pays off, in code review. We’re all going to look at code reviews, and try and see if there’s an obvious bug. I said, not stressing the bug finding, is a big key to this.

But yes, you’re going to look for them, and you’re going to comment on them when you find them. What I really like when people do, is just sort of take their slant on how they think software development should be. Just kind of look at it with their lenses and see, “Oh, did you consider doing this alternative thing over here?” I typically look at … I’m always harping on naming. Right? Part of what I think makes code review so great, is that it’s a great place to have a technical discussion about your actual software. Rather than in the abstract, like when we go to conferences and things like that.

I harp on naming a lot to say, “Do these names give us a good basis for a conversation, about this? Are they descriptive?” That’s really important to me. I look for test coverage, to see … Like I said, I’m not hunting for bugs throughout the entire system … But I am looking to see, “Is this adequately covered, by test?” I’m not going to look at every single test, but I’m just going to to kind of get an idea of “What kind of tests would I expect to see in this change?” I’d expect to see a feature spec. Or I’d expect to see a unit test. That kind of thing. Just make sure that those are there. Stuff like that.

Like I said earlier, the biggest thing is just everybody kind of, bringing whatever it is that they’re interested in … Whatever they’re an expert at … To the table, so that we can all learn from each other.

“Having conflict in your code reviews is actually really beneficial”

Code Review Author and Reviewer Best Practice

Derrick:

As a code author, what should you do to get the most from a code review?

Derek:

The number one thing is context. When you’re submitting a pull request, you’ve been working on this thing for four hours, or eight hours, or two days, or sometimes even a week, or whatever the case may be. You have a lot of context built up in your head. Some things seem really obvious to you at this point. But, to the person reviewing it, they weren’t there for you. They don’t have that context. What you really need to do is think about… It really helps if you’ve been making several small commits along the way, where you’re describing what was in your head.

But as you prepare the change… If you’re going to use a GitHub pull request, and you’re going to submit your pull request to GitHub, make sure you give a nice description of, a summary, of everything … What I really like to see is, not what … A lot of people will summarize what they did? That’s kind of important, the bigger the change gets, so I know what to expect when I’m looking through the change? But it’s not the only thing I want to see, right?

I can figure out what a change does by looking at the code. Unless it’s totally obfuscated. What’s really interesting is why. Why are we changing it? Why is this the best solution? What other solutions did you consider? What problems did you run into? Is there an area of the code you’re really unsure about, that you’d really like some extra eyes on? That kind of thing. Those are going to help you get a much better review, by setting up everybody else to be on the same page as you.

Derrick:

When you’re reviewing code, how do you do it without being overly critical or needlessly pedantic?

Derek:

This happens a lot. Where code reviews that aren’t done particularly well, or overly critical, can kind of, lead to resentment among the team. The big thing there is, negativity bias, that you need to be aware of. If I’m talking to you … Like I am in this conversation, and I give you some technical feedback, and I say, “Oh, why didn’t you use this pattern here”, whatever. You’re going to perceive that in one way. But if I say that same exact thing written down, it comes off more harsh. You’re going to perceive that more negatively.

It’s much more subject to your particular mood. I can’t influence it with the way I say something. It’s just a fact that, the same feedback written, is going to be perceived more negatively. One excellent way to get around that, is to give feedback in a manner that’s more of a conversation. What I like to do is ask questions. At Thoughtbot, we call this “asking questions, rather than making demands”, right?

Instead of saying, “Extract the service object here, to reduce some of this duplication”, I would say, “Hey, what do you think about extracting a service object here, to eliminate this duplication?” Right? They’re very similar comments, but now I’m opening it up to a conversation, by asking you a question. Like, “Oh, what do you think …?” Sometimes I’ll even say something like, “What do you think about doing it this way?”, and I’ll provide a code sample. Then afterwards, if I don’t really feel particularly strongly about it, I’ll be like, “No, I’m not really sure though, what do you think?” Just to kind of say, “I can see how this would go either way.” “What do you think?”

Clarifying how strongly you feel about a piece of feedback, is also something that can help. Making sure that you’re addressing people’s feedback. That’s basically, how to avoid being overly critical. Is just asking nice, friendly questions, that open up a conversation? The pedantic part, I guess would be like, when you start arguing in circles. When you’re not coming to a good conclusion here, right? What I’d say there is just, make sure you’re focusing on high value things. Don’t go edge case hunting everywhere.

There’s a lot of times you can find edge cases that, just aren’t going to come up. Or, maybe they are and they’re important. But really, what you want to be focusing on is, the more higher value type stuff that we talked about earlier. Try and focus on those, to stay away from these like, pedantic arguments that you can into in code review.

“The big secret is that most of these code reviews only take me five minutes”

Handling Conflict in Code Reviews

Derrick:

Inevitably, with discussions between developers in code, disagreements are going to occur, from time to time. How should you handle this type of conflict?

Derek:

I think the first thing to recognize, is that, having conflict in your code reviews like this, is actually really beneficial. Right? As long as they’re the right types of conflict and nobody feels bad about them afterwards, that kind of thing … Because if you’re agreeing with your teammates all the time, and nothing interesting is happening in your code reviews, you basically have a monoculture, and those are dangerous on their own right.

Like I eluded to before, you want everybody bringing their own experiences, and their own expertise, and sometimes those are going to clash with each other. My experience was, doing things this way, led to these problems, and your experience was, doing things this way, was actually really beneficial. We’re going to have conflict about that. The key is that, handling those conflicts properly, is how everybody on the team is going to learn.

What I suggest, when you find yourself going back and forth, a couple comments about something, and you don’t seem to be getting anywhere … Nobody’s yielding, right? What I try to do is take a step back and be like, “How strongly do I feel about this?” Do I feel like, “This is a quality issue, that if we go out with this code, like it is today, it’s going to be a serious problem immediately?” Or is this kind of like, “It’s not really the approach I would have taken, but, maybe it will work. Or it’s a reasonable solution.” That kind of thing right?

Often times, that’s actually what it is. Once we get beyond a certain level of quality, what we’re talking about is trade-offs, all the time. That’s basically all we’re talking about when we’re doing computer programming. Like I said, once we get past the initial quality is, the trade-offs involved. If you’re arguing about what is essentially a trade-off, maybe it’s time to be like, “Okay. You know what? I would prefer to do it this way, but I can see why you’re doing it that way, and why don’t we just revisit this, if we need to, when we have more information?”, right?

Sometimes, you’ll argue about code, for a while, and then it goes into production. Then you don’t touch it for six months. Which means, it was fine. Even if you didn’t think it was the greatest looking code in the world, like it was written, and it doesn’t have bugs that are obvious. It doesn’t need to be continually improved so, whatever, it’s fine.

If you can table the arguments you’re having until you have more information, and then kind of revisit them. Be like, “Oh, okay. I see now we have this bug, or we have this additional feature we need. I can see how that thing you said earlier, would be a better approach here.” That kind of thing. Waiting until you have more information to, really dig in again, is probably a good thing to do.

Recommended Resources

Derrick:

Can you recommend any resources for those wanting to improve the effectiveness of their code reviews?

Derek:

We have guides. If you go to github.com/thoughtbot/guides, there’s a bunch of guides in there. Some of them are like style, and protocol and things like that. But there’s also a code review guide in there. Whether or not you agree with everything in there, I think it’s a good example of something that I’d like to see more teams do. Where they provide, “This is what we write down, and agree to.” Then have pull requests against, when we want to change. What we think code reviews should be. How we think they should operate.

Every piece of feedback, should it be addressed? Yes, I think so. At least to explain, “Okay, I see what you said there, but I’m going to go in this direction instead.” That kind of thing. I’d like see more people take a look at that, and then adopt it for their team. Other things that can really help with code reviews, are style guides. Which we also have in that repo but, there’s also many community style guides. Just avoiding those arguments about, “Oh, I’d really like see you call …” Like in Ruby, we have map and collect under the same method, right?

Let’s be consistent. Let’s pick map, or let’s pick collect. Or something like, just writing that down somewhere, making that decision once. Rather than arguing about it on all pull requests, those types of things. That’s basically it. I’d like to see more people, get on board with and kind of documenting their experiences and, their expectations out of these things.

Derrick:

Derek, thanks so much for taking time and joining us today.

Derek:

Yeah, thanks for having me. It was good fun.

——–

Its extremely important to learn how to build a code review culture. Code reviews are great for code quality as they reduce errors, help deliver better code and encourage teams be more compassionate towards one another.

Refactoring to a happier development team

In this interview with Coraline Ada Ehmke, Lead Software Engineer at Instructure, we discuss data-driven refactoring and developer happiness teams. Coraline gives some great advice on the kinds of tests we should write for refactoring, tools to use and metrics to monitor, to make sure our refactoring is effective. We also learn about the role of refactoring in the Developer Happiness team at Instructure. You can read more from Coraline on her site.

Content and Timings

  • Introduction (0:00)
  • Useful Tests for Refactoring (0:57)
  • Data-driven Refactoring Metrics (4:13)
  • Winning Management Over to Refactoring (6:34)
  • The Developer Happiness Team (8:36)
  • Recommended Resources (13:58)

Transcript

Introduction

Derrick:
Coraline Ada Ehmke is Lead Engineer at Instructure. She is the creator of the Contributor Covenant, a code of conduct for open source projects, and Founder of OS4W, an organization encouraging greater diversity in open source projects. She speaks regularly at conferences about software development, including the talk ‘Data-Driven Refactoring’. Coraline, thank you so much for joining us today. Do you have any more to share about yourself?

Coraline:
I want to say I’ve been doing web development for about 20 years now, which is forever. I actually wrote my first website before there was a graphical browser to view it in. I started out in Perl, went into ASP for a little while, did some Java, and then discovered Ruby in 2007, and I haven’t looked back. All that experience has led me to be very opinionated about what makes good software. I have some very strong opinions that I’m always flexible about changing, but I have a sense of what good software looks like, and that sort of drives me in my daily work.

“A lot of problems come with code that’s just good enough”

Useful Tests for Refactoring

Derrick:
I want to dig into your experience with refactoring a bit. You say that without tests, you shouldn’t refactor. Why are tests so important to refactoring?

Coraline:
I think it was Michael Feathers who once said that ‘if you’re refactoring without testing, you’re just changing shit’. Basically, the importance of testing is you want to challenge and document what your assumptions are about the way that a piece of code works currently, which can be really difficult, because you might look at a method or a class name and assume its role based on its name, but that name could have drifted over time. You need to ensure that you’re documenting what you think it does and then testing to see that it does what you think it does. Testing can also help you stay within the guardrails through refactoring efforts. It’s hard to know where to stop sometimes, so tests can help you identify when you’re doing too much. You want to make sure you’re doing the minimum rework with the maximum results.

Derrick:
Yeah, that sounds great. It’s so easy with refactoring to just continue down that rabbit hole. What kind of tests are useful when refactoring?

Coraline:
It’s good to have good test coverage to start with, if it’s possible. If you don’t have good test coverage at the start, it’s good to build up some unit tests and integration tests just to make sure you’re staying on the path. There are a couple kinds of tests that I’m particularly interested in when it comes to refactoring. The first is boundary testing, which is basically using test cases to test the extremes of input. The maximum values, the minimum values, things that are just inside or outside of boundaries, typical values, and error values as well.

I like to do generative testing for this. If I have a method that takes an argument, I will create an enumerable with lots of different kinds of arguments in it, and see what passes and what fails. Those failures are really important because when you’re refactoring, you can’t know for sure that somewhere in the code base something is waiting for that method to fail or raise an exception. Your refactoring should not change the signature of that method such that a given piece of input stops causing a failure. You want to be really careful with that. Generative testing can help a lot with that, so there’s that with boundary testing.

Also, I like attribute testing, which is an outside-in way of testing. You check that after your code runs the object that’s being tested possesses or does not possess certain qualities. This can be really useful for understanding when you changed how an object is serialized or the attributes of an object without getting into the implementation details.

The most important tests, though, for refactoring are tests that you throw away. We’re hesitant. We love deleting code, but we hate deleting tests, because it gives us this feeling of insecurity. The sort of test that you do during refactoring doesn’t lend itself well to maintaining code over time. You’re going to be a lot more granular in your tests. You’re going to be testing things that are outside of the purview of normal integration or unit tests, and it’s important that you feel comfortable throwing those away when you’re done with a refactoring effort.

Derrick:
Yeah. The importance of being able to throw away stuff really gives you that perspective on what you’re trying to do.

Coraline:
And it lets you work incrementally, too. You can start by challenging your assumption about how a piece of code works. Once you feel confident, you can set up some boundary tests to see how it responds to strange conditions. Once you feel confident with that, then you’re probably confident enough to do some refactoring and make sure that you’re not introducing regressions.

Data-driven Refactoring Metrics

Derrick:
An important aspect of your approach to refactoring is data and measuring the impact of refactoring efforts over time. What are some useful metrics to track?

Coraline:
I want to emphasize that over time is really, really important, because if you’re not collecting data on your starting point and checkpoints along the way, you don’t know if you’re actually making your code base better or worse. It is possible through refactoring to make your code base worse. Some of the things I like to look at at the start are test execution times. If your test suite takes 45 minutes to run in CI, you’re not doing TDD. It’s impossible, because the feedback loop for your test has to be as short as possible. Refactoring tests is actually a great way to get started in trying to adjust that test execution time.

Another one that I’ll probably talk about later is the feature-to-bug ratio. If you look at your sprint planning, figure out how much time you’re spending on new features versus how much time you’re spending on bugs. You can actually use some tools to track down what areas of your code base are generating the most bugs, and combine that with churn to see what’s changing the most. Those are interesting.

I like to look at code quality metrics. A lot of people use Code Climate for tracking code quality, which I don’t really like that much, because it assigns letter grades to code. If a class has an ‘F’, you might say, “Oh, it needs to be rewritten,” or if a class has an ‘A’, you might think, “Oh, it’s perfect. No changes are necessary.” Code Climate doesn’t really give you the change over time. It’ll give you notification if a given class changes it’s grade. That’s great, but you can’t track that over time. I like some other code quality tools. Looking at complexity, there are tools that do assignment branch conditional algorithms to see how complex a piece of code is. I also like to look at coupling, because coupling is often a symptom of a need for refactoring, especially in a legacy application.

Derrick:
What mistakes do you see people making with refactoring?

Coraline:
Basically trying to do too much at once. It’s really easy to look at a piece of code and immediately make a value judgment, saying, “This is bad code,” which is really unfair to the programmers who came before, and saying, “I’m just going to rewrite the whole thing.” We have this instinct to burn it all down. Trying to change too much at one time is really a recipe for disaster. You want to keep the surface area of your changes as small as possible and work as incrementally as possible. Those things take discipline, and I think it’s hard for a lot of people to achieve that without actively policing themselves.

“The most important tests, though, for refactoring are tests that you throw away”

Winning Management Over to Refactoring

Derrick:
Often just getting the time to actually spend on refactoring can be a challenge. What are some benefits of refactoring that can win management over?

Coraline:
That’s a big, important question. I think in a healthy development organization, the development team, the engineers themselves, are stakeholders. They have some input into your backlog. If there’s technical debt that needs to be addressed, that can be prioritized. Not all of us live in a world where we have that kind of influence over the backlog. Some of the ways you can convince management that refactoring is a good idea… I talked before about the bug-to-feature ratio. Stakeholders want new features. New features keep products healthy and appealing to end users and to investors. Anything that stands in the way of a new feature getting out is necessarily a business problem.

If you look at your feature-to-bug-fix ratio and see that it’s poor, one way you can sell it is to say, “through this refactoring, we’re going to improve this ratio and be able to do more feature work.” You can also look at how long it takes to implement a new feature and talk about how refactoring a piece of code, especially if it’s code that changes very often, can make it easier to add new features to a particular area of the code base faster and easier.

In the end, if none of that works, just cheat. Just lie and pad your estimates, so you automatically build in some time for reducing technical debt with all of your estimates, which unfortunately I’ve had to use more often than I would have liked to. It is a valuable tactic to keep in your toolbox.

Derrick:
Yeah, definitely. I still really like… You mentioned this earlier, but the feature-to-bug-fix ratio is really important.

Coraline:
It really is a great health check for how the team overall is doing, what the code looks like and the health of the team, as well. If people are doing a lot of bug fixes, you’re probably going to have some unhappy engineers, because they want to work on new and shiny things. That can have an impact on how happy your developers are, which is really critical to how much work they’re getting done and how good your product is.

The Developer Happiness Team

Derrick:
Definitely. Let’s talk about happiness. You previously led what was known as the Developer Happiness or Refactoring team at Instructure. Tell us a little bit about the role and mission of that team.

Coraline:
It was one of my favorite jobs, honestly. We were charged with increasing the happiness and productivity of the engineering team. Within our charter was identifying processes or parts of the code base or even people who were standing in the way of developers being as productive as they could possibly be. Being very data driven in my approach, the first thing I wanted to do was get a sense of just how gnarly the code base was.

We ended up writing a bunch of code analysis tools. Again, we were using Code Climate, but I wasn’t really satisfied with its tracking ability over time. So we wrote a few tools. I wrote one called Fukuzatsu, which is an ABC complexity measurement tool. There was already a tool out there that was very similar called Flog that was written by Ryan Davis, but it’s an opinionated tool. It punishes you for things like metaprogramming, and it also favors frameworks like active record and punishes you for using alternative ORMs, so just in the nature of the bias that was built in. I wanted something that… I don’t want opinions with my data. I’m an engineer. I’m a professional. I’m capable of forming my own opinions. I just wanted raw data to work with, and that’s what Fukuzatsu gave me.

Another tool that we ended up building as part of this process at the very beginning was something called Society, which basically makes a social graph of the relationships between your classes. You get this nice circular diagram with afferent and efferent coupling displayed in different colors, and you see the links between different classes. That can help you identify service boundaries, for example, because if you have one class that’s a trunk of a lot of inbound or outbound connections, you might say, “That’s a good place for a service.”

A lot of the work we did early on was building tools. We built a mega-tool that collected data from all these other tools and presented them in a dashboard format with change shown over time. You could drill into complexity. You could drill into coupling. You could drill into code quality or code smells, or various other metrics, and see how they were changing at the commit level. That being done, we identified which areas were causing a lot of bugs, which areas of the code are really complex or really changing a lot.

The next step was creating a team of refactoring ambassadors. Rather than taking on the refactoring work ourselves and handing it over to the team that owned the code, our goal was to send in someone who’s really good at refactoring to work with that team to refactor the problematic code, which I think was pretty valuable in terms of ownership and continued success, and also training and teaching and helping those teams level up.

I think a lot of problems come with code that’s just good enough. I think we’ve all seen pull request bombs where someone had a bug to fix or had a feature to implement, and they went down a path that maybe was not optimal. By the time you actually saw it to do a code review, it was too late to suggest an alternative approach, because so much work had been put into it. You knew that you would just crush the spirit of whoever sent the PR. We end up with this lowest-common-denominator code. People also tend to copy and paste the approach that they’ve seen taken elsewhere in a class or elsewhere in a code base. Demonstrating to them that there’s a better way and there’s a better pattern you can follow is really important to maintaining code quality. That was the overall mission of the team.

Derrick:
Is that kind of focussed team something you’d recommend others try? What kind of impact did it have on factors like code quality and the developer happiness?

Coraline:
I think people appreciated that we were paying attention to engineering’s needs. We’d send out surveys to gauge how satisfied people were with the code that they were writing, with CI, with the test suite, with the overall process. We tracked it over time. I think engineers want to be listened to outside of the scope of just, “What are you building right now?”, or “What are you fixing right now?” They feel empowered when their needs are being addressed and when people are asking them questions about how they’re feeling and the work that they’re doing.

In terms of it being a full-time team, I think that really depends on the size of your engineering organization. Instructure has about 100 engineers, so it made sense to have a dedicated team doing that for a while. I think you could have an individual who’s charged with doing that as their primary job, and that would probably help, or have a team that’s a virtual team where you’re rotating people through on a regular basis.

There are different ways to approach it. I think the important thing is just gauging the health of your development organization and gauging the happiness of your engineers. That is going to have a significant impact on the quality of your code in the end.

Derrick:
You talked about all those tools for code quality, and they sound really great. How did you measure developer happiness? Was it talking to people, or…

Coraline:
Talking to people. We had a survey that we created that asked a bunch of questions about, “What do you think are the impediments to getting your job done? How good do you feel about the feature work that you’ve been doing? Are we spending too much time fixing bugs?” We published the anonymized results of those surveys to our internal wiki so people could go back and reference them, and we could use that to track how well we were doing as a team, as well. Again, just listening to people makes them feel better about things and gives them some hope that maybe change is coming.

“I think engineers want to be listened to outside of the scope of just, ‘What are you building right now?’”

Recommended Resources

Derrick:
Can you recommend any other resources for those wanting to learn more about effective refactoring?

Coraline:
I would suggest really getting to know what your testing tools are as a first step, and looking at some alternative ways of testing. Generative testing, for example, gets a bad rap, but I think it’s really a helpful technique to use when you’re doing refactoring. Looking at what people in other languages are doing in terms of their philosophical approach to testing is really important, and making sure that you’re really up to speed on what those different tools are so that you can be more effective in your work.

In terms of tooling, I would recommend a tool for Ruby called Reek, which is a code smell identifier that can help you isolate what areas you want to focus on. You can create an encyclopedia of code smells for your code base and refer back to that, and organize your work such that, “Oh, we’re going to address all the code smells that are of this kind,” and do that across the board. Really look at the tools that are available for your language in terms of code quality.

There are a few books that I recommend. The first is ‘Working Effectively with Legacy Code’ by Michael Feathers. The examples are written in Java, but the lessons that it teaches are applicable to any language. That’s a really good place to start. I work in Ruby, so I would also recommend ‘Refactoring: Ruby Edition’ by Jay Fields and Shane Harvie, and another book called ‘Rails Anti-Patterns’ by Chad Pytel and Tammer Saleh.

Derrick:
Those are fantastic resources. Coraline, thank you so much for joining us today.

Coraline:
Great, it was a lot of fun. Thank you for inviting me.

 

Originally published on www.fogcreek.com on October 2015

Don’t Set New Year’s Resolutions – Create Reusable Components

With the new year just around the corner, we’re entering the season of New Year’s’ Resolutions. Prepare yourself for overcrowded gyms and inspirational Instagram quotes tagged with #bigdreams.

If that’s not quite your style, I’d like to introduce you to a very different way of making progress on your goals: Component Thinking.

Instead of fixating on far-off, audacious horizons, Component Thinking has you focus your efforts on creating small, reusable components in the short term, knowing that you’ll be able to assemble them into something bigger in the future.

Digital work is made up of components

Every work product is made up of smaller parts, which I will call “components.” This is true of physical products, but it’s not very easy to take them apart and put them together in a different form. But for digital products, reuse is easy.

Any snippet of text can be copied and pasted anywhere else. Any image or video can be edited and uploaded to different places. And of course, a piece of code can be reused in different parts of a software program, or even in different programs.

Here are some simple examples of how to create reusable components:

  • If you create a lot of business proposals, make a proposal template you can use again and again
  • If you often design websites, start collecting web clippings of websites you like in a notes app
  • Instead of just updating your resume every few years, start collecting work deliverables you could show off in a portfolio
  • If you find yourself writing the same onboarding email multiple items, make it into a knowledge base article that you can reference with just a link
  • If there is a common customer service issue you have to deal with, record a 2-minute screen capture that you can upload to your website

These actions are valuable not just for one-time use, but for many possible future needs. A template for business proposals is inherently valuable, independently of any specific proposal. A notebook full of model websites could be useful in any kind of web design project. A portfolio is always a good thing to have, whether you’re applying for jobs or raising a round of funding.

Having many of these components ready and waiting gives you a few powerful benefits:

  • Each one gives you optionality, increasing the number of options you can consider
  • Each one helps you take action more quickly, because you can reuse past work instead of starting from scratch
  • Each one can remove uncertainty by testing assumptions, making future projects less risky
  • You can improve components incrementally over time, by tweaking and adjusting them each time you use them, instead of trying to make all the improvements at once

The modularity of digital work

The impermanence of digital work can often feel like a curse. Nothing ever seems to be finished. We rarely get to celebrate a clear-cut completion. But we can turn this curse into a blessing – if nothing is ever final, there’s no point in waiting to get started!

Instead of waiting until you have all the pieces in place, launch a basic version and upgrade it slowly over time:

  • Launch a beta version of your app, knowing that any component of it can be added later through software updates
  • Send out a draft of your blog post, knowing that you can update the text at any time
  • Self-publish an ebook on the Kindle platform, knowing that any update to the manuscript will automatically be synced wirelessly to anyone who has purchased the book
  • Publish a simple, one-page website with a photo and a bio, and add a new page every few months when you have extra time

Digital work is naturally modular – the various components that make up a product can be created at different times, evolve at different speeds, and be swapped in and out. We can take advantage of this modularity to make progress on our goals in small pieces, instead of in one huge leap.

Solving problems by making things

Most people solve problems through analysis, which means “separating” the problem into smaller parts. The way makers solve problems is through synthesis – by making things and testing them. There is nothing like a tangible thing placed in front of a real human being to bring a dose of reality forcefully into a project.

The best components are those that:

  • Answer questions or test assumptions
  • Simplify or speed up future projects
  • Make future decisions faster or easier
  • Need to be done anyway

People are often afraid to start on projects until they know they will succeed. But this is like waiting to cross town until all the traffic lights are green at once. It won’t ever happen. We have to make progress whenever and however we can.

By focusing our efforts on creating multipurpose, reusable components, we are preparing the ground so that we can quickly take action when an opportunity presents itself. Instead of waiting for the conditions to be just right, we are actively revealing assumptions, learning new skills, and preparing the resources we’ll need.

This new year, instead of setting a flashy resolution, try creating a reusable component.

Tiago Forte teaches people how to capture their knowledge, organize their digital life, and create reusable components, among other things, in his online course Building a Second Brain. Save $100 on the course using code FOGBUGZ (first 25 only).

We’re Bad At Interviewing Developers (and How to Fix It) Interview With Kerri Miller

In this interview with Kerri Miller, Lead Software Engineer at LivingSocial, we discuss how to hire and interview developers. We typically don’t get trained on interviewing and we’ve all experienced the haphazard approaches of those new to it – poor organization, repeated questions, fizz-buzz… Kerri tells us how to run interview days, the types of questions to ask, how else we can evaluate candidates and what to do after the interview. For more tips, Kerri writes about software development and hiring on her blog.

Introduction

Derrick:
Kerri Miller is a lead software engineer at LivingSocial. She is also a RailsBridge instructor and frequent conference speaker. She talks about software development and hiring, including the talk, ‘We’re Bad at Interviewing and How to Fix It’. Kerri, thank you so much for taking the time to join us today. Do you have a bit more to share about yourself?

Kerri:
I am actually, in fact, a lead software engineer at LivingSocial. Part of that is working with junior developers, or more junior developers, leading software teams and projects, and I also do a fair bit of work in our engineering culture team, so doing things like how do we propagate a good culture for code reviews, post-mortems, and hiring.

“You want them leaving the interview process regretful that they didn’t get hired, not resentful that they didn’t get hired”

What’s Broken with Developer Hiring?
Derrick:
What do you think is broken with the current way a lot of companies hire and interview?

Kerri:
We don’t do a really good job of hiring with intent. We decide that we need more people, but we don’t do a really good job of figuring out what we need those people to actually do, and who we actually need to hire. I like to think of my software teams as little ecosystems, little, tiny arcologies that exist in a bottle. They’re not entirely a closed environment, and, like any ecosystem, anytime you introduce anything new to that realm, there will be changes. There will be impacts.

Any time you hire somebody, you’re changing that ecosystem. You’re introducing a new species or a new variable to things and it’s going to change. Thinking about what you want to change means that you have to have laid that groundwork to understand where you are at the moment. A lot of teams and companies don’t do a really great job of understanding that. They’re just simply, “We need more bodies. Let’s hire bodies.” They don’t go into these things with a conscious sense of where they are and what they need, and how the future’s going to change by adding more people.

How to Structure and Run Interview Day
Derrick:
Let’s talk about the interview day. How should we structure it, and what are some key aspects you need to get right?

Kerri:
You need to go into it having a plan, and that plan starts with knowing what questions you’re going to ask and why. Understanding that every question you ask that a candidate can’t answer, or every step of that process is an opportunity for a candidate to filter themselves out of that process, it’s a point for you to get information to make that final decision. I think it’s really important that you take a look at what that plan is going to be. If you have, say, three people, and you’re hiring for a front-end developer, you should have one person ask about JavaScript. You should have one person ask about, perhaps, browser interaction, or working with designers, or what have you. Just splitting up that interview so that you’re not asking the same questions over and over again, you’re really able to get really solid signal on a person’s skill sets, what they’re comfortable with, and what their concerns are. What kinds of decisions are they making?

Good Types of Questions
Derrick:
What are good kinds of questions that we should be asking?

Kerri:
Well, I’m not a big fan of whiteboarding, because I think that’s something that we just automatically do, and we don’t think about, “Well, what questions are we trying to answer by asking a candidate to solve a problem?” Are we dinging people for trivia questions, for not remembering, “Oh, I need this third option flag or an obscure method from a core library.” Instead, I really want to focus on questions that are asking about decisions that they’ve made, what choices have they made, and what choices would they make again in the future? Are they reflective about mistakes that they’ve made? Are candidates looking for opportunities to improve, and how do they actually go about it? Do they make plans for themselves, like how they would improve a certain skill set, whether that be a technical skill set or a more soft skill set, for example, management, or project shepherding for example. Those are the kinds of questions that I think really get you at the heart of not necessarily what somebody knows, but what they’re capable of.

Beyond the Interview – How Else to Evaluate Developers
Derrick:
You’re a proponent of evaluating candidates in other ways than just an interview. How else should we be finding out more about potential employees?

Kerri:
I’m a really big fan of pairing on projects, like actually working with somebody. It doesn’t have to be a formal or traditional pair programming situation with one computer and two people, talking through the technical choices that they would be making as they programmed on something. At LivingSocial, we do a code challenge like a lot of companies do, using that as, then, a launching pad to have a discussion with a candidate to say, “You solved the problem using this technique. Why didn’t you choose this other technique? Why did you choose this one? How would you do it better? What if we sat down and refactored?” That’s one really good way to really get the heart of why are they making the decisions they’ve made? Not just did they make this choice because they didn’t know, or are ignorant, or did they make this choice because they had a certain belief about what the requirements of a given project were? That’s one way to do it.

Other ways you can be finding out more about potential employees … I’m a really big fan of asking the employee to explain something to me or teach something to me. In the past, we’ve done this with simply just saying, “You can teach me anything, something that I don’t know, and preferably is non-technical.” How well do they communicate about something that they’re a local expert in but they’re intended audience is not? Could they then go off and go and learn a new framework, or go have a meeting with, perhaps, a stakeholder, or a client, and come back and explain what the actual requirements are to me, to distil down what I need to know and communicate that well? Communication is such a big part of what we do in this job, and so testing for that essential skill in a really clear and explicit way can be really useful and get you a really good signal about who that candidate is and how they’re going to fit into your organization.

“We don’t do a really good job of hiring with intent”

After the Interview – Making the Hiring Decision
Derrick:
After the interview, what are key things that employers should be doing?

Kerri:
I think it’s really important that we don’t just say, “We’re going to get back to you,” but to say, “We will get back to you by Thursday, end of the day.” Then, if you can’t make your decision within those three or four days, communicating that to the candidate so they have expectations that you can meet, because it’s not just good for the candidate, it’s good for you as a company to have that discipline, because you want people to, whether you hire someone or not, you want them leaving the interview process regretful that they didn’t get hired, not resentful that they didn’t get hired. Being professional and upfront and just friendly and encouraging about the entire process is great.

I try always to make sure that, if we can’t hire somebody for whatever reason, we make sure that we give them constructive advice or feedback afterwards, or at least make that available. If you did like somebody, if it came down to either Joe or Mary, and you hire one or the other, keep that person on file, and follow up with them in a few months to see how are they doing, what’s going on? “Hey, we have an open position, would you like to re-apply, or would you like us to consider you for that?” That gets into the part of how you keep metrics on things as well because if you didn’t hire somebody, figure out why you didn’t hire them and then follow up and see, are they actually doing that work, and did we hire the … Not necessarily the wrong person, but did our process let us down? If you assume that somebody didn’t know anything about, say, SQL, and now they’ve gone on to work on a SQL-heavy project, for example, what in our process missed that step?

“It’s really hard to look at who you hire and decide that you have a good or bad process. But you can look at who you don’t hire.”

Derrick:
Great, so we talked about having a plan as part of the hiring process, what’s a good process to follow to make a hiring decision?

Kerri:
When you split up the interview topics, the questions you’re going to ask, and you’re going to consistently ask all of your candidates, it feels a little bit like reading a script, but it really lets you compare apples to apples as much as possible. Once you’re done with your little section of the interview, you should immediately go back to your desk and not get back to work but write down what your impressions were. What were the pros and cons, the bullet points, and find something good about the candidate and something not-so-good about the candidate, something that you wish they did have? Doing that at that moment and passing that back to a central person so as not to … Don’t pass it back to a group, pass it back to a central person, whether that be an HR or the hiring manager, to collect that, so you’re not coloring the impressions of other people.

When you get back into that room with everybody else, whether it’s virtual or real, to really discuss your opinions, you’ve got your opinions of the moment and you can’t be swayed by the impressions of somebody else. For example, if you were supposed to interview them about JavaScript, and the senior JavaScript person, who’s got twenty years of experience in JavaScript, just really did not like that person, how would that color your opinion if you had to give your opinion in that moment? If you wrote it down previously, no, this person really is good at JavaScript, then you’ve captured that honestly and you can really give honest feedback about what that person’s qualities are and what their strengths are without being colored by other people in that discussion.

Measuring and Improving Your Hiring
Derrick:
You hinted at this earlier, but a key part of your approach to hiring is measuring the process to improve it. How could we go about measuring the effectiveness of our hiring?

Kerri:
It’s very seldom that we ever hire anybody bad. When you hear horror stories about hiring, it’s always somebody else’s team that hired that one jerk, or that one idiot, so it’s really hard to quantify because now we know that person, and we’ve worked with them, and we understand their strengths and their weaknesses. It’s really hard to look at who you hire and decide that you have a good or bad process. You can look at who you don’t hire. You can look at that in terms of what were the false negatives? Did we bounce this person out of the process for a specific reason and then it turns out that that reason wasn’t good based on where they ended up going to work?

It’s really easy to LinkedIn stalk people, and peak into their GitHub profiles if they’re doing that sort of work, to see what they’re doing a few months later. It can be really useful to, four, or five, six months down the road, go back and look at the candidates that you passed over and see what they’re doing to understand, if you keep records of the questions that you ask, and the reasons why you maybe didn’t hire somebody, to see if those reasons are still valid.

Other metrics that I think are really, really important to an organization are understanding what your pipeline for candidates consists of. At each step, you have a certain amount of leakage, because people just simply don’t make it through the process or they abandon the process, they disappear. How many people are you losing at each step, and is there one step that you’re losing a lot of people at? Maybe you need to refine that step, remove it, or move it earlier or later in the process based on what your organizational needs are. I think it’s also important to look at who you’re losing as well. Are you losing junior developers at a step that you really don’t want to be losing them at? Are you losing more diverse candidates? Are more women abandoning your process at a certain step than men are, and understanding, or questioning at least, your process to see, is that a problem? Can we fix it? How do we fix it?

“You should immediately go back to your desk, and not get back to work, but write down what your impressions were”

Common Developer Hiring Mistakes
Derrick:
What are some common mistakes you see companies making when hiring developers?

Kerri:
Some of the more common mistakes are hiring from our friend networks. I think that the friend network is such an important part of how we get jobs, but it also tends to reinforce our monocultures a little bit. We tend to be friends with people who are mostly like us, and so those are the people that we’re going to be recommending, and so those are the ones that get hired more often. When I was mentioning earlier how the team is an ecosystem, it’s important to have some diversity there, and not just the diversity we talk about in terms of gender or ethnicity or race, but age, class, looking at people’s technical backgrounds, do they come out of CS programs versus being a self-taught or a boot camp?

Industry backgrounds, did they work in, perhaps, consumer electronics testing before they became an SDET at Microsoft? Were they at startups versus large enterprise companies, or somewhere in between? All those pieces of diversity are going to be influential and improve the health of the ecosystem of your team, and so those friend networks are important for getting candidates in the door, but understanding that that sometimes is going to lead to a certain amount of self-selection for candidates.

You have to, like in soccer, they say, “Run to where the ball will be, rather than where the ball is.” If you have those early conversations about who you need to hire, and what you want to look for, what sort of energy and person do you want to add to your team, to influence it into a good direction? And then go to those people, find them, whether it be through meetups or user groups, or extending your extended network, not just your immediate friend network.

Derrick:
Are there any other resources you can recommend for those looking to improve how they hire developers?

Kerri:
Looking at the different boot camps you’re doing, and how they’re talking to their students, as well as to their sponsoring companies, or the companies that are hiring. I’m a really big proponent of hiring more junior developers, because no one is ever going to know our exact technology stack and our exact way of working, we always have to teach people, so looking at what those boot camps are doing, and how they’re talking about the industry, because they’re trying to set people up for success over the next five years. There’s a lot of wisdom. They’re spending a lot of time to gather wisdom that they can relate to us about who we should be hiring over the next five years, and what skills we should think are important.

Finally, I tell everybody this, go take a relationship skills class. Although they’re sold as being aimed at couples, a lot of that is really about listening to other people and understanding what their concerns are. Once you can start to build those sorts of skills for understanding the perspectives of other people, just generally improves everything about your hiring process, and your team, and how you work with each other.

Derrick:
Kerri, thank you so much for joining us today.

Kerri:
I’m really excited about this topic. I’m glad to see more and more people talking about it. There’s no one size fits all solution. We all face some really unique problems, but there are some commonalities.

9 Effective Code Review Tips

9 Code Review Tips

For everyone:

  • Review the right things, let tools do the rest

You don’t need to argue over code style and formatting issues. There are plenty of tools which can consistently highlight those matters. Ensuring that the code is correct, understandable and maintainable is what’s important. Sure, style and formatting form part of that but you should let the tool be the one to point out those things.

  • Everyone should code review

Some people are better at it than others. The more experienced may well spot more bugs, and that’s important. But what’s more crucial is maintaining a positive attitude to code review in general and that means avoiding any ‘Us vs. Them’ attitude or making code review burdensome for someone.

  • Review all code

No code is too short or too simple. If you review everything, then, nothing gets missed. What’s more, that makes it a part of the process, a habit and not an afterthought.

  • Adopt a positive attitude

This is just as important for reviewers as well as submitters. Code reviews are not the time to get all alpha and exert your coding prowess. Nor do you need to get defensive. Go into it with a positive attitude of constructive criticism and you can build trust around the process.

For reviewers:

  • Code review often and for short sessions

The effectiveness of your reviews decreases after about an hour. So putting off reviews and doing them in one almighty session doesn’t help anybody. Set aside time throughout the day including breaks not to disrupt your own flow and help form a habit. Your colleagues will thank you for it. Waiting can be frustrating and they can resolve issues quicker whilst the code is still fresh in their heads.

  • It’s OK to say “It’s all good”

Don’t get picky, you don’t have to find an issue in every review.

  • Use a checklist

Code review checklists ensure consistency – they make sure everyone is covering what’s important and avoid common mistakes.

For submitters:

  • Keep the code short

Beyond 200 lines, the effectiveness of a review drops significantly. By the time you’re at more than 400, they become almost pointless.

  • Provide context

Link to any related tickets or the spec. There are code review tools that can help with that. Provide short but useful commit messages and plenty of comments throughout your code. It’ll help the reviewer and you’ll get fewer issues coming back.

9 Integration Testing Do’s and Don’ts

Integration tests check whether your application works and presents properly to a customer. They seek to verify your performance, reliability and of course, functional requirements. Integration tests should be run against any of your developer, staging and production environments at any time.

Writing good tests proving your solution works can be challenging. Ensuring these tests to perform the intended actions and to exhibit the expected outcomes requires careful thinking. You should consider what you are testing and how to prove it works – both now and in the future. To help you create tests that work and are maintainable, here are 9 Do’s and 9 Don’ts to contemplate:

When Creating Integration Tests Do…

1. Consider the cost vs. benefit of each test

Should this be a unit test? How much time will it save to write this test over a manual test? Is it run often? If a test takes 30 seconds to run manually every few weeks, taking 12 hours to automate it may not be the best use of resources.

2. Use intention revealing test names

You should be able to figure out or at least get an idea of what a test is doing from the name.

3. Use your public API as much as possible

Otherwise, it’s just more endpoints and calls to maintain when application changes are made.

4. Create a new API when one isn’t available

Rather than relying on one of the Don’ts

5. Use the same UI as your customers

Or you might miss visual issues that your customers wouldn’t.

6. Use command line parameters for values that will change when tests are re-run

Some examples include items like site name, username, password etc.

7. Test using all the same steps your customers will perform

The closer your tests are to the real thing, the more valuable they’ll become.

8. Switch your system under test back to the original state

Or at least as close to it as you can. If you create a lot of things, try to delete them all.

9. Listen to your customers and support team

They will find ways to use your systems that you will never expect. Use this to your advantage in creating real-world beta tests.

When Creating Integration Tests Don’t…

1. Write an integration test when a unit test suffices

It’ll be extra effort for no benefit.

2. Use anything that a customer cannot use

Databases, web servers, system configurations are all off limits. If your customer can’t touch it, your tests have no business touching it either.

3. Access any part of the system directly

Shortcuts just reduce the quality of your tests.

4. Use constants in the body of your tests

If you must use constants, put them in a block at the top of your test file or a configuration file. There is nothing worse than having to search through all your source files because you changed a price from $199.95 to $199.99.

5. Create an internal-only API

Unless necessary for security or administration.

6. Create an internal only UI

You’re supposed to test what the customer will see after all.

7. Make your test too complex

No matter how brilliant your test is, keep it simple. Complexity just breaks later. If you are finding it hard to write, it will be hard to maintain too.

8. Test more than one thing

Stick to what you need to test. If you try to do too much in one test, it will just get more complex and more fragile.

9. Leave the test system in a bad/unknown state

This means a broken or unusable site, database or UI.

 

A Guide To Open Sourcing Your Project at Work

Congratulations! You’ve written something at work that is amazing and you want to share it with the world! This guide covers three key areas that you should consider before making the leap: Why, when and how to do it.

Why Should I Open-Source My Work Project?

Open-sourcing your project at work can be a great idea. It can:

Help you build a developer-friendly brand

  • From those with a developer-focused product, like Stripe and Twilio, to those with APIs, like Facebook, Google and Square. Open-sourcing your code can be a good way to build your company’s relationship with developers.

Allow you to give back to the community

  • Just think of all the libraries and software you use on a daily basis that make use of open-source code. Adding your own is a good way of paying it forward so that others can benefit from your contribution. We’ve open sourced a number of libraries and even whole products.

Help you to recruit

  • Take Yahoo and LinkedIn for example. They’ve found that through their commitment to Open-Source projects (like Hadoop and Kafka), that they’ve been able to encourage developers to join them who otherwise might not have.

Gain more contributors than your project ever would have in-house

  • Like for example Square’s Dagger, a dependency injector for Android and Java. Having released it, many developers are contributing to it, including those at Google. In fact, Google developers have been contributing more than Square’s developers do themselves.

When Should I Open-Source My Work Project?

There are two conditions that you would want to meet before open-sourcing your project. You want to make sure that:

It won’t hurt your business

  • It may be an impressive, complicated bit of code that would be useful for other products beyond your own. Yet if that development is your secret sauce, then giving it away would be bad for the business. Likewise, if your library is an integral part of what makes your product unique or even what makes it possible, then you might want to keep it in-house.

Your code is helpful to others

  • Consider whether anyone else would actually want what you’ve created. Is it so uniquely tied to your workflow or infrastructure that it wouldn’t be useful for others? As a rule of thumb: if making it suitable for general consumption would make it less useful for yourself, then it’s probably not worth the effort.

Ok, so you’ve met those two requirements. Then let’s move to the mechanics of open-sourcing some code.

How Do I Open-Source My Work Project?

Step 1: Audit your code for security leaks

  • Chances are higher than you might like to admit that you or a colleague have left some passwords, usernames, IP addresses, machine names, personal contact information or other security hazards somewhere in your code. Keep in mind that this applies not only to your final master code but also to all the changesets you’ve had in the past.

For that reason, we recommend you do two things:

1. Make a brand-new repository
  • Chop off all the history of the code up to that point. There will be a new history and it saves you having to audit all the historical versions of your code. Plus, no one needs to know that it took you two weeks to wrap your head around C++11 lambda syntax.
2. Audit the code for security problems
  • This will take a lot less time than you think. Look especially at test suites and any places that are near connection points to other systems.

Step 2: Strip your code of profanity and immature pot-shots

  • While you’re in there, also rip out anything inappropriate that makes you sound more like a teenager than a professional. This doesn’t mean you can’t have any humor in your source code. But it does mean that jokes made at the expense of your competitor, a customer or the decrepit browser you’re forced to support might not be appropriate.
  • If in doubt, think about whether you’d feel comfortable reading your code loud to those beyond your team.

Step 3: Make sure your code adheres to best-practice naming and formatting

  • You’ll want your open-source code to be examples of your best work. Make sure you are using good, standardized naming conventions and formatting. Use tools like pyflakes/pep8, jslint, gofmt, ReSharper and others to help.
  • Also, keep in mind that if you’ve been wanting to do the One True Naming Standardization for your project, now’s a good time. Once you open-source your code, there will be a lot of inertia to avoid breaking changes. Get those done before you release. It’ll also make it easier for other contributors to get started with your code.

Step 4: Document it

  • You don’t have to write ninety pages of info docs but you should at least have a nice Markdown-formatted README.md in your root directory that explains what your software is, how to use it, and (if applicable) how to build it.
  • If you’re releasing a library, you should also make sure your code has docstrings/JavaDoc/whatever so that you can generate API documentation.

Step 5: License your code

  • You may want to get some proper legal advice on this. But before releasing your code, you should pick a license. Unless you have a compelling reason to do otherwise, the MIT license will probably suffice. It’s short, sweet, well-understood, liberal and makes integrating third-party changes back into your own products headache-free. But if you’re contributing to the code that you want to include in a project that already has its own license, you might want to use that license instead. Here’s a useful overview of license types for more info.
  • You’ll want to put a LICENSE file in your repository and have a copyright notice somewhere prominent — either in that file or in the README. Such as ‘(C) 20XX Your Name. All rights reserved.’

Step 6: Name your library or tool

  • Pick a name. Make sure it’s not offensive and avoids having the same name with other existing libraries and trademarked products.

Step 7: Push your code

  • Put it on GitHub, create your own organization, repository and push your code.
  • Keep in mind that some communities have secondary systems that you should consider utilizing as well. If you’re writing .NET, then another one might be Codeplex. If it’s Ubuntu-specific then a Bazaar mirror on Launchpad etc.

Step 8: Publish your package in the appropriate package archive

  • If you’re publishing a library, submit it to the appropriate package manager. For .NET, that would be NuGet; for Python, it’s PyPI; for Perl, it’s CPAN; for Ruby, it’s RubyGems; for Node, it’s NPM; and so on. Also, make sure that someone else at your company, such as a sysadmin, has the ability to continue maintaining the library under the unfortunate circumstance that you get hit by a bus.

Step 9: Announce your code

  • You’re all good, time to announce it! You’ll want to blog and tweet it out. You should also consider publishing on /programming on Reddit and Hacker News etc.

And that’s it! You’re all done!

…well, nearly.

Step 10: Don’t forget about your code

  • Just because you’ve published it doesn’t mean you’re done. You’ve unleashed a new-born into the world; you need to take care of it. Monitor pull requests and bug reports on your new project. If you realize that keeping your project going is overwhelming, then a hearty congratulations! You should remember that it is your responsibility to at least find an extra or substitute maintainer. It’s okay if your project ultimately forks but it’s best not to do so just because you dropped the ball incorporating freely and submitted improvements to your code.

That’s it. For real this time. So go out, contribute, and have fun!

Taming A Wild, Testless Code Beast and  4 Steps To Improve Test Coverage

Whether you’re working on an existing or new application, you’ll often find yourself playing catch up when it comes to tests. Soon deploying code changes feels like poking at some ugly, sleeping code monster — you aren’t sure what’s going to happen, but you know it won’t be good.

Here are the 4 things you should do first to tame the beast and improve test coverage:

1. Add the Right Tests

Start by adding tests in the areas where it is easiest. It’s important to consider the order in which you do this to make sure you get the most out of your scarce resources. You want to start adding tests in the following order:

  • i. Create tests as you fix bugs

Add tests to prove that your specific fix is working and keep them running to show that this does not break again. This prevents from being somewhat targeted — you are creating tests in your weakest areas first. The weaker it is (i.e. more bugs) the faster you will build up tests.

  • ii. Create tests with all new features

All new features will need to include tests created to prove that the feature works as expected. If you’re covering the new aspects of your application, then at least things aren’t getting worse.

  • iii. Create tests as you add to old features

When updating old features, add tests as you go to show that the older functionality is not breaking in unexpected ways.

  • iv. Create tests in identified risk areas

Talk to the developers and testers on your team and ask them to point out any weak spots or issues they have experienced. Also, you talk to your support team — they are an excellent resource with a direct line to the customer. They’ll know the features of your product that frequently causes issues.

2. Turn on Code Coverage

Code coverage is a tool included in most continuous integration systems (or one that can be added with a plugin). This tool will instrument and monitor your code as you run the tests to determine how much of your code used by the tests. For this to be useful, follow these steps:

  • Start running code coverage against all your code
  • Get a baseline

Find out what the tool can see, where you are currently at etc.

  • Determine areas that you want to exclude.

There are likely areas of your code that you don’t want to cover — third-party tools, ancient code untouched for years etc.

  • Determine coverage goals

Sit down with your team and discuss what your current coverage is and what your ideal can realistically be (usually 90% or above).

  • Work-out steps to improve your coverage

You aren’t going to fix this problem overnight. Put in place some specific tasks which are going to help you achieve your goals over time.

  • Determine your pass/fail criteria

Is staying the same OK, or should it always go up? Do you define any drop as a fail?

  • Run Code Coverage constantly

Use automation to run your coverage test and use the criteria you determined as a team to report a pass/fail and do this constantly. It is a lot easier to add tests when the code is still front and center in your mind than later on.

3. Run your Tests on a Scheduled Basis

You should run your tests regularly, on several schedules:

  • Run them on every check-in

Use CI tools like Jenkins to run (at least) your unit tests on every check-in. Run them simultaneously if they are taking too long to run at this frequency.

  • Run them on every build (package)

Depending on how your systems work, your CI infrastructure can help you with this. This could be on every check-in if you are on Continuous Deployment, or every day/week/month that you use. This should be a clean install on a test environment and a full run of all your automated tests.

  • Run them on every deploy

You should run all your automated tests against your environments immediately after a deploy.

  • Run them every X days/hours/minutes

Run your automation suite against your constant environments as often as you can (Production, Staging etc). This should be at least a “once a day task” and take place during ‘off-peak’ times when it does not interrupt others too much. You can increase the frequency further if your tests are short, just be mindful not to overload the system.

4. Provide a Button to Run the Tests

Again, use a tool like Jenkins to turn test runs into a self-service operation. A developer should not be delayed by asking a QA person to run a test for them. Get a system in place where your tests will run and just give them a button to press. Remove as many barriers for everyone to run the tests as possible.

If you follow these steps, over time, you’ll see that you are able to turn an unwieldy application into something more manageable. First, by adding tests to the key areas, then making things as easier as possible, you can build confidence around your code changes and deploys.