Junior skills, senior tasks
I spent the last year working as a developer in an organisation that has strict code quality principles, strong team practices and rock-solid expertise in what is doing. My colleagues are all senior developers, people owning the domain and comfortably innovating solutions on user and technical level. A lot of them work many years for the company already.
I am not new to being a developer, but I am definitely new in this level of professionalism and this level and scale of delivering products. Working in a senior team doing senior tasks with junior skills(we’ll dive in what those are in a bit) is a challenge and I learned a lot of things the hard way.
The debate of what makes a junior and a senior developer is ever ongoing. If you google it, you’ll find an immense pool of opinions on this.
The career progression of a developer is very blurry — we use these junior/senior categories to illustrate a jump forward, partly because they relate to our financial renumeration for the work we are doing. The old-school distinction was really tied to experience, days and years writing code as a day job, but we’re seeing a shift from that thinking recently. It is becoming increasingly more apparent that the job of a developer is much more than just writing the code, and instead of being brilliant in one skill is being apt in a set of skills. A big portion of people that come into the job in the recent years are not classically university trained engineers. They come from different backgrounds and each comes with a unique set of strong skills. Some of them, beginner in writing code, will come with the organisational, professional, social and teaching skills that a person writing code for five years is still beginner in, and yet these skills are crucial to what makes a “senior” developer.
For that reason, I think that the junior/senior categories are too rigid for the current workplace, so I will only refer to being junior or senior in certain skills.
At the beginning of this year I started working independently for a couple of months. That meant I picked, made decisions about and delivered a set of features by myself for the first time after joining the team. The set of features consisted of stories related to each other, not in particular order, with varying difficulty and scope, located in a for me semi-known part of the codebase. Until then I was part of bigger projects constantly pairing.
Surprise, surprise(not), to be able to successfully deliver a feature you are working on, the work you do before you attempt writing any production code will determine the pace, the quality and the stress levels you are going to encounter. Knowing how to write witty Python will not save you from the failure of not estimating or planning properly. The key lies in understanding, real deep understanding of the problem and the solution, and making sure you’ve done all the prep even if something seems trivial(especially if you are still learning like me!).
After a feature taking twice as much time as I initially estimated, fixing five bugs found by others on another one and rewriting whole core logic parts on a third feature after a review, I said — easy there Tamara, you need to slow down. I needed to revise my working process and I made a little checklist for me to do before I start writing production code for a story.
- Read the task description. Twice. Three times.
- Do you understand everything that this feature needs to cover from the user perspective?
- Does the feature seem consistent with similar features already in the software by design?
- If not and it is something new, does this need some infrastructure work before you can do this feature?
- Are there any corner cases you can think of immediately that the description might not cover? (Maybe the domain experts and the product owner do! Always worth the chat.)
- Does the description describe one scenario or it is multiple scenarios and the current description actually describes two ore more features? (sometimes the distinction is technical, and the POs can’t know that)
- Does you have all the technical expertise to deliver this feature?
- If not, what kind of help do you need, and is the person that can help available in this time? (If not, maybe the feature should be postponed. You should communicate this!)
- Break it down into tasks.
Not only having your story broken down into small tasks will give the team overview of where you stand with your work(yay you have something tangible to say at standup), it will also keep you moving forward and give you a sense of accomplishment while nailing the hard ones. Breaking the story into tasks will make you think deeply about the approach you are taking to solve this. The more explicit you can be with the tasks, the better. They should be measurable and testable. The tasks will also give you a nice neat git history, as you can easily translate them into tiny bite-sized-logic commits. The task creation time is also the best time to reach out to more experienced colleagues to clear some things up for you if you are struggling. As a bonus, you’ll get an early revision of your proposed approach, and surely it is a better time for that than a ready PR.
Now, if you are new to a product and codebase, your tasks will be more fuzzy and that’s ok. It is also ok to hack around a bit if you only know what you want, but not how to get it. I do that often.
- Only then → Estimate.
Ok, estimation is hard. You need a lot of conditions checked to have the sufficient knowledge to make it right. I certainly fail at this too often, and I am sure you do too. Estimation is important so the product owners/project managers know how to plan the work. They would like to be able to count on outcomes and gather enough features to move the product forward. So despite this being hard, you need to put a number. I am now more mindful about all I need to consider before putting that number in, and I wait a bit before I do it. I refer to the tasks when I need to think about estimating.
- Are there a lot of tasks?
- Do some of them scare you?
- Are you familiar with the parts of the codebase you need to touch to get the tasks done?
- Is there an external dependency(someone that needs to help you, another team intervention, waiting for design)?
- How long does it take on average to have a feature reviewed?
- Test. It. All.
Shoutout to Herr Jan Buchholz for this one!
We do TDD, and I try to follow that. Testing all that I can test at the beginning has saved my life more than once. I now always test all the user scenarios, how they would work if everything is already done, all the corner cases that the domain expert or the PO have suggested. It really helps in not forgetting things and covering all the holes, before you dig into the details. The more holes covered, the less bugs return to be fixed. And we all love that. While writing tests you can also get additional insights about the feature you are about to do.
- Start writing production code.
Maybe the above written helps someone on their path of being a better developer!
What else are you doing to make sure you successfully deliver your work? What is your process? I’d like to know!