There are those who believe that a developer should not test their own code. This may sound logical, but I’m not sure I’m buying it.
This statement typically refers to QA testing, and doesn’t mean that a developer shouldn’t write unit tests. The thinking here is that a second person testing the features that you’ve developed might think of things a different way and find a problem that you didn’t think of when you wrote the code.
There are lots of commonly accepted statements and ideas like this in software development. But I’ve found that in many cases, these ideas are usually based on certain assumptions, and if you can challenge those assumptions, you might open yourself up to things that you didn’t think were possible.
The assumption that I see here is that a developer writing the code is not sufficiently capable of thinking of all of the test cases. Imagine you write code for a feature, and now you have to test it. At this point, you’ve gone through a certain mental thought process when you implemented the feature. This makes it much harder to think outside of the box to come up with the edge cases. Not to mention that when you see that the feature appears to be working overall, it’s really really tempting to do some basic manual testing and then move on to the next feature without really doing your due diligence. A independent QA tester, however, will look at the feature objectively because their thought process isn’t clouded by past experience of having written the code.
OK, so what if the developer figured out all of the tests cases before writing the code? Now their thinking isn’t clouded by the implementation of the feature because they haven’t wrote the code yet. Maybe a QA person helps define the test cases, but this post is about developers testing their own code, so let’s assume that QA people aren’t involved. I would argue that now we’ve removed the main reason that developers are not good at testing their own code (thinking of the test cases after writing the code), so they should be able to think of test cases just as well as a QA tester, and therefore they should be able to test their own code.
Don’t misconstrue what I’m saying there – I’m not saying that we don’t need our QA teams. I’m saying that developers need to be responsible for testing. QA teams can add more testing help, but developers need to be responsible for their own code.
This opens you up to new possibilities. It enables developers to be confident about the quality of their code. It limits the wasted time you incur when you have the back-and-forth that comes with QA finding bugs and developers having to go back and fix things. It can reduce the amount of “checking” that QA people need to do because they might be comfortable knowing that developers are writing quality code.
If you’re a developer, this is some thing you can start doing today. Before you implement a feature, come up with all of the test scenarios before you write your code. If you have a QA team, have them review your test cases to see if you’ve missed anything. Then go write some bug free code!
How much of the responsibility for the software that you are creating falls on your shoulders?
There are two ways of looking at responsibility on a team. One view would be to say that if there are 10 people on the team, then I’m responsible for 10% of the software development process. I don’t need to be concerned with the quality of the requirements because that’s the business analysts’ job. I don’t need to worry about testing my code because we have testers to do that.
The other view is that even in a team environment, I am still 100% responsible for the software I’m creating. That means that I’m not just implementing the requirements, I’m trying to understand the requirements to make sure that they’re correct and that we’re building things in the best way possible that will meet the needs of the business. And that certainly means that I’m never ever going to send code to QA that I haven’t tested just because I think they’re going to test it for me.
I need to be responsible for communicating with my team members the best that I can. I would much rather be clear about who is doing what rather than assuming. If I make an assumption, it’s probably going to be wrong – either I will assume someone is going to do something when they’re not and something will slip through the cracks, or I will assume someone is not going to do something when they are, and now we’ve duplicated effort.
This is what I see happen often on software teams, especially when it comes to testing. Developers assume that QA is going to do the testing, so they give code to QA without completely knowing if it’s working. QA assumes that developers are going to do this and don’t know what was tested and what wasn’t, so they think they have to test 100% of the functionality of the feature. In reality, the developer probably wrote decent code that mostly works, and they probably did test it to some extent (whether manual or automated), so the tester is duplicating some of the effort, but if they don’t know what was already done, they don’t have a choice.
This is where communication is key. If I as a developer am going to write automated tests to prove that my code works, then I want QA to be involved in the writing of the tests (even if that’s just reviewing what I’m doing). That way QA doesn’t have to duplicate effort because they can know that developers have already done some of the testing, and developers can start giving code to QA when they are confident that it works (with actual proof to back it up). QA and developers can work together to decide who is going to test what, what is going to be tested, and how it’s going to be tested.
In this case, everyone is 100% responsible for the quality of the software. Instead of expecting others to cover for us, we work together with others to make sure everything is covered. This requires people to move past their traditional roles, trust each other, and work together. In the end, we won’t duplicate effort and we won’t let things slip through the cracks.
I recently went through a big change in my role at work. I went from being a tech lead on a team of 15 people to working on a project all by myself.
Anytime you go from one extreme to the other, you see some stark differences between the two environments, and in my case, it caused me to think about the way we do things in teams.
The most obvious change was a huge decrease in meetings. I went from an average of 4-5 meetings a day (not counting standups) to an average of 1 meeting a day. When you’re a team lead of a large team, I suppose that comes with the territory. But when you have close to 7 hours a day of time to work with minimal interruptions, you get a LOT of work done.
Meetings are a common complaint from people who work in a team environment. And even though you can read hundreds of articles about how meetings are pointless and you should skip them, the fact is that most meetings exist for a good reason, and while skipping all your meetings may seem like a good short term decision, you can’t realistically do that all the time.
I think that the problem isn’t necessarily the meetings, it’s the fact that the meetings are needed in the first place. Every time you add a person to a team, you’re introducing more inefficiency to the team because now there is one more person that you need to communicate with, that you have to share information with, that you have to invite to a meeting.
Now, even though this inefficiency exists, typically you are adding someone to the team because the benefits of having them there outweigh the negatives. But to what extent? Is there a point where you get diminishing returns from adding new people?
Managers exist for a good reason – to coordinate team activities, make sure everyone is on the same page, communicate with other teams, and go to lots of meetings so that the rest of the team doesn’t have to. When your team gets really large, you start needing more management. Then what happens is one of two things – the manager becomes overworked and can’t keep up with everything, or you end up having your tech leads go to more meetings and become more like managers. The problem there is that tech leads are tech leads because they’re good at tech, not necessarily because they’re good at management, and now you’ve essentially taken your best technical person and removed them from the role where they can provide the most value. Then your tech leads get frustrated because they feel that they don’t get anything done because they spend all of their time on meetings.
If you’re hiring a bunch if people and creating a big team, it’s probably because you have a lot of important work that needs to be done, so I’m not saying to not hire those people. But I would encourage you to find a way to split them up into smaller teams. You may have multiple teams working on the same project or even in the same codebase, and that’s fine, we just want to decrease the amount of communication that is needed in order to get things done.
Our IT department has done a lot of this lately, trying to take large teams and divide them up into smaller sub-teams of around 4-5 people. Now those communication inefficiencies are diminished because you only have to communicate with a few people (who ideally sit in the same area as you). Not only that, planning is so much easier. It’s much easier to accurately predict what you can do with 4 people than it is with 15 people, not to mention that if things go off the rails for an iteration, it’s a lot less expensive.
I think the ideal team size would be 3-5 people, where you don’t have more than 2 people in each discipline (BA, QA, dev). It would be even better if those people were somewhat cross-functional so that they can help each other out when someone gets behind.
While splitting into smaller teams may make those teams more efficient, you still will need coordination across teams and more meetings and management. But I think having smaller teams helps you to see the need for management and enables you to put the right people in those roles instead of just pulling your tech leads in to fill those roles.
There are no hard and fast rules for this sort of thing, and the results may be different for you than it was for me. The important things is that we constantly evaluate how we are doing things and find ways that we can increase our efficiency and reliability of our software teams.
We all have numerous activities and people competing for our time. More than anywhere else, this seems to play out at work.
If you’ve ever had a day full of meetings, you know what I’m talking about. It feels like you go to work for the entire day so that other people can get stuff done while you feel like you accomplish nothing.
A day half full of meetings isn’t much better, especially when the meetings are scattered throughout the day. Sure, you technically have half of your day to get work done, but it’s constantly broken up by meetings.
We came to a point on our project where this was getting really bad, especially for developers. We would often spend half of our days in meetings, and as a result we wouldn’t have any long stretches of time to focus on writing code. We had to do something about it.
So we did. We blocked off 2pm until whenever you left each day for no meetings. We acknowledge that meetings are necessary, but we need to set aside time for ourselves so that we can get the things done that we have promised that we would get done. This is an actual calendar invite in Outlook, so the time shows up as busy to anyone trying to schedule a meeting.
We also blocked off 10am-11am every day to have meetings. When we need to schedule a meeting, we try to fit them in between 10-11. We have our standup at 10, so we’re already stopping for that anyway, so it’s a good time to talk.
This system has been awesome. I often have meetings from 10-11, and sometimes longer, but if the 10-11 slot is full, people will schedule meetings in the time slots around it. As a result, I’m often done with meetings for the day by lunchtime. I have close to the same amount of meetings as I did before, but now I get them all over with at once. Now I have the whole afternoon to get work done. This has done wonders for our sanity.
Since we don’t have many time slots for meetings, this forces people to not schedule frivolous meetings. You know the ones I’m talking about, where someone schedules a half-hour meeting for what ends up being a 10 minute conversation. Now we just have a 10 minute conversation after the standup.
There is a real cost to context switching. It takes some time to get in the zone, regardless of whether you’re writing code, writing requirements, or testing. Every time that you have to stop what you’re doing to do something else, you need to spend time to get back into what you were doing.
In the end, it boils down to being in control of your schedule so that you have time to do the things that are most important. I encourage you to set up whatever boundaries you need in your day in order to help you succeed.
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.
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.
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.
These days, there is a certification for everything. Almost every discipline in software development has several different certifications that you can get if you attend a training class and then take a test that verifies that you understand the book definition of a process or language. This totally misses the point.
In some industries, certification matters. I’m glad that my doctor has to go through 12 years of school and thousands of dollars in student loans in order to get his M.D. If someone can make it through that, I have confidence that they know what they’re doing.
The bar for software certifications is much lower. All you have to do is pay a few thousand dollars for a training class and then take a test that shows that you paid attention in class and understand the basic concepts.
What do we think we get out of these certifications? A basic understanding of the principles, maybe. The problem is that those things are the easy part of software development.
Here are some of the things that I actually look for when hiring people:
- Ability to listen to users
- Understanding your team members
- Motivation and purpose
- Ability to think outside the box (as opposed to being certified that you know that you how to think inside the box)
- Learning ability
- Problem solving skills
I feel that one of my greatest strengths is the ability to make it up as I go. Sure, I might have my Agile bag of tricks, but every project and environment is so different. When we inevitably encounter a problem, the hard part is finding the right solution for it, and no formula or certification is going to tell you the right solution to every problem.
Certifications aren’t all bad, if you spend a week learning learn how to be a “certified Scrum developer”, you’ll learn TDD and good OO practices and other things that will help you succeed. We can argue about whether it’s worth the money, but you are going to learn some good stuff.
The point of all this is that (in my opinion) some of them most important qualities in a team member are less quantifiable things like attitude, passion, and the ability to think outside the box. These are the things that I want to strive for, and the only “certification” that you can get for this is experience.
One of my favorite tricks around changing how a team does something is to get other people to drive the change for you.
This especially applies if you’re coming into an organization as an outsider. Most people are initially somewhat skeptical of outsiders and you need to earn their trust. This sometimes takes a long time, and you might want to change some things before you’ve built up the political capital to drive it yourself.
When I started on my current project, all of the QA testing was done manually, and QA people weren’t involved in the process at all until after the code had been written. As a result, they would get features to test and not have any idea of what they had to test, and many times they couldn’t trust that the requirements were even up to date.
The solution that I was hoping for was to get QA people to meet with developers and BAs before the code was written so that they could come up with a test strategy and acceptance criteria. That way they would have input up front, and developers could automate all or most of the acceptance tests, which would save QA a lot of time. But I didn’t want to bring it up myself.
So I would ask questions in meetings. We all agreed there was a problem, so I would ask everyone what ideas they had to fix it. Eventually someone would give the answer I was looking for. “That’s a great idea!”, I’d say, “How do you think we should do that?” Now it wasn’t my solution, it was someone else’s. That person feels good because they came up with a good idea (that eventually ended up working), and since that person is actually on the team and doing the work, they might have more credibility than an outsider like me.
I would much rather have someone else get the credit for coming up with the ideas, because I think that it gives the idea a better chance of success, and when it works, it encourages people to try and think of more ways to improve things. If one person comes in and tries to drive and enforce all of the change, it’s very easy for people to discredit that person (maybe even just in their mind) and try and fight the change. But when the ideas are coming from multiple different people on the team, now you have more and more people buying in because they’re the ones coming up with the ideas!
When I think of a “coach”, I think of someone who helps other people find the path to success. You can try to push them in that direction and they might turn around and fight you instead. Or you can help them use their own ideas and expertise that they already have to find their own way.
If you want to change something in your organization, that must mean that there is some problem that needs to be fixed and a solution to fix the problem. That’s obvious, right?
Maybe it’s obvious to you. But is it obvious to others?
If other people on the team don’t see that there’s a problem or if they’re OK with the status quo, it’s going to be very difficult to get them to change. For example, let’s say that your team does not do automated testing and you want to get developers to start writing unit tests. The problem is that you have lots of bugs and it’s scary when you have to refactor the code.
But wait a minute, do other people think it’s a problem? More than that, do they think that your solution will be better than the status quo? That’s a completely different question! Maybe the developers on the team have all been getting good reviews from their manager. They might not like the bugs and the scary refactoring, but they might not think that introducing TDD will fix the problem, or they might think that it’ll be more work to learn TDD than just deal with the code without tests.
You need them to both see the problem and buy into the solution (man, this is getting hard). So maybe you go and write unit tests around some part of the system. Then later when another developer needs to change the code, you show them how easy it is to run the tests and see that the code is still working. Now maybe they’re more open to your solution because they can see the benefits of it and see that maybe it won’t be as hard to implement as they previously thought.
Until you can get people to see that there is a problem and that your solution is viable, you’re probably not going to have a lot of success getting them to change.
Older Posts »