3rd Time Often Is The Charm …

me10The expression “the third time’s the charm” references the concept of eventually reaching the *right* solution after a some unsuccessful attempts.  Believe it or not, the neurons in the decision-maker’s brain could be influencing the decision more than one might expect.

As an example, let’s assume that upon analyzing the current state of an application, you architect/design enhancements to resolve issues that either a) currently exist, b) may surface down the road, or c) both.  However, after presenting your ideas, the decision-maker decides to forgo implementation of the recommendation.

Now, let’s assume that over time the decision-maker receives similar (if not the exact same) recommendations by other individuals experienced with the application.  Often times this happens after the original architect/designer (“you” in the example above) has moved on to other tasks and responsibilities.  In more cases than not, the decision-maker accepts the recommendation after hearing the same suggestion multiple times.

Initially, I planned to focus on how often I have witnessed this scenario during my career.  (Keeping in mind, a majority of times that I have seen this happen I have merely been a casual observer.)  My goal was to relay the message that this situation still exists.  Instead, I decided to take things a step further – to try to see if I could figure out why this pattern has continued to repeat itself over the years.

Earlier this year, Tübingen neuroscientists concluded that decision-making processes are influenced by neurons in our brain.  They cited the simple of example of how the brain reacts when seeing someone on the other side of the street who resembles an old friend.    The neurons in our brain often use the memories of the relationship from the look-a-like friend to determine how we will react when our paths cross with the individual on the other side of the street.

In our example, when the decision-maker realizes that the same information is being presented, it brings up memories of the prior recommendations that were suggested.  These memories eventually alter the decision in favor of implementing the design enhancements.  As a result, your long overdue recommendation is finally about to be put into place.

During the course of my career, I have experienced being the person making the recommendation and also the person repeating past recommendations which were eventually accepted.  Interestingly enough, it seems like the original architect/designer often receives the label as being “on the bleeding edge” or maybe even “too aggressive.”  While, the individual delivering the recommendation on the time that it is accepted by the decision-maker seems to always receive the label of “hero.”

It is common to focus on the lost time and additional efforts required to convince the decision-maker to finally accept your recommendations.  However, stepping back and looking at things from a higher level, everyone involved should feel proud that the needed enhancements were eventually accepted.

Advertisements

Unit Testing … worthwhile or a waste of time?

me5The idea of Unit Testing has been around for quite some time.  Adapatibility seems to vary – both at the client level and within time periods for a given client.  The biggest trend (for adopters) I’ve seen is heavy usage of Unit Testing for a period of time followed by heavy discontinuation of Unit Testing.  This leads me to wonder if Unit Testing is still worthwhile or just a waste of time.

What Is Unit Testing?

To briefly walk through what Unit Testing is all about, consider the following (very simple) example:

public void processStudent(Student student) {
   // Get current course list for student
   List courseList = studentService.getCourses(student);

   for (int i = 0; i < courseList.size(); i++) {
      Course courseObject = (Course) courseList.get(i);
      determineGrade(courseObject);

      // Other tasks for the list of courses
   }

   // Other tasks for the student being processed
}

private void determineGrade(Course courseObject) {
   // Will determine grade based upon several factors
}

The program code noted above is intended to process various events for a student.  One of those events would be to get a list of the current courses the student is taking and the other would determine the grade for each course.  So, the entry point would be the public method called “processStudent” and it would call the private method “determineGrade” which would update attributes of the Course like the letter grade (A, B, C, etc) and the grade percentage (i.e. 97.9%).

The goal of Unit Testing would be to build scenarios using program code that would make sure all the situations are covered.  The simplest way to think about this would be to consider the “determineGrade” method.  Certainly, we would want to have a test case that would validate the correct letter grade is returned.  So, there would be a test that makes sure a letter grade of A is returned when expected.  The same would be true for the other letter grades.

We might even want to include a test case for every edge scenario too.  In this situation, perhaps we would consider the grade percentage.  Maybe a 94.9% grade percentage would be rounded up to a 95%, which might be the cut off for a letter grade of an A.  So, one test would use 94.9% yielding a grade of an A, while another might use 94.8% (or whatever the cut-off rule becomes) to leave the grade at a B.

What’s the Benefit?

Unit Testing is intended to provide the following benefits:

  • Allow the developer to validate the program logic is functioning as intended.
  • Catches issues before the logic is released for testing, avoiding wasted Tester time.
  • Helps to document the program code’s intentions.

One other benefit to bring up is that Unit Tests can be part of the build/deploy process.  So, before program code is delivered into the Test environment, all the Unit Tests that exist can be executed.  If they fail, the deployment to the Test environment is suspended.

The benefit to taking such an approach is that Unit Testing can catch unexpected problems when a change was made.  Using our example above, perhaps a change was made to something with the Course object.  Doing so caused the logic in the determineGrade method to require updates which were not made.  As a result, the test results started failing and ceased the deployment to the Test environment – avoiding having the Tester test an environment that was already known to have issues.

Worthwhile or a Waste of Time?

From a programmer’s perspective, I believe Unit testing will always have a place in the software development life-cycle (SDLC).  Within the last couple of weeks, Unit Tests that I have written uncovered minor issues with the logic that has been developed.  In one case, a logic condition was actually removed because it would only generate a business exception – since there was not a valid way to fall into that scenario.

However, decisions are not always made from a programmer’s perspective.  Given the investment required in building valid Unit Tests, this time is often the first to be cut when a project needs to meet a certain deadline.  As a result, I believe this is how the “heavy usage of Unit Testing for a period of time followed by heavy discontinuation of Unit Testing” situation (noted above) is born.  Unfortunately, recovering from this situation will likely take more time than if the Unit Test programming wasn’t suspended in the first place.

Advanced Topic – Private Method Testing

One last item I wanted to bring forward, is something I introduced on my current project.  That being the concept of writing Unit Tests at the private method level – and not just the public method level.

In the example above, the processStudent method was a public method and available for Unit Test frameworks to see without any issues.  The method is public and available to all who have access to the program class.

However, the determineGrade method is a private method.  Basically, the logic in this method was not intended for other classes or services to utilize. So, the decision was made to hide this method and make it private.  Out of the box, Unit Test frameworks cannot see these methods.

With my current project, there are several private methods that are used multiple times.  Instead of writing Unit Tests against the public methods, I wanted to write Unit Tests which would fully exhaust all the permutations for the private methods.  Then, I would only have to write Unit Tests to fully test the code at the public method level.  Doing so, would actually a) cut down on the number of Unit Tests that were truly required and b) provide better documentation to understand the desired intent at the method level.

Using Reflection and a great article by Bill Venners, I was able to accomplish my goal.  In fact, a utility class called TestPrivateMethod was created to contain the common elements for other Unit Tests to use.

Conclusion

I hope this blog, while long and a bit technical, was a worthwhile read.

If possible, I would like to hear from you either via comments or using the poll listed below.

When the Dream disappears from your Dream Job

me2Recently, a friend encountered a situation at work where his dedication was causing him an additional amount of work.  He was convinced that he was getting more items added to his workload, since he was more responsible or focused than his peers.

I found out about the situation, because we had planned to meet at his house one day after work.  When he didn’t show up and I asked if everything was okay, he provided the background information.

I could tell my friend was  frustrated at what his “dream job” had morphed into – due to his desire to be a dedicated, responsible and focused individual.  Up to this point, he was excited to head to work each day.  Now, he walked with his head down … wondering what unexpected item might be added to his list.

Thinking back at my prior jobs, it was easy to find similar situations that I have encountered.  Interestingly enough, it seems like in more cases than not, the “dream” disappears from your dream job due to circumstances not related to the job itself.  Even more so, those dream-job killers are not items one expects to encounter prior to accepting employment in the first place.

In my friend’s case, it was an over-abundance of work.  I tried to paint his situation into a compliment, but it just was not happening.  You see, for him to get all of this work done, he has been putting in a tremendous amount of additional hours – which has started to impact the relationship with his family and commitments outside of work.

I would say the biggest dream-job killer has to be related to peer jealousy.  In this situation, the peer (whether it be a coworker, manager/supervisor or even someone at the executive level) has made the conscious decision to oppose you working with them.  Depending on the peer’s level of influence, the impact to your dream job can be minimal or can be intolerable.  Thus, the ability to “keep the dream (job) alive” can range from turning to the other cheek or (eventually) turning to alternative places of employment.

With my friend, I don’t expect him to look for alternative places of employment.  If I know him like I think I do, he will simply ride through this wave of extra work and hope it calms down soon.  I told him though, if it only gets worse, I am certain he will find another dream job opportunity.  The pearl from his experience is that he’s been through this type of situation now and can use that experience to help him in the future.

For me, I try to take not only the great things from my prior employment opportunities, but also take the not-so-great things as well.  Those who know me often hear stories from both sides of my prior job experiences.  The cool thing is these experiences all have the following things in common:

  • They are in the past – no need to worry about them.
  • I learned something from the experience – to keep in mind and hopefully not repeat.
  • They tell a story … one which I will try to use in order to make someone smile.

When I left a not-so-great job years ago, my dad reminded me “you were looking for a job when you found that one, so go find another one.”  He would have been 71 years old this month and that is probably the one piece of advice I remember the most from him.

Just remember, there is always a dream job out there for you!  You just have to look for it.

We Were Both Right, But I Was Wrong

me3Similar to my last post, I wanted to continue down the Requirements path – to discuss a situation I ran into several years ago.  This was a situation where the Application Owner and Information Technology (IT) were both correct, but someone had to wrong.

At the time, I was a Developer/Business Analyst combo (times were tough back then) and the Subject Matter Expert (SME) had worked with the Application Owner for over 10 years at the time.  They worked together on a daily basis and both had a very strong background on the business needs the application was designed to fulfill.

The enhancement life cycle (if we can call it that) was that the SME spent time with the Application Owner in order to understand what features he wanted to see.  She would provide feedback on the impact to the end-users, since she maintained a strong relationship with the user-base.  Once they were ready, they would bring the enhancement request to IT.  After I reviewed the request with the SME, I looped my supervisor in on the changes and then started documenting the requirements.  Once they were complete, the SME reviewed/approved the requirements and development started.

Throughout the development process, I would have the SME check what had been put into place at that point.  This was before Agile Software Development had gained momentum, so it was more of an iterative approach.  As the feature reached completion, the SME and I were both impressed and excited about our solution.

We deployed the changes into the Test environment and setup a meeting to demo the enhancements to the Application Owner.  My supervisor decided to join us.  We all expected to enjoy a round of “high 5’s” after the demo was complete.  In our view, this was merely a formality before deploying the fixes to the Production environment.

The Application Owner sat through the demo and didn’t really say much.  I didn’t put too much stock in his reaction at the time, since the guy always had a million things on his mind.  When we finished, he looked at us and announced, “this is not at all what I expected to see.”  I know my mouth hit the floor, as did the SME’s.  My supervisor’s face turned a shade of red, which matched the reddish tint in his hair.

We walked through his expectations during that same meeting.  He was right, what he expected to see was not what we had built.  Fortunately, a great deal of the underlying components and design were not impacted and the time to fix the application was measured in hours and not days or weeks.

In the end, when you look at what was developed initially and what was ultimately deployed into the Production environment, both solutions achieved the needs noted in the requirements documentation.  Of course, both could not be right, so one of them had to be wrong.  Since the Application Owner was the customer and I (as an IT employee) was the IT solution provider, I had to be wrong.  I was okay with that.

I have struggled trying to figure out how to prevent this scenario from happening.  Mind you, this is not a common scenario, but one that has happened enough over the years.  I would have never expected the SME to be that far off from the Application Owner’s vision.  After all, they had worked together for 10+ years and both had a great understanding of the problem they wanted to solve.

I wondered if more screen shots or even a wire-frame might have helped.  But at the same time, I would not have expected the Application Owner to get involved at that level – remember, the guy always has a million things on his mind.  I am certain the extra documentation would have been overkill at the time – since the SME and I were on the same page.

In the end, I think this is one of those situations where the problem has to occur once.  Then, when additional features are requested down the road, it will be easy to ask that the Application Owner be looped into the process periodically.  Making this suggestion prior to running into this scenario could impact the relationship with the SME, which I don’t believe is worth the risk.

The Challenge for Complete Requirements

J. VesterDuring a recent project, our team faced that common challenge for complete requirements.  While trying to extract additional requirements, the Subject Matter Expert (SME) responded with “I don’t know if I can tell you the right answer, but I can certainly tell you when I see something that is wrong.”  The project manager struggled with this statement, because without complete requirements, there is really no way to determine the scope of what remaining work still needs to be completed … and provide target dates to senior management.

In all actuality, the SME’s approach is more in line with reality than probably anyone would want to admit.  After all, SME’s often are delegated into the role and often do not truly possess the necessary knowledge needed to document all the requirements.  Furthermore, they rarely think about requirements in the manner that Information Technology (IT) professionals expect.

In my example, certainly 80% of the requirements were noted.  However, 80% is not 100% complete.  Unfortunately, the road to complete that final 20% can end up taking more time than the work completed for the initial 80%.  This is because the 80% is often the “low hanging fruit” that is easy to document, design and test.  The remaining 20% mostly consists of rare situations (or edge cases) that are not expected or common.

A solid design of the business rules, should help expose some of these rare situations.  However, in order to do so, the developer must think beyond the requirements received.  Realizing that interactions with the SME would be limited, I opted to catch the rare situations and stop processing at that point.  A custom error was displayed in the application, which would allow the testers to interact with the SME in order to obtain the right direction.  Using this approach, we were able to get closer to 100%, but this was certainly not a “silver bullet” that could always solve the problem of incomplete requirements.

Unfortunately, to reach the 100%, iterative design and testing between IT and the SME is likely to be required.   These tasks are often difficult to estimate and outline ahead of time.  So when this point is recognized, the decision should be made whether a) the project manager and senior management simply allow the iterative effort to continue or b) the design is deployed in the current state – documenting any defects that surface and fixing them in a future release.

In any case, as this knowledge is recognized, it is vital that the underlying requirements be updated and communicated.  Doing so could shed light in other aspects of the application where similar edge cases exist.