In the previous post, I explained how I use a branching strategy to manage deployments to UAT and production instances. I also explained how the branching could help to implement new features and user stories. In this post, I am going to explain how I break the project to smaller pieces to make the development more manageable and the benefits of doing so.
I never finish anything, unless I set a deadline for myself. Surprisingly, many of my successful friends are the same, and an important reason they are successful is because they set deadlines for their work. Visual Studio Team Services makes having deadlines (read milestones) and project planning really easy. In this post I am going to explain the way I use Visual Studio Team Services to manage my work.
At the top of my project management hierarchy are releases. For example, I create biweekly or monthly releases. Ideally, I do not associate production deployments to releases, meaning I might push changes to production sooner than the release date is due (maybe daily with continues integration and automatic deployments). But releases are a great way for me to group what features/user stories are deployed at each period. Also I restrict myself not to do any other feature outside of the current release. For example, if I finish features under this release sooner than the release date, I will not move any of the features from the next release to the current release. The following image shows the hierarchy of my work items:
A release for me is a deadline. For example, let’s assume the project is a single page web application for a marketing landing page, which should be done in two weeks. I create a release with the date "2016/12/10" (two weeks from today).
Each release is expanded by defining features. Obviously, features and their scope is defined by the business requirements. In the example, I would create a feature with the title:
Single Page Marketing Landing Page for Promotion “Dummy Promo”.
Note that this is a very simple example. In a larger project with a larger team, there will be multiple features for each release. Or, a single feature can only be implemented in multiple sprints within a release. I want to keep things simple in this post. So let's continue with our simple example.
Then I start creating user stories for this feature. In bigger teams, usually features and user stories are created by the business analysts (BAs) and passed down to developers. I like to keep this routine in my small projects too. In my simple example, I would probably create the following user stories:
- [As a user I want to see] Create a single page web project and create the site layout
- [As a user I want to see] Implement search engine optimization features into the landing page
- [As a user I want to see] Implement a subscribe to newsletter form
Note that I am not really following any standard convention regarding the verbiage of these user stories.
I am only utilizing user stories to break down a feature to smaller components (goals). It is extremely important that if the user stories are vague or does not specify a single user story, they need to be discussed with the BAs (or revised by yourself) to be broken down to smaller, clearer user stories.
The next step is I put on my developer gloves and start thinking about tasks for each user story. When I create tasks, it is as if I have already started developing (read coding) the user stories. A lot of developers (including myself in the past) start thinking about the user story with the code editor open in front of them. Unfortunately, in my experience this will extremely effect both the quality of the code and the deadlines. Nowadays, I normally grab a piece of paper and draft how I am going to implement a user story (literally staying away from the code editor). Then I create tasks under the user story in Team Services. Let’s take the first user story in my simple example:
- Create an empty ASP.NET MVC web project
- Add a layout file, add layout html
- Add design assets (general JS libraries, CSS files, Images)
- Create an MVC Controller/Action to render the landing page.
- Implement the landing page View
- Pass View’s dynamic content using a View Model in the controller
- Create a Model to populate the View Model with dynamic content.
But this is so simple, boring and redundant! And I agree. As an experienced [web] developer I can just take the user story and start implementing it right away. What I am trying to highlight here is, I am already in the developer mode. Creating these tasks are part of my coding journey to develop the user story. If any of these tasks are dependent on other resources (for example I need to get the design assets from another team member/department), I can send an email about it to get the project going, rather than trying to resolve this issue in the middle of my coding and waiting for it to be resolved.
Breaking down user stories to smaller tasks has the following benefits:
- Creates a step by step plan for development. Creating tasks is not about documentation, it is about planning ahead how to implement a business requirement. It will save a lot of time in the long run to start thinking about how to implement a user story before starting to code.
- If there is a dependency in the current user story that needs to be resolved it is known before start of the task. For example, finishing another user story first, communicating with other team members, contacting other teams, and waiting for more clear business requirements.
- Creating granular tasks will help breaking business requirements to smaller pieces. At coding time, you no longer have to worry about business requirements. You exactly know what needs to be done, and only have to focus on your code. You are already aware of the big picture, because you have created those tasks in the first place for the user story.
- You can provide a better estimate for when the user story will be done. Creating tasks is not just creating smaller to-do items. It is also spending time thinking about the problem (user story) at hand. Therefore, you are carefully engineering your work before actually implementing it. And you have a better understanding of how long each small tasks will take to finish.
- You can assign tasks to other team members to help you implement a user story which is assigned to you. If the project has a tight deadline, the smaller tasks can [safer] be assigned to other developers to meet the deadline. And it is only because these tasks were well thought of with development requirements into consideration.
Note that this post is about being in control of your development or as the title says Managing the [development] Work. There is clearly a management overhead, specially in small projects, creating releases, features, and etc. But ultimately, with constant change of requirements in todays dynamic world, it will make change management much easier following these simple steps.
I must emphasize again, it is important to create the tasks based on the right user stories to provide more accurate effort estimates. If the user stories are not well defined (usually happens in bigger teams) they need to be revised to create distinction (separation of concerns in software engineering) between feature components.