Tuesday, April 8, 2014

Boise Code Camp 2014

This year I did a presentation at Boise Code Camp on "Creating Testable Mobile App with MVVMCross, Xamarin, Windows Phone, and Windows Store Apps.  At the request of some of the attendees here is my slide deck also here is the source code

Thursday, November 28, 2013

Testing un-mockable base class methods

Working on a project using the Xamarin Framework and came across a problem where I needed to see if a method was being called.  The problem was the method was on the base class and was un-mockable

To get around this I used a lazy load property and a delegate to create a wrapper.
   1: private StartActivityDelegate _start;
   2: public StartActivityDelegate Start
   3: {
   4:     get { return _start ?? (_start = StartActivity); }
   5:     set { _start = value; }
   6: }
   7:  
   8: public delegate void StartActivityDelegate (Type type);
   9:  
  10: protected override void OnCreate(Bundle bundle)
  11: {
  12:     base.OnCreate(bundle);
  13:     Redirect();
  14: }
  15:  
  16: public void Redirect()
  17: {
  18:     if (Preferences.HasRequired())
  19:     {
  20:         Start(typeof(ClientActivity));
  21:     }
  22:     else
  23:     {
  24:         Start(typeof(SettingsActivity));
  25:     }   
  26: }
To test it you simply set the property in my test class to a test method
   1: [TestFixture]
   2: public class When_Starting_SplashScreen_Without_Required_Preferences_Test
   3: {
   4:     public SplashActivity Target;
   5:     public Type Actual;
   6:     public PreferencesMock PreferencesMock;
   7:  
   8:     public void TestStartActivity(Type type)
   9:     {
  10:         Actual = type;
  11:     }
  12:  
  13:     [SetUp]
  14:     public void SetUp()
  15:     {
  16:         PreferencesMock = new PreferencesMock { HasRequiredStub = false };
  17:  
  18:         Target = new SplashActivity { Start = TestStartActivity, Preferences = PreferencesMock };
  19:         Target.Redirect();
  20:     }
  21:  
  22:     [Test]
  23:     public void Has_Expected_Activity_Test()
  24:     {
  25:         Assert.AreEqual(typeof(SettingsActivity), Actual);
  26:     }
  27: }
Next to test that we are calling the base class method we are expecting, we add a new test fixture and use a little reflection to get the method info for each and then compare them
   1: [TestFixture]
   2: public class SplashActivity_Tests
   3: {
   4:     public SplashActivity Target;
   5:     
   6:     [SetUp]
   7:     public void SetUp()
   8:     {
   9:         Target = new SplashActivity();            
  10:     }
  11:  
  12:     [Test]
  13:     public void LazyLoads_Write_Test()
  14:     {
  15:         MethodInfo actual = Target.Start.GetMethodInfo();
  16:         MethodInfo expected = typeof(Activity).GetMethod("StartActivity");
  17:         Assert.AreSame(expected, actual);
  18:     }      
  19: }

Wednesday, October 16, 2013

Steps for shortening the “Feedback Loop”

Information is the basic building block of software development and the most valuable form of information is useful feedback.  Feedback can come from the customer, the application’s users, and the development team. 


Regardless of the development methodology used the feedback loop is going to follow this basic flow


Looking at the Waterfall Methodology it’s very easy to see why it has become dated.  When you look at the basic flow 

The first opportunity for the developers to get feedback is at the end of the Verification stage.   Depending on the size of the project the Feedback Loop for Water Fall can take a couple of months to over a year.  This large gap between gathering requirements and implementing them makes it very difficult and costly to fix misunderstood or faulty requirements. 

What if the oil light in your car only gave you feed back every 30 min?   If you lose your drain plug, 30 min. is a long time to run without oil.  Software development is the same way, unless you’re getting regular feedback you won’t know something has gone wrong until it’s too late and you face costly refactors.

The hardest part of shortening the Feed Back loop is getting started.  It takes not only a change in behavior but also in thinking.  To quote a great American writer

“The secret of getting ahead is getting started. The secret of getting started is breaking your complex overwhelming tasks into small manageable tasks, and starting on the first one.”






Step 1: Short Development Iterations

A project may look large and complex but keep in mind the Egyptian Pyramids where built one block at a time.  By breaking tasks down into more manageable items you are able to focus on very specific requirements and get feedback on that specific requirement.  I personally like 2-week iterations; it’s enough time to get things done, without getting lost in the details.

Step 2: Work in Small Teams 

The old adage “too many cooks spoil the broth” is just as true in software development.  Large teams have the same problems that large tasks do; there is too much going on.  Large teams require too much coordination, reduce individual responsibility, and only the most vocal get heard.
It has been my experience that three to five developers works best.  With fewer developers the team can lack skill set diversity, and with more you run into coordination and crowd mentality issues.  Never have a team of one. 

Step 3: Test Driven Development

Test Driven Development (TDD) is creating software tests to verify requirements, and then writing the software to perform that behavior.  This provides the developer with a personal feedback loop to know that what is being created has the expected result.  This also provides the added benefit of built in regression tests.  

Step 4: Continuous Integration

Continuous Integration (CI) is the process of merging code as soon as possible and running tests to verify everything is working as expected.  CI can be done manually but is more commonly done with a build server such as Team City, Jenkins, TFS, or others.  This quickly gives software developers feedback regarding overlapping work, quality control, and overall code health.  This step will quantifiablly improve the quality of your code more than any other single task you do.

Step 5: Automate as much as possible

When automating tasks you are going to get quicker feedback, a consistent behavior, inherent documentation (by way of the automation script), and reduces overall costs by freeing up resources to work on more important tasks.

Wednesday, October 9, 2013

Death by Golden Hammer

The old adage “When all you have is a hammer, every problem looks like a nail.” is a very common problem in the software development world.  Developers may become proficient with a particular technology or tool set and use it to every problem, even to the point of excluding a more appropriate solution.  This narrow technological view has been nicknamed, “The Golden Hammer”.  There are benefits to having a very deep understanding of a specific technology stack, however t is more important to understand when to use an alternative.

A common Golden Hammer is using programing languages in ways they were never intended to be used.  For example, in the late 90’s the Perl programing language was very popular, and to some extent still is. With good reason, it’s an incredibly powerful and useful scripting language.  It was originally created for parsing text, which it’s really good at it.  It was so good at doing what it did, that people became very adept at it, and started using it for things it was never really intended to do; such as writing full applications.  Being a scripting language created for simple text parsing, its syntax was very loose and lacked the structure needed to create well formatted and maintainable code.  In spite of its shortcomings it was used far more than it should have been.

Another common Golden Hammer is using tools like Microsoft SharePoint or a content management system (CMS) such as:WordPress as a development platform.  These tools were built with the intent of managing content, and for the most part they do that very well.  The down side is when you start extending these tools beyond their intended use.  Using Microsoft SharePoint to build a warehouse order management system is like building a drag racer out of a school bus.  I’ve seen both done and it’s a prime example of “just because you can doesn’t mean you should.”  You can force tools to do what you want them to do, but it’s going to take a lot of customization and your end product, like the drag racing school bus, will never perform as well as if you had built it with the appropriate solution.

When looking at what tools and technology to use it’s just as important to look at what not to use.  One of the most valuable lessons I learned in high school was from my shop teacher:

“Learn to use the right tool for the job, not what’s most convenient. Screwdrivers are not chisels!”
Dallas E. Tolman


In the long run you will always be better off using the right tool vs. the most convenient one.  

Monday, October 7, 2013

Having the right tools can make all the difference

The ability to make and use tools is what separates humans from the rest of the animal kingdom; having said that, there is a difference between having a tool and knowing how to use it.  

When not developing software, I’m a woodworker. When I started building things, one of the first lessons I learned is that spending the money to get quality tools will save you money in the long run.  Chisels made from high quality steel can be made sharper, and will hold an edge longer, allowing the user to make cleaner cuts and reduce waste in materials and effort.  Quality development tools can do the same thing, with tools like intelli-sense, reference navigation, and auto test runners; we reduce the labor of development thus reducing the cost. The licensing for Visual Studio, Resharper, and NCrunch may look expensive until you look at the amount of time saved not having to wait for tests to run, not having to hunt through file after file when a method name is updated, etc.