As a new developer, I'm trying to focus on producing the best work the least amount of time. This is obviously going to take me longer than a person who has worked for a number of years in development and gained lots of experience. But I believe that establishing the right process now may save me a lot of time in the future.
Now, I want to recommend a good development method, especially for beginners. I also want to introduce you to steps you should work through before you even start writing any code.
The Basics of Scrum
In my team, we work using the Agile methodology Scrum. For those that aren't familiar with the process, here's a brief explanation.
Scrum is a process of working to create a product that is iteratively developed by breaking down all new requests for big features (known as Epics) into bite-sized chunks called Work Items.
Each project usually has a team of five to nine people (the optimum being seven), who work on an agreed set of items for a set length of time known as a sprint.
Our team sprints usually last two weeks, so every two weeks we have a new set of items divided up between the team.
You Have Your Item, Now Where Do You Begin?
What I found difficult to know when I first began was where to begin my work item, or in other words, what to work on first. Once I'd worked out the most time efficient order in which to complete the tasks, I went about tackling number one on the list.
Moving from testing to development, I didn't have much experience with unit tests or Test Driven Development (TDD). While I knew it was a good idea to use TDD and write unit tests, it wasn’t imparted upon me to put this knowledge into practice. So, given the option as a beginner, I generally made the mistake of jumping into writing the code first.
The Basics of Unit Testing and TDD
Although it's not expected, our team does try to use TDD. In this system, you write out unit tests to see whether your code produces the correct result for the business logic you're trying to match.
After you have finished development, this yields a quick way to check and see if any issues have arisen within your code, even years later when new functionality is added.
New functionality means new tests should be written. Eventually, you build up a solid set of tests to fully cover the code you have written, which is known as code coverage.
The tests that you write are usually located in a separate test project alongside your project within your solution, but this is all dependent upon how your team structures your code base.
Managing Time Constraints Using TDD
When I've used TDD, I've found that coding using this method is great for someone new to development. It forces you to break your code down into small, testable chunks to achieve one purpose. This makes you think more about how you are going to structure your code before you write it.
However, TDD is very hard to stick to when you're under time constraints (which is almost always). I did want to try and stick to this technique, but I kept coming up against this issue of time.
I think using TDD was a good step in the right direction for learning how to approach a development task, but I felt some bits were missing. It already assumes you have total knowledge with what you're doing, and that might not be case. You may even find that once you sit down and read the item yourself, you have deeper questions that weren't covered before. Because of this, I decided to seek advice from someone older and wiser.
Early on into my transition from a tester to a developer, I asked my manager the best way to approach a development task. At the time, he'd been developing for about ten years across different technologies and software, so he's a pretty good source of information.
Here's the advice I got in 9 simple steps.
1. What's your goal?
To establish your goal, you need to do three things:
- Clearly understand your work item
- Figure out what the business requires from this change
- Grasp the business value of this change
If you're not sure about any of these things, talk to the appropriate people to gain this knowledge before attempting any coding.
2. Discuss the best way to accomplish your goal with others
Consult with experienced mentor types on your development team to help you get to your solution quickly. Again, the aim here is to use your time efficiently.
By all means, try and overcome challenges yourself, but be mindful of the time you spend on it. You should not and do not need to shoulder all the work yourself. No matter what level of experience you have, don't be afraid to ask for help or turn to the all-knowing Google.
3. Break down your goal into tasks and objectives
Smaller chunks are easier to digest; it's just logical. Before you begin, think about your goal like a computer scientist, what you need to do, and then tackle each task one step at a time.
Making lists or simply brainstorming what you think is involved is a good way to clearly see the steps you need to take. If you order these steps, it will also help you identify a logical order to proceed. Hopefully, this will ensure less jumping back and forth within code.
4. Look for similar existing unit tests and run them
Think about the current functionality that exists in the product you're enhancing.
Is there anything similar that you can step through and debug to help you make your task easier? If you find any methods like this, try and find tests that execute these methods to check if you can extend them to fulfill your new task.
5. Write your new test
If all else fails, write a brand new test from scratch, but start by writing a test and not by writing the code for your solution. You start by writing the test because you know the outcome you want to achieve. You want to do X to achieve Y.
You will also have some idea of where your new code will sit within the project. Writing an empty method here for your test to run over will provide you something to build upon and expand in order to make your test pass. Lastly, writing your test now will save you time later.
6. Solve the task with the minimum amount of code
Try and use the least amount of code to write a solution for your task in order to fulfill it. Don't worry about efficiency yet –– just get it done.
You will be tempted to try and write code perfectly to ensure the least amount of bugs, the greatest performance gains, and to show off your awesome coding skills. However, you need to keep in mind that doing all this may take you longer to do than solving the initial problem, especially if the task is small. You need to keep in mind that you may be over-engineering a solution or trying to future-proof against scenarios that may never happen. Be efficient with the time you have now.
7. Make your test pass…
Run the test over your small chunk of new code. If it passes, great. If it doesn't pass and the reason isn't obvious—for example, the condition of the assert wasn't met—you need to debug the code.
Go through each line, inspecting the value of each variable, property, and return statement.
Once you've found the culprit causing the issue, fix it and ensure that your test passes and fulfills its task.
8. …Then refactor your code
Now that your test has passed, you can extend your solution to become more efficient.
Don't forget that for every new method you may need a new test or two or more. This will depend on the number of ways that block of code can be exited. For example, you could go through the block of code where everything functions as normal and you get the result you expect, like a list of objects. But, there may also be a case where you could go through the same block of code and an error occurs which gives you a list of the same objects but they're empty. Other ways to leave the code could be a number of different types of exceptions.
These all would need different tests.
9. Work back through step 7 – 9
Repeat steps 7 through 9 to ensure that the changes you’ve made in your code don't make the test fail. If it does fail, debug the test to find out why.
Feel free to add in as many assertions to verify the outcome of your tests are correct and reliable at any stage.
And That's It! Easy, Right?
Well, no. Actually, it takes quite a lot of discipline to avoid jumping straight into coding the solution, especially when you're a junior developer.
However, if you want to try and take small steps towards using TDD, you could try an alternative approach. If you write tests as you go along, i.e. after every method you create, you will save yourself time after the development of your features.