Monday, March 30, 2015

Software Estimation: How to estimate software accurately part 2

In this series on software estimation I defined an accurate estimate as something that will:
  • Give you an understanding of risk and unknowns.
  • Quantify the known work.
  • Be something that you can base a big decision on.
  • Be refined as new information becomes available.
  • Be a range with a 90% confidence interval.
In part 1 I explained how to account for risk and unknowns in your software estimation. In this post I'll explain how to quantify the work that is known.

Quantifying The Known Work


All software has to be designed, architected, implemented, tested, debugged, and deployed. Each of these areas needs to be accounted for in the software estimate. Here are a set of questions that should be asked for each area to help you understand the level of effort associated with building your software.

Using these questions you can break out the known work into smaller buckets of work. You can then estimate each of these smaller pieces independently.

Design


Has the user experience and user interaction been defined? Do people interact directly via a user interface you provide or indirectly from another user interface? Have all the transitions and states been defined?

Will your software be available in multiple regions and/or locales? Does the design take regionalization and localization into account? Who provides the translations?

Architecture


What platform will the software run on? Are there platform specific requirements or constraints? Does hardware need to be purchased or provisioned?

What abstractions need to be defined? What is the hierarchy and/or composition of the abstractions?

Does the software rely on persistent data? How is it generated? How is it updated? What data specific workflows are there?

What metrics do you need to track?

How is the software going to scale? Are there single points of failure? Is the software going to be memory bound and/or CPU bound?

What is the software NOT going to do?

Versioning


Is your software released incrementally? How will the system handle data structure changes?

How are functionality updates handled in your system? Do updates need to be isolated from each other or can they co-exist. Is there a need to maintain backwards compatibility?

Implementation


What is the source control mechanism? Is it already setup? Does everyone have access? Is there a branching strategy?

Who is going to implement the software? Do they have all the hardware and software they need? Do you they know the platforms or technologies that your project uses? Do they require time to ramp up on the platform or tools? Is external training required?

Testing


Is your project going to use continuous integration? If not, why? Is your project going to use continuous deployment? If so, how do you deal with a failed deployment?

How are bugs going to be tracked?

How are the units of software defined? Are there tests for all units? A good software project has tests for each unit of work as well as tests for the integration of multiple units.

Are your tests automated? How often are the tests run and by whom?

Do you need black box testing, white box testing, or a combination of both for your software? Are you testing more than just the happy path or are you doing negative case testing as well? Does your software need stress or load tests?

Does your testing require specific hardware or software? Do these need to be procured?

Debugging


What tools are going to be used to debug the software? How are you going to profile performance?

What needs to be logged? How often and by what components? How are logs collected?

How are errors reported? What work is required to make errors in the system reproducible?

Deployment


How is the software going to be released? How is your software going to be monitored? How is your infrastructure going to be built out? Can you automate the infrastructure build out using tools like Chef or Puppet?

How is the software documented? How is the documentation updated?

What's Next?


In my next post I'll explain the last pieces needed to give an accurate software estimation.

Monday, March 23, 2015

Software Estimation: How to estimate software accurately part 1

In my last post Software Estimate: What you're doing wrong I explained why people tend to create inaccurate software estimates. In this post I'll outline what's necessary to create an accurate software estimate.

Previously I defined an accurate estimate as something that will:
  • Give you an understanding of risk and unknowns.
  • Quantify the known work.
  • Be something that you can base a big decision on.
  • Be refined as new information becomes available.
  • Be a range with a 90% confidence interval.

Let's take a deeper dive into each of these areas with the goal of helping you to understand what information you need to gather to accurately estimate your software.

Identifying Risk and Unknowns


It is inevitable that there is risk associated with the software you're building. Risk in a software project is typically associated in one or more of the following areas:

  • Blocking another project.
  • Being blocked by another project.
  • Requirements or scope that haven't been defined.
  • Attrition.

If we understand the areas that pose risk to our project we can use that information to inform our estimate. Your project may need additional time to coordinate with another team. You may need to account for another projects schedule and/or risk.

Blocking another project


While blocking another project many not sound like something that needs to be taken into account when estimating software it can actually be the source of unexpected work. The other project may have requirements for your software that you're unaware of. You may have to make last minute changes to your software to account for these requirements. This is especially true if the other project is a higher priority project for the company than yours.

It's important from an estimation standpoint to understand if there are other projects that need to consume your software. If so, how well is the dependency between your project and theirs defined? Does the other project take direct dependencies on your software (for example by compiling against your library)? If you're providing a service how well is the service contract defined?

When you update your software what are the downstream effects on consumers of your software? Does your software require versioning?

Being blocked by another project


What other components, libraries, or services does your software depend on? Have they already been shipped? If so how do you deal with updates to the software? If the software hasn't already shipped, are their milestones known?

What happens if they can't deliver or aren't able to deliver in time for your project to meet it's goals? Do features in your software get removed? How long will it take to remove or update the affected components?

Requirements that haven't been defined


Blocking another project or being blocked by another project are not the only sources of undefined requirements. Additional requirements many come from your product owners due to under-defined user experiences or user interactions.

Are there mock ups of the user experience and user interaction? Have static web based mocks that people can touch and feel been built? Are all the transitions defined? What state does your application need or maintain?

Attrition


While attrition is often difficult to account for in the actual estimate, asking yourself some attrition related questions will help you identify work that should be accounted for in your estimate.

Does your software require a specialized skillset or tools? How long does it take to aquire the tools? What's the ramp up time to learn the skillset? What's the lead time that it takes to hire someone with the needed skills or platform knowledge?

What's Next?


In my next post I'll explain how to quantify the work that is known.

Monday, March 16, 2015

Software Estimation: What you're doing wrong

During the beginning of my career as a software development engineer one of things that I dreaded the most was the beginning of any project where I knew I was going to be asked to give an estimate for the software I was going to write. Often I thought "how can I estimate something I have no clue how I'm even going to build?"

Ultimately the dread I felt came down to this one simple fact. I had no clue how you could accurately estimate software. Over the years, as I've learned to estimate software development much more accurately, I've learned that what I thought of as software estimation was built on several assumptions that were incorrect.

Fallacies of Estimation

  • Estimates require giving a specific date
  • Estimates should be given on the spot
  • Estimates can't change

Estimates Require Giving a Specific Date


This fallacy was probably the heart of the anxiety I felt about software estimation. I always assumed that an estimate was a fixed amount of time like 2 days or 1 month. It never occurred to me that an estimate could be a range. Fixed dates are rigid and inflexible and are easy to get wrong. Fixed dates cannot account for the fact that there are unknowns associated with the project. 

An accurate estimate will be a range. Ranges are more flexible and can help account for the unknown and any risks associated with the project.

Estimates should be given on the spot


This fallacy is based on the assumption that some big decision needs to be made right now and doesn't have time to wait for you to think about what unknowns you're dealing with. First off, if you're making a big decision on the spot based on a back of the hand estimate you shouldn't be in your role and shouldn't have the responsibility that you do. It's careless and dangerous to you, your product, and your customers to expect some engineer to accurately give you an estimate on the spot.

An accurate estimate will require you to do some research.

Estimates can't change


It may be true that the original estimate needs to be something that you can make a big decision or commitment based on. It's not true however that estimation stops once that decision is made or a project is put into motion. An estimate needs to be a living thing.

Estimates are about approximations. They're about dealing with ambiguity. As things become less ambiguous your estimate should be refined.

Where to go from here?


Now that we know the fallacies of software estimation we can define the characteristics of an accurate software estimate. An accurate estimate will:
  • Give you an understanding of risk and unknowns.
  • Quantify the known work.
  • Be something that you can base a big decision on.
  • Be refined as new information becomes available.
  • Be a range with a 90% confidence interval.

In my next post I'll talk about the truths of software estimation and give you a set of resources to help you create accurate software estimations.

Monday, March 9, 2015

Making The Leap From Individual Contributor To Management

A few years ago I made the switch from being an individual contributor (IC) to being a manager. At the time of my transition I was a principle software engineer and engineering lead on a team of developers building mobile apps and frameworks for iOS and Android.

The last few years of being an IC I was the engineering lead on several projects at several different companies. My time as an engineering lead gave me greater exposure to mentoring, project management, and product management. I started coding less and taking more accountability and responsibility for the vision of the projects I was working on as well as the delivery as a team.

Growing Others


As an engineering lead I started taking on more responsibility for growing other engineers on my team and across the company. I worked with engineers and their managers to identify areas of growth both technically as well as from a career perspective. I also worked with them on their social dynamics and team interactions, trying to help them work more effectively with their teammates and those in the company they didn't personally get along with.

From a career development perspective I mainly focused on helping them to make the connection between their contributions on the project, the work they pick up, growing their skills, and stretching as individuals. I found that I really enjoyed this part of mentoring more than any other aspect. As I saw people being successful putting to practice things we'd talked about and worked on I felt very fulfilled. Surprisingly, this fulfillment was equal to or greater than the fulfillment I had when I delivered a complex solution I had solved in code.

Managing The Project


I've been a very big fan of agile software development for a long time. Early in my career I worked with several people who helped me understand that what you're building changes as the ambiguity is removed from a project. The system that you use to manage your project life-cycle has to be able to account for this change.

As an engineering lead I usually took on the role of scrum leader. This meant that I was managing the sprint, everything from daily stand-up to sprint planning meetings. I found that I enjoyed planning the sprints and found myself taking every opportunity that presented itself to expand my scope of planning, owning the project schedules and plans for large features and projects.

Future Of The Product


As an engineering lead I would attend meetings with management and product to talk about the direction of the product. We'd focus on the current project and talk about where the product was heading, what road blocks we saw getting in our way, and what areas of the product were emerging that we hadn't envisioned or that had been to ambiguous previously.

In these meetings I found that I was able to bring a different perspective. It's not that my being more technically focused was the game changer, but more that I discovered that I was able to translate some of the more technical details into something that was actionable by product management.

Making The Leap


At an employee moral event a few years ago I was having a casual conversation with one of the directors at the company I was at and I jokingly mentioned that I thought I could handle managing one of his teams that was currently without a manager. After that event he reached out to me and asked if I was serious about wanting to give managing a team a try. I thought about it for a few weeks, talked to my wife, and decided to dive in.

I've found that management is very fulfilling. I'm able to stretch myself in ways that I couldn't as an IC. I'm able to have a larger impact on my organization, my project, and my team. Along the way I've learned a lot about humility, about being a better listener, effective coordination, and how to build a collaborative environment.

I still write a lot of code at home on personal projects. I'm still a software engineer at heart. But I've also discovered that I'm a good people manager. I've find more satisfaction in the success of my direct reports than I ever thought possible. I've learned more about myself, my gaps, and skills I never thought I had.

Monday, March 2, 2015

Android WebView: HTML5 Video and Rotation

In the last few posts I've shown you have to add a Web View to your Android application. Web View's are useful for showing external content without leaving your app, adding dynamic content to your app allowing change without an app update, or simply display legal pages (terms of service, end user license agreements, etc) directly from your site.

I wanted to end this brief series talking about HTML5 video and rotation. There are some gotchas that it's important to be aware of in these areas that I've come across over the past few years.

Stopping Video


In some versions of Android the audio of video that was playing in a Web View will continue to play in the background even after exiting the Fragment or Activity that is hosting the web view. This appears to be a bug where onPause isn't being called on the web view in those versions of Android.

Handling this isn't simply a matter or calling onPause explicitly on the Web View if your app is targeting devices running Gingerbread or below. This is because those versions of Android don't have a public onPause method on the Web View.

The easiest way to handle this in a platform version independent way is to call the Web View's onPause method via reflection.

Class.forName("android.webkit.WebView")
         .getMethod("onPause", (Class[])null)
         .invoke(yourWebView, (Object[])null);

Playing Arbitrary HTML5 Videos


Web video players are very very fragile when it comes to playing arbitrary HTML5 video. Sites that host HTML5 video often rely on nuances that are present in some browsers or javascript engines but not in others. You may find that some HTML5 video just will not play in your embedded Web View.

Playing HTML5 Video Using A Native Video Player


While it is possible to create a custom WebChromeClient to intercept HTML5 video and play it using a native video player I would not recommend this. There are several problems with this approach that are very difficult to overcome.

  • You need to intercept ALL media playback events from javascript and handle them natively.
  • Handling all video related javascript events can only be accomplished by injecting javascript in the page or having direct access to the javascript engine.
  • Some pages dynamically load videos on the page which means you have to be monitoring the DOM for changes.

Rotation


Depending on how you handle rotation in your Activities and Fragments you may be accidentally reloading web pages on rotation. This happens when the call to loadUrl is made during the Activity or Fragment setup, since the rotation workflow causes the Activity or Fragment to be recreated.

This can be made even worse when the user had navigated several links deep into a web page. When the app is rotated and the Url is reloaded the user will find themselves back on the initial web page and not where they expect.

Handling rotation with a WebView can be done by: