Much has been said recently about companies like Github, Valve, and other places that create these open corporate cultures of empowerment where employees can do pretty much whatever they want. This manifests itself in many different ways, from allowing employees to work where they want when they want to allowing them to even decide what they want to work on and not limiting their time off. A great example of this is Valve’s new employee handbook. Stop reading this post and go read the handbook, it’s worth the read.
Hey, welcome back. How do you feel after reading something like that? It gets you a little excited, doesn’t it? Personally, I love the idea of getting to move my desk wherever I need to, or being able to decide what I want to work on. In a place like that, there’s no limit to what you are able to accomplish. You are only limited by your own abilities and time.
Let’s be honest though, most of corporate America can’t be as free wheeling as a video game company. When I go to work, I’m doing work for people who tell me what project to work on, and they get to decide what projects are most important to them. That’s the nature of the company that I’m working for, and there’s nothing wrong with that.
I care more about the principles behind these empowerment cultures. The main theme that I see is that they hire awesome employees and then let them be awesome. How many times do you hear about developers who feel like that can’t be as successful because their team lead or manager won’t let them use a certain technology or framework or technique? Maybe those people feel like their control is doing good (and maybe it is), but the trade-off is that they are stifling their top performers. In that case, the side effects might be worse than the perceived decrease in risk.
Since most companies don’t have an empowerment culture, there must be a reason.
It is really hard for people in control to give up control. Say you’re a manager, and your lead developer comes to you and says that he wants to use MongoDB instead of SQL Server on his new project. Immediately you think of reasons why it’s not a good idea (Our infrastructure team doesn’t know how to host it properly! Our DBAs don’t know how to use it! What about reporting?). Those are all important questions that need to be answered, of course, we don’t want to be reckless. Ultimately it comes down to a choice – you can choose the safe option (SQL Server), or the more unknown (MongoDB) which might have some new challenges that you need to work through, but also might provide developer productivity increases, better application performance, and increased morale of the team.
If you don’t let top performers be top performers, why do you have them? If you stifle them, you are losing out on one of the main reasons you have them in the first place! If it lasts long enough, they will leave and try to find another place where they might be able to use their skills.
It takes a lot of guts for a manager to give up control. If that manager were to let his developer go ahead with MongoDB, that would take a lot of trust. He’s basically putting the project at risk (maybe not really, but in his mind) and placing a lot of trust in his development team. And you know what, it might fail.
But let’s be honest, if we can’t trust our development team, why do we have them? Why don’t you just get rid of them and have the managers and architects do the work? Are they really the only ones who can be trusted to make big decisions, and even small decisions?
Employees that live in a culture of control often live in fear. These cultures often try to remove risk because failure is seen in such a negative light. As a result, you can’t try new technologies (because it might fail), you have to use the approved enterprise development frameworks (so that we use something that we know has worked last year), and heaven forbid you say the “A” word and want to implement agile practices (because the project managers don’t have as much control). This may keep some projects from failing, but it pretty much guarantees that every project will be sufficiently average.
Do you want to work in a place like this? I don’t.
In a culture of empowerment, you have the freedom to try new things. And since some of those things won’t work, you also have the freedom to fail. When it does work, we all win, and when it doesn’t work, we learn something so that we are better next time. But everyone wins when it comes to that feeling that you get when you go to work believing that you can change things for the better and that you can make a difference. Now I truly have responsibility, because I’m responsible for the success of something and I will be held accountable for my decisions. But this just motivates me to do better.
That freedom is what really gets people excited. When you don’t feel like you have anything holding you back, your mind is free to dream of anything, including those crazy ideas that might actually work. This is incredibly motivating, because now we’re only limited by our team’s abilities and time.
There are certain types of people who tend to prefer empowerment cultures. The ones who don’t like it are the ones who want to play political games, have a bad attitude, and are afraid to try new things because they are afraid they might fail. The ones who like it are the innovators, the people who embrace change, the motivated, the top performers. These people don’t just value a salary, they value autonomy, mastery, and purpose. Every company tries hard to recruit these people, but few realize the importance of the empowerment culture.
I read an interesting article in the Wall Street Journal the other day about “Must-Have Job Skills in 2013″. While this wasn’t necessarily referring solely to technical fields, it was still interesting. Here is their list of must-have job skills:
- Clear communications
- Personal branding
- Productivity improvement
It made me think of the software craftsmanship people and the importance that they place on things like code katas, learning new languages, etc. If you’re a developer and you spend time honing your craft, how much value are you placing on skills like:
- Being able to write a good requirements document
- Facilitating a requirements gathering session with business users
- Giving demos of your software to users (in their language)
- Coming up with estimates for a large set of functionality
- Being able to evaluate tools and frameworks and choose the best one for your project
Admittedly, it’s much easier to practice TDD than it is to practice requirements gathering. But these are skills that I feel are very important for developers. There are lots of people who can write code, even good code. If I don’t know how to use a language or framework, someone can teach me pretty quickly and I’ll pick it up. But can you also pitch in and help with requirements gathering, test planning, system architecture and design, and everything else that needs to be done on a project? Now that will set you apart.
When you think about learning new skills and investing in your career, just make sure that you don’t limit that to tools and technology.
Time is one thing in life that will always remain constant. You can acquire more knowledge or more money, or you can save today’s money and use it tomorrow. But you only get 24 hours a day, and you can’t carry them over to tomorrow.
Most people would agree that there are not enough hours in a day. There are plenty of things I would like to do, books I want to read, projects that I want to work on, that I just don’t have the time to do. The challenge is figuring out how to make sure that you’re spending your time on the things that are important to you.
Know your priorities
If you don’t know what your priorities are, you won’t know how to prioritize your life. That sounds obvious, but it’s really hard to actually do. Many people don’t really know what their priorities are, let alone how to execute on them.
Do what’s important first
Something or someone will fill your day if you won’t. Personally, I hate the days where I feel like I didn’t get anything done that I wanted to get done because I was constantly reacting to things that came my way. Sometimes this is inevitable, but you can control it. For example, I expect that I should have at least half of my day available to do work (i.e. not stuck on meetings), so when a day is half full, I block out the rest of it so that no one can schedule me for a meeting. I do that because I need that time to accomplish what I feel is important and what people are expecting me to accomplish.
Live out your priorities
People are a priority to me, so if someone wants to go to lunch, I may or may not have time for that, but I usually go anyway and then find a way to everything else in around it. I have other friends who will go out of their way to make time to eat lunch when they’re really busy. That shows me something – that I’m valuable enough to be made a priority in their life. I love that.
My team is also a priority for me. This goes back to shunning meetings. I feel that in my current role, it’s more important for me to be with my team than to sit in a meeting with people from another team, so I block off my schedule and try to get out of meetings if I don’t feel that it’s valuable for me or the meeting organizer. (Sometimes people like to schedule 30 minute meetings for things that could be solved with a 10 minute hallway conversation.)
Own your life
I want to control my life and time as much as I can. I don’t want my life to control me because then I’m not able to do the things that I feel are important. The more proactive I am, the more likely I am to succeed at this.
We had a week-long debate awhile back about whether or not it’s OK to modify your production code in order to enable automated acceptance testing. I’m not talking about using dependency injection, interfaces, etc. to allow you to mock things in unit tests. I’m talking about modifying application code solely to help your automated acceptance tests.
There are many ways this can be done, some of which we’ve done:
- Creating a SystemTime class, which is like DateTime except that we can set what “Now” is, so we can change time in tests
- Adding optional parameters to stored procedures solely so that we can have them only operate on a subset of data in an acceptance test instead of operating on the entire set of data in the database
- Adding extra HTML attributes so that automated tests can find elements on a page easily
To me, modifying production code to help us do automated testing is no big deal. First, if our goal is quality, I don’t think it matters how we get there. After all, we own the code base and tests so there aren’t any real restrictions on what we can do with the code or the tests as long as the end product is good.
Second, developers and QA are on the same team, and we work together quite closely, so we should do what we can to help each other out. So if we can make a minor change to the application code to save us a lot of time developing or running automated tests, then to me it makes sense to do so.
This goes back to my assertion that we need to stop thinking of QA like external auditors that have to take the application just as it is without talking to the developers and act as the independent quality police. We need to all work together to ensure quality, both developers and QA. Developers are just as responsible for quality as QA. If we place all of the responsibility for quality on QA, then developers will care less and less about quality, and you end up with shoddy code with lots of bugs (and usually no tests). I’d rather treat testing as a whole-team activity and structure the application to make testing as easy as possible.
Lately I’ve been thinking about a whole team approach to testing, where we decide as a team how features will be tested and where we use the skillsets of the whole team to automate testing. We do this on our project, and this has led to a regression testing suite of ~2500 SpecFlow acceptance tests that automate almost all scripted QA testing and regression testing for our application.
We didn’t always do this. Originally there was no automated acceptance testing, but developers were diligently writing unit tests. Those unit tests are still around, but we don’t write many unit tests anymore. We start with acceptance tests now, and the acceptance tests cover all of the testing scenarios that need to be covered. Our application has well-defined design patterns that we follow, so the idea of TDD driving the design of our code doesn’t really apply. If the unit tests fail, we often just delete them because it’s not worth fixing all of the mocks in the unit tests that are causing them to fail, and we have acceptance testing coverage around all of it.
This approach does not line up with the conventional wisdom on automated testing. They say that you’re supposed to write lots of unit tests that run really fast to give you fast feedback, help design your code, and ensure the internal quality of your code. In the past, this is how I’ve always done it. In fact, many of them dislike Cucumber.
Cucumber makes no sense to me unless you have clients reading the tests. Why would you build a test-specific parser for English?
— DHH (@dhh) March 29, 2011
While TDD isn’t as mainstream as I would like, TDD is nothing new. Kent Beck was writing about it 10 years ago, and the original XP guys valued such things as unit testing, the SOLID principles, and things like that.
Automated acceptance testing still feels like a relatively new phenomenon. I’m sure people were doing it 10 years ago, but back then we didn’t have Cucumber and SpecFlow and the Gherkin language. Now I see a lot more people using tools like that to automate QA testing in way that uses business language and more maintainable code, rather than the old “enterprise” solutions like QTP.
Here’s what I’m getting at – I wasn’t there 10 years ago when Kent Beck was writing his books and the XP movement was starting, but it seems to me to be primarily an effort by developers to ensure the quality of their code through the effort of developers. I see very little talk of where QA fits into that process. There is some mention of QA for sure, but the general gist seems to be that developers need to write tests in order to ensure quality, and the best way to do that is to write unit tests. QA people typically don’t say that unit testing is enough because it doesn’t test end-to-end, so then what do they do? Manually test? Use QTP?
My question is this – if we think of testing as whole-team activity and not just a QA activity or a developer activity, will we arrive at the same conclusions as we did before?
I’m not ready to discount unit testing as a valuable tool, and I’m also not ready to say that everyone should do it my way because it worked for us on one project. But we have largely abandoned unit testing in favor of acceptance testing, and other teams in our department are doing it too. I write unit tests for things like extension methods and some classes that have important behavior on their own and I want to ensure that those classes work independent of the larger system.
We have 3 Amigos meetings in which one of the things we do is develop a set of acceptance tests for a feature before any code is written. We usually decide at this point (before any code is written) that most or all of these scenarios will be automated. We write the acceptance tests in SpecFlow, I watch them all fail, and them I write the code to make them pass. I follow the patterns and framework that we have set up in our application, so there aren’t many design decisions to make. When my acceptance tests pass, I am done.
Where do unit tests fit in there? If my acceptance tests pass, then I’m done, so why spend more time writing duplicate tests? Also, with acceptance tests, I’m not dealing with mocks, and more importantly, I’m not fixing broken unit tests because of broken mocks. If you follow the Single Responsibility Principle (which we try to do), you end up with lots of small classes, and unit tests for those classes would be mostly useless because those classes do so little that it’s hard to write bugs and each class does such a small part of the larger activity.
There is an obvious trade-off here – my acceptance tests are not fast. I’m just testing web services (no driving a browser), so all ~2500 tests will run in about an hour. But we accepted this trade-off because we were able to get things done faster by just writing the acceptance tests, which we were going to do anyway to automate QA testing. The end result is high quality software with few bugs, not just because we have tests, but also because we communicate as a team and decide on the best way to test each feature and what it is that needs to be tested, and then we find the best way to automate the testing as a team.
Again, I’m not ready to say that this way is the best way for every project, and I’ve seen each approach work extremely well. I just wonder if the conventional wisdom on testing would be the same if we thought of it from the perspective of the whole team.
I’m a big fan of board games, and I have invested many hours of my life playing board games. I’m not talking these “group fun games” like Cranium or Guesstures, I’m talking about games that have more strategy like Settlers of Catan, Ticket to Ride, and Dominion.
Each of these games has it’s own strategy, but I’ve found that in all of these games, the most important strategy is to have a plan for winning. Not only do I have to have a plan for winning, I need to do it fast. I’ve won many games where I came from behind because the person who was ahead got comfortable with the lead and didn’t keep pushing forward.
The same idea applies to software development. I don’t like when command-and-control managers try to push unrealistic timelines on development teams. But at the same time, every business could use everything that you’re doing for them yesterday, so we need to find a way to go faster.
This means that I need to make the best use of my time, all the time. This especially applies when things are a little slower. We’ve had times where we’ve had weeks where there was nothing pressing to be done and we decided to tackle technical debt in the code. This is one of the most important times on a project because this is your chance to come up with a way to do things better and faster.
This is when you need to have a plan for winning. You need to determine what things you can do that will help you write better software faster. You definitely don’t want to squander the opportunity, because who knows when another one like it might come along.
We are in a race against time. Any time wasted means lost revenue, lost productivity, missed market opportunities, and higher development cost. All of these things are critical to the business. Imagine that we were writing an app for your company with your money. Would you do things differently?
Everything that you do on a project should be done with a sense of urgency. Not a fear-based pressure that leads you to make bad decisions, get flustered, and cut corners, but a conscious effort to maximize the return on the investment of your time (and yes, your time is expensive). This shouldn’t have to come from your manager or some outside source, this needs to come from inside you.
In our fast paced culture, we are constantly looking ahead to the next big thing. We think about some magical someday when things will be better than they are now. Then when we get there we’re still looking ahead to something else.
I’m all for setting goals for the future and reflecting on the past. The danger in all of this is that we might just miss out on the present.
Recently I’ve been trying to live in the moment and be present in the present. I want to enjoy the people and opportunities that I have in front of me right now. I want to actually stop what I’m doing in my busy day and turn around and listen to someone who wants to talk to me. I want to spend less time looking for the next big thing and spend more time taking advantage of what’s in front of me.
You can’t take anything for granted in life because things change too fast. Never again will things be the same as they are right now. A year from now you might be working with different people, friends might move away, and your kids will be a year older. Sometimes it seems like things will always be the same, but nothing lasts forever.
So I find time to enjoy today. I’ve started to go to lunch with people more often because I want to enjoy them as much as I can. I had a great time in college, and I would give a lot to be able to have one day with those people all in the same place again doing the same things, but those days are gone. I hope that I’m saying that same thing about 2012 in a few years, and I don’t want to regret not taking advantage of it while I still had the opportunity.
While it’s wise to study the past and plan for the future, don’t forget to enjoy what you have now. Because you’ll never have another today.
I saw this in a job posting the other day, describing the work environment at the company:
We pair a lot, but not all the time. We test a lot, but not all the time. The key is being able to explain your practices with rational argument.
I love this. There are practices like testing that I hold in high regard, but nothing should be done all the time. As the posting says, “the key is being able to explain your practices with rational argument.”
Can you explain why you do something like TDD? That’s probably easy for you. But can you explain when you shouldn’t use that practice? That’s a little harder to do, and maybe because you’re holding onto some ideal that says you should test all the time or have 100% test coverage.
For every idea or practice that you find valuable, you should also be able to explain when it doesn’t apply. If you can’t explain when not to do it, I would say that you don’t really understand when and why you should use it.
What do you do when you get stuck on something at work? Do you ask for help? Or are you too afraid to bother someone else with your problem?
This is one of my pet peeves. When you’re writing software, gathering requirements, testing, or whatever you are doing, at some point you are going to get stuck on something. You spend a little time trying to figure it out, but you can’t solve the problem.
At this point, many people are afraid to ask for help. I don’t think that it’s because they’re too proud or lazy to do so, they just don’t want to inconvenience me because I “look like I’m busy” or they “don’t want to bother me”.
I may actually be busy and I maybe I even don’t want to be bothered, but if I can spend one minute answering someone’s question and save them 20 minutes of figuring it out (and the headaches that come with it), I’m going to do take the time to do it. Even though it’s an interruption, that time spent helping someone else is a good investment that will pay off because hopefully that person will no longer be stuck. If I really am so busy that I can’t help, I’ll just tell people that and they usually understand, and then I’ll try and follow up with them later.
I feel that in general we are so afraid of inconveniencing other people, even our good friends. I have good friends who have young kids like I do and they will go multiple years without going on a date without the kids. I’ve offered several times to watch their kids for them (which is not that hard to do since their kids will occupy my kids), yet to this day no one has ever taken me up on it. We’re talking about people that we are good friends with. Yet they are so afraid of inconveniencing us (even though we were the ones to offer to babysit) that they won’t do it.
I don’t really know where this comes from, but it’s frustrating. Several people working together are going to be more efficient that individuals working on their own, and that’s because we can work together to achieve something that we couldn’t achieve on our own. But that won’t happen if we aren’t willing to bother someone else with our problems.
I frequently try and tell people on my team that it’s totally OK for them to bother me. I think my business analyst interrupted me at least 10 times the other day to ask me questions. This made me excited because she wasn’t afraid to inconvenience me with her questions, and as a result she probably got a lot more done today than if she had just tried to struggle through it herself.
Software development is a very collaborative activity, and we will be way more efficient if we ask others for help. So ignore that little voice in your head and go ask someone for help, and don’t feel bad about it.
« Newer Posts — Older Posts »