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.
To test it you simply set the property in my test class to a test method
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
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: }
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: }
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.
Subscribe to:
Posts (Atom)