Mock objects and Testing
March 15th, 2009
This has been a much discussed topic over the web in the last couple of years. I was responding to one of the emails at work about mock objects. While organizing my thoughts about Mock objects, I decided to write this post.
Various thought leaders in TDD promote Mock objects. I agree with some of it but not everything they say.
Some caution towards using Mocks extensively:
-
Using Mock objects might affect design decisions:
-
The mocked classes (and the methods used to set up expectations) cannot be final. If called, their normal code may be executed. I prefer making every class either final or abstract unless there is a strong reason to not to do so.
-
A class with only private constructors cannot be instantiated.
-
The behavior for equals() and hashCode() when using mocks may not be what you normally expect.
-
Private methods cannot be mocked. I prefer making every method private unless there is a strong reason to not to do so.
-
-
Trustworthiness & ROI of Mocks: Mocks may hide integration problems and push the burden on other tests. High-level and End-to-end tests give the most ROI, in my opinion. I would value these over the unit tests that use mocks extensively when constrained by Time & Resources. Most of the times, I have seen that tests using mocks extensively completely miss the intent of the test..!
-
Increased complexity and maintenance costs - Setting up mock object expectations create clutter and duplication to test code. Mocking Fine-Grained or Chatty Interfaces results in a lot of brittle unit-test code. High-level tests may not require such extensive changes.
-
It is a well-known fact that unit tests (that use mocks extensively) don’t catch as many bugs as the integration/high-level tests.
I do not want leave an impression that I do not like the idea of using Mock objects for testing. We just need to use it for the right things and right places after understanding it’s rewards and risks, just like any other tool/framework.
Mocking is still suitable for various scenarios that include:
-
Testing sub-systems that don’t exist yet or are being developed separately. But, then after the dependent code is available, I would switch back to real code from mock objects.
-
Legacy code that does not have interfaces and is tightly coupled.
-
Sometimes we may need to mock only some methods of a class and keep the normal behavior of others.
-
Testing against slow/heavyweight components that have significant dependencies.
-
To simplify Unit testing when there are no alternative ways to test the same effectively (for example, if the dependent component is very hard to setup/configure, etc.).
IMO, choosing the right scenarios objects (if any) for using Mock objects is the trickiest part.
I personally avoid using Mock Objects (unless there are no other easy options) by using good OO Design & Programming practices to write my code such that it is testable without having to use Mock Objects.
Feedback for improvement in agility
February 18th, 2009
Last week, during a casual chat with our Agile evangelist, I asked about what could be improved in our team based on what he observed.
He quickly said that it depends on a lot of things and that it is difficult to give feedback without being part of the team. He asked me to pose that question to the team. We already do that in retrospective meetings.
But, after pushing further to get some high-level things that we could improve upon, he gave me a few suggestions:
- Adopt pair-programming for every line of code that we write.
- Increase the level of communication between team members
- Everyone needs to really pay attention during stand-ups
- Work towards overall team productivity rather than individual productivity
- …..
My immediate reaction as soon as I heard “pair-programming for every line of code” was to point out that it may not be the right thing to do all the time. Now, I realize how stupid I was..! I was asking for feedback. I should have shut my mouth and should have treated every piece of advice as a compliment. I did thank him for his time, however.
This was very valuable feedback. I need to apologize to him tomorrow for arguing with him even if I did not completely agree with his opinion.. ![]()
Agility and large Backlogs
January 11th, 2009
Backlog is used for prioritizing, tracking and communicating the work (work items) to be done in the future Iterations/Sprints.
There may be multiple teams working from one backlog, but if there are more than 3-5 sprints worth of work items for all teams working on that backlog, then I consider that to be huge. I have noticed that if the product owner is not careful, the backlog can grow and become really huge.
This is not good for several reasons:
- It is depressing for the everyone on the team. This may lead to a belief among team members that this is a case of a large product with not enough resources.
- Priorities change - It is a waste of effort for the product owners to endlessly sort through the work items in the backlog every Sprint to come up with a list of stories for a Sprint.
- Some of the items in the backlog are never worked upon even after months/years. In that case why spend effort prioritizing them?
- It is hard to react to change in the market conditions, when the teams are so focussed on possibly “stale” requirements in a backlog.
So, what are the possible causes for this?
- Lack of clarity of product vision.
- Disagreements between the product management and marketing about the importance of features. So, the “unimportant” ones (mostly due to disagreements) find the bottom of the backlog.
- Product owners unable to decide on the “business value” and ROI on requirements in the backlog. This may be due to the lack of authority (to do so) or communication breakdown or just the organization culture itself.
- Sometimes, for various reasons, a suite of products might have one product owner per product who do not necessarily agree on everything especially when it comes to the cross-product requirements.
- Inadequate resources, unstable team, attritions, shuffled team members, not-so-well-performing teams, etc.
- Treating defects as backlog items. Sometimes, a lot of medium defects are tossed in to the backlog.
- Poor/Complex Technical Architecture - This means that the features get done much slower than estimated.
Requirements - Product Owner and Customer
December 13th, 2008
One very important thing that I have learnt from my consulting experience (dealing directly with Clients for building solutions) and in my experience of building exterprise products is:
When you are given a set of requirements, always understand the requirements in terms of what problem of the Customer (an actual client or the product owner) is this requirement trying to solve, instead of just treating the requirement as a feature or an enhancement request.
This may sound very simple, but it has far reaching implications in building great products/solutions. With a good understanding of the inner workings of the product or the architecture or technology or just out-of-the-box thinking, sometimes certain extremely simple alternative solutions might just do the trick with very little or almost no work/re-rework required..!
This was reinforced by one of the examples given by Mary Poppendieck in the Lean Management principles presentation I attended recently:
In the Military/Army, the communication given to the soldiers consists of just 2 things:
- End State
- Command Intent
So, the “Stories” or “Requirements” should specify the “what” and not the “how”.
Performance tuning vs. Lean/Agile
November 6th, 2008
I am currently working on performance tuning & refactoring a product. And, interestingly I found some Agile/Lean principles that apply for performance tuning and refactoring:
- Most Lean principles appear counter-intuitive at first
- Aim for system optimization instead of point optimization
- Build prototype and measure (run quick experiments), not just theorize
- Minimize the number and size of things-in-process
- The most predictable performance comes from maintaining options until you have the most information
Lean Software Development
November 3rd, 2008
I had an opportunity to attend a one-day lean manager’s workshop (by Mary and Tom Poppendieck) organized by my employer at my workplace.
It was so much different than the other similar workshops I attended in the past:
- The whole talk was so cohesive - Mary and Tom constantly focused on a few core principles approaching from various perspectives. They arrived at the very same conclusions by using examples and data from various Industries/Verticals in a very lucid style.
- Another thing that resonated with me was the application of Scientific principles from Queuing theory, Fluid dynamics and emphasis on using actual measurements as data to improve. Also, they used some examples/directives from the Military/Army manual (on communication) and applied them to Lean/Agile Software development.
I will be blogging more about what I learnt and how I plan to apply them at work.
Continuous Integration on a grand scale
August 17th, 2008
All the individual products in our organization use continuous integration development practice. However, all the products are built by different teams (with different skill-sets) under Sprints that do not share the same boundaries.
Some of these are complete products by themselves. They also are bundled together in a suite and so require integration testing. How do we apply continuous integration practice on a grand scale to this problem?
We ended up making these decisions:
- The individual product team (with “inward” dependency) shall take the responsibilities of writing/maintaining the integration test cases.
- We decided to push the individual product builds into this environment every week, mostly and also have the flexibility of being able to push the builds on demand, if necessary.
- Start with a basic set of integration test cases and build upon them to keep it simple/Agile.
- Start with manual steps to deploy these individual product builds into the integration environment and then slowly build a set of scripts to automate this.
- Eventually, we should have a “push-button” integration environment where individual teams can push a button or set up rules to promote their builds in to this integration environment.
- Decide that all teams should eventually move to a single source repository.
- Initially, to keep it simple, all of the individual product teams will push only binaries into this environment.
- We agreed upon a simple defect tracking process for reporting/escalating integration testing bugs.
5 not-so-Agile practices with SCRUM
July 21st, 2008
I have come across several articles on the best practices for Agile/SCRUM.
I read this somewhere and really liked it:
There is not and never will be a list of “Scrum Best Practices” because team and project context trump all other considerations.
Here are 5 practices that may be considered as “not-so-agile” by purists. But, making the following changes to our Agile/SCRUM process actually made us a very effective Agile Organization..!
-
Dedicated Testers & Writer on the SCRUM Team:
This could be against the “No specialization” or “No fixed Roles” Agile principle.
-
Minispecs:
This could be against “use the working code as documentation”. We use MiniSpecs very effectively to document key requirements and design/implementation decisions in a concise manner.
-
Our SCRUM Master is our Sr. Director/Manager:
This is self-explanatory. Our Manager is actually a certified SCRUM Master with two decades of development experience. He demonstrates great balance.
-
Team members shared across teams:
We have a UI specialist and an Architect/Developer shared across 2 teams. I guess it might make sense to share the UI specialist. The Architect/Developer shared across teams has helped us immensely improve communication and to effectively sort out integration issues across the products in our Product Suite.
-
Multiple backlogs for the same product suite:
Okay. This one might be up for debate. Our Product suite consists of at least 5 products that have their own SCRUM Teams. There is also a Product Owner with individual Product backlog for each of these products. Also, there is a common backlog for infrastructure/common functionality.
How SCRUM/Agile affects typical roles in Software Development
July 20th, 2008
I have been using SCRUM and XP principles/practices since early 2003 for various software projects.
Here is my take on how SCRUM/Agile software development has affected the typical roles in Software development for the Organizations adopting SCRUM/Agile.
Management, Leadership:
Customers/Clients:
Product Owners:
SCRUM Team/Developers: