I head out to Fullerton tomorrow for the start of my .NET TDD Kickstart world tour Smile

In this session, the speaker and the audience will "pair up" for a coding session which will serve as an introduction to Test Driven Development in an Agile environment. We will use C#, Visual Studio and Rhino Mocks to unit test code to be built both with and without dependencies. We will also highlight some of the common issues encountered during TDD and discuss strategies for overcoming them.

I will be presenting this session at numerous venues around the country this year, including, so far:

If you are interested in having me present this or another session at your event, please contact me.

There is much more than an hour’s worth of material to be presented, so instead of trying to rush through everything I want to talk about during this time, I’ve instead taken some questions from this presentation and posted them below.  Please contact me if you have any additional questions, need clarification, or if you have an suggestions or additions to these lists.

 

Unit Testing/TDD FAQ

Q: What is the primary goal/benefit of unit testing?

A: Having solid unit tests allows the developers to refactor without fear.  That is, they can much more easily maintain and extend the application.  Since the majority of an application’s cost is in maintenance and extension, helping to reduce those costs can significantly impact the total cost of ownership (TCO) of an application.


Q: What does TDD give us that we can’t get by building tests “after the fact”?

A: I can think of four main advantages to doing test-driven development over “test-later”.  Please let me know if you come up with others:

  1. To make sure the tests get done -- It is very easy to forget important business rules when building tests after the code has been written.  TDD helps to guarantee that all of the important features have valid tests written for them.
  2. To help define the problem before solving it – Stopping before building and defining the problem in terms of a test is very helpful for gaining insight into the problem. Often, I have eliminated what would have likely been some significant rework by building my tests first.
  3. To force “design for testability” – One of the worst things about writing tests is having to go back and change working code because it isn’t testable.  By doing the tests up-front, we guarantee that our code is testable before we even write it. In addition, since testable code is generally decoupled code, TDD helps to enforce a good standard that also helps reduce TCO.
  4. To help prevent scope creep – It is often easy to creep the scope of a development effort by including features that are not currently required, because they seem easy when doing the development.  If, however, you require yourself to build tests for each feature first, you are more likely to reconsider adding features that are not currently necessary.

Q: What are some of the common pitfalls of TDD/Unit Testing?

A: Some of the pitfalls I have discovered over the years are listed below along with some suggestions for avoiding or overcoming them:

  1. Brittle tests – It is easy to create tests that break when later functionality is added. Newer versions of mocking frameworks have helped with this problem by introducing mock types that demand that stated expectations are met on mocked dependencies, but don’t fail when additional interactions with those dependencies occur.  As an example, in Rhino Mocks, you should use a DynamicMock object when it makes sense, rather than a StrictMock because the tests created with a DynamicMock are less brittle.
  2. Missed features – I highly recommend creating a specific test for each feature, even if the test is an exact duplicate of another test. The reason for this is that, in the future, those features may evolve independently, and it is likely that the one test shared by both will be modified to fit the first feature that changes, leaving the second untested.
  3. DateTimes don’t validate well – When comparing DateTime types, it is often difficult to get accurate results due to the rapid change in the current time and the varying degrees of precision of different time types.  I have found it best to use a tolerance wherever possible in my DateTime testing.  For example, I have created a custom Constraint for Rhino Mocks called a DateTimeConstraint that allows me to specify the tolerance that I will allow in my tests.  That tolerance could be to the millisecond, the second, the minute, or whatever makes sense for that test.
  4. Type specific values don’t compare well – An Int32 with a value of 12345 is not the same as an Int64 with the same value. Be careful when comparing data types, even if the value in those types should be the same. It is often best to cast or convert the value with the lesser precision, to the other type.
  5. Testing using shared resources is difficult – While there is much discussion about what you call a test that touches the database, or another external resource such as a message queue, there is no doubt that interactions with those types of resources must still be tested.  If the database or queue you are using is shared, it is possible that data can be manipulated during your tests, making these tests imprecise at best.  Whenever possible, you should isolate these tests by using local resources if possible, or by creating the resources specifically for the test.  That is, if in your test you create a message queue using a GUID defined in your test as the name of the queue, then use that for your tests and destroy the queue at the end of the test, you can be reasonably confident that no other user will be manipulating the data in that queue during the test.
Tags: , , , | Categories: Development Posted by bsstahl on 1/17/2012 12:35 AM | Comments (0)

I noticed something interesting with Rhino Mocks today while testing some demo code:

Rhino.Mocks.Expect.Call(myDependency.MyMethod(param1)).Return(result).Repeat.Times(5);

behaves as I anticipated; it expects the call to MyMethod to be repeated 5 times and returns the value of result all 5 times. Meanwhile:

Rhino.Mocks.Expect.Call(myDependency.MyMethod(param1)).Repeat.Times(5).Return(result);

also has the expectation of 5 executions, but it returns the value of result only once. The other 4 executions return 0.

When I think about it now, it makes sense, but it wasn't the behavior I originally expected.

Tags: , , , , | Categories: Event Posted by bsstahl on 10/13/2011 12:29 AM | Comments (0)

It's AZGiveCamp time again! Our third event is coming up in under 2 weeks, Oct 21st-23rd 2011 at the Park Central Mall (Central Ave. between Thomas and Osborn) in midtown Phoenix. Please sign-up to volunteer as a developer, designer, or analyst at http://azgivecamp.org/Volunteer.aspx.

Special appeal: we need graphic designers! If you’re a pro or amateur, it doesn’t matter. Designers are always the most popular people at any GiveCamp!

Those who participated in the last 2 events already know that AZGiveCamp is the local component of a national event where the software development community comes together to support local charities and non-profits by developing or improving their web sites and applications. It's fun, it's agile, it's geeky, and it's good for the community.

We had a fantastic time at the last 2 events and, in Arizona alone, have helped more than 20 non-profits with their development needs. As someone who has now participated in GiveCamps as both a participant and as an organizer, I can honestly say the experience is very, very, worthwhile.

You can find out more about AZGiveCamp at http://azgivecamp.org and about the national organization at http://givecamp.org.

I am very excited about this event and look forward to working with all of you at AZGiveCamp III.

Tags: , , , , , | Categories: Development, Event Posted by bsstahl on 8/25/2011 6:14 AM | Comments (0)

http://www.pluralsight-training.net/microsoft/webcasts/index?utm_campaign=Newsletter&utm_medium=email&utm_source=VR

When I started at Arizona State University (ASU) about twenty-six years ago, I’d already been programming for five or six years, and building applications for a year or two. I’d done things like create hacking tools and WarGames dialers for my own use, and I’d built a few applications for businesses where I was doing lookups and filing information that was specific to that business, but all of that was very heavy on code and light on technique and reusability. I knew how to use variables and arrays, I knew how to make the computer do what I wanted it to do, but I didn’t know how to write good code. At ASU, there were two classes that I had take freshman year that were part of the Engineering & Applied Sciences core, that really woke me up to the world of Computer Science and the things that we, as engineers, can do with our code. Those classes were “Data Structures in Pascal” and “Discreet Mathematics”. These two classes are really the only classes where I have specific memories of the things I learned so long ago.

I remember, very clearly, in the data structures class, learning about linked-lists. I remember the realm of possibilities that I saw when introduced to this data structure. This really very simple data structure showed me tremendous power as a flexible, reusable foundational element, that dwarfed arrays and the other tools I knew at the time. Linked lists showed me how I could hold the same values as I held in an array with addition metadata that gave me the tools to access the values in a different way, in a way that made more sense for the use-case. I saw in these structures a tool I could use to build reusable frameworks that could operate on data in a way that was much more use-case specific. For example, I could use linked-lists to create a queue structure. Then, if the use-case dictated, I could extend that structure to hold a priority and make the queue priority based. These things, while possible just using flat arrays, were much more difficult and harder to reuse. Other structures like binary-trees had impact on me as well, but nothing like the fundamental power of the linked-list.

I remember, in the discreet math class, learning about algorithms that were, in effect, practical uses of math for programmers. Although that class was not officially geared towards programmers, it was very easy to see why it was a core requirement for the College of Engineering & Applied Sciences. I remember learning about various sorting algorithms and encryption methods, optimum path algorithms and best-fit criteria. Basically, I learned ways of applying mathematics to everyday problems I faced when writing code. As with the data structures class, my horizons were significantly expanded by this knowledge and I have used these tools, and my understanding of these tools, to some degree every day since.

For me, making the decision that I wanted to be a software engineer, as opposed to a hardware engineer, didn’t occur until after I started college. The two classes I have described, had a big impact on proving to me that my talent, and my passion, was for software and that programming was the path that I wanted to take in life.

Now, I see an opportunity, 26 years later, to refresh my memory and update my skills on some of these topics. There have been many changes in software engineering since my time in college. The .NET Framework now provides many of the foundational structures I use daily, and, with the help of generics, those structures will often work in a strongly-typed way on any data type I choose. These topics helped establish the course of my career and I am looking forward to seeing how the tools, and the use of these tools, has changed over time. While I realize that I cannot recreate the “eureka experience” of my original awakening, and that you cannot squeeze 2 full-semester classes into a 1-hour presentation, I am still very excited about attending the Pluralsight webcast on Algorithms and Data Structures tomorrow.

Categories: Development Posted by bsstahl on 7/30/2011 2:25 AM | Comments (0)

Warning: Speculation Alert!

While attending the Pittsburgh GiveCamp, I had something of an epiphany about Microsoft’s HTML5 strategy. Looking back at it now it seems so obvious, but at the time it felt like a revelation, so I want to share that experience with you.  You should be warned however that this is not based on any actual knowledge.  I am not a Microsoft insider and I have no information that any other developer who uses Microsoft technologies doesn’t have access to.  These thoughts are purely speculative, but they make sense to me so I felt the need to share them and I look forward to your comments.

I believe that Microsoft will make HTML5/CSS3/ECMAScript a 1st-class language within the .NET stack.

Right now, just about everything that can be done in HTML5, can be done in Silverlight and WPF.  Because Microsoft has already spent the time and effort building those technologies into the .NET Framework, there is already the capability in the Microsoft Intermediate Language (IL), which all .NET code compiles down to, to support the actions that might be needed in an HTML5 application.  Certainly, the standard HTML UI elements have an equivalent in the XAML-based world of WPF and Silverlight.  In addition, there is already style support similar to CSS, and we know there is strong programmability support.  So, when you get down to it, all of the framework pieces are in place to compile an HTML5 application into IL.  Once compiled, most likely into an .exe file, this HTML5 application could be executed in exactly the same way as any Windows desktop application.  I believe Microsoft will be announcing this capability as one of its key features of .NET 5 at their Build conference in September to take advantage of the marketing synergy between the .NET 5 and HTML5 brands.

Can you imagine a workflow where you use File –> New Project in Visual Studio to create an HTML5 project, build HTML5 pages along with your script, style and other resources, and then can publish the project as either a standard HTML website, or as a .NET executable file to be run on Windows 8, or even earlier versions of Windows if they have the .NET framework 5.0 installed?  I can imagine it easily, and I like what I see when I do.  This may be why Microsoft is billing the Build conference as for more than just Professional Developers.  That is, web designers and hobbyists will now also have the ability to create Windows desktop applications simply by utilizing the web skills they already possess.

As for the future of WPF and Silverlight, I speculate that, if Microsoft takes the path that I have described, it practically ensures the survival of the XAML technologies.  The HTML5 spec will be constantly evolving and Microsoft will need to continue to add features to the framework to support those new capabilities.  Once in the framework, Silverlight and WPF can add those same or similar features for almost nothing, simply by adding the language support in XAML or C#/VB.Net.  Microsoft will also have two platforms available in Silverlight and WPF to use to test features that are not yet in the HTML5 spec.

It is likely that there will be some consolidation in the future between the two XAML-based technologies, but that was anticipated long before there was any talk of HTML5 as a viable alternative and is not a result of any policy change due to the existence of HTML5. However, HTML5 is looking, for better or worse, like it will become a major player in cross-platform software development. I suspect that many developers who might otherwise have picked-up Silverlight will choose to learn HTML5 instead. In the long-term, if that becomes a significant trend, then eventually WPF and Silverlight will be phased-out.  However, I don’t see that happening anytime soon. In facet, as I mentioned, I feel the synergy with HTML5 found in these technologies makes them stronger in the short and medium term and they will continue to be players in their various spaces for many years.

 

Tags: , | Categories: Event Posted by bsstahl on 6/28/2011 6:47 PM | Comments (0)

On a personal note, I’ve signed-up to play in the Reggie Sanders Foundation’s Wiffle Ball tournament which is part of the MLB All Star Weekend.  The event is being held at Salt River Fields at Talking Stick on Saturday morning, July 9th at 9am.  On hand will be former MLB players and other celebrities and the event is to benefit the Southwest Autism Research and Resource Center (SARRC).  If you are interested in playing, sponsoring, or attending, please contact John Zackery at (602) 421-3479 or by email at jzackery (at) gmail (dot) com.

Tournament Flier

I previously posted the slides for my Building Enterprise Apps using Entity Framework 4 talk here.  I can now post the source code for the completed demo application.  That code, created for use in Visual Studio 2010 Ultimate, is available in zip format below.  This is the same code that was demonstrated at Desert Code Camp 2011.1 and SoCalCodeCamp 2011 as well as the New Mexico .NET User’s Group (NMUG).

EF4EnterpriseDemoCode.zip

Categories: Development Posted by bsstahl on 6/20/2011 6:03 PM | Comments (0)

StackOverflow has a fantastic list of programming terms that have been coined by the development community recently.  Some of the best, most appropriate terms are documented below.

Automanually
Used to refer to a batch job or application that should be scheduled or triggered automatically, but due to unspecified reasons requires manual intervention every time. (not the same as automagically)
Boolean Zen
The proper practice of using boolean expressions directly without testing for equality to true or false.
Common Law Feature
A bug in the application that has existed for so long that it is now part of the expected functionality.
Disaster Driven Development
When Your PMs and salesmen promised that You will build a "space shuttle" in one month.
Egyptian Brackets
Describes the god-awful c-style where curly-braces are not aligned.
Heisenbug
An oldie, but still valuable…describes a bug that disappears or changes when put under scrutiny.
Higgs-Bugson
a hypothetical bug predicted to exist based on a small number of possibly related event log entries and other anecdotal evidence.
Hindenbug
A catastrophic, data destroying bug.
Jimmy
a generalized name for a low-level developer (n00b).
Nopping
From the assembler instruction NOP (no operation). Similar to nap but doesn’t imply sleep, just zoning out.
Object Oriented Pasta
Used to describe spaghetti code wrapped in classes to make it look like an object.
Perl-Grade Obfuscation
The highest level of code obfuscation possible. Better than passing code through a 1-way hash function.
Refuctoring
the process of taking a well-designed piece of code and, through a series of small, reversible changes, making it completely unmaintainable by anyone except yourself.
Rubberducking
The process of talking your own way through a problem, as if talking to a rubber duck.
Scar Tissue
Any code that is commented out but still included in the current and/or checked-in version.
Smurf Naming Convention
When almost every class has the same prefix. IE, when a user clicks on the button, a SmurfAccountView passes a SmurfAccountDTO to the SmurfAccountController. The SmurfID is used to fetch a SmurfOrderHistory which is passed to the SmurfHistoryMatch…
Stringly Typed
One of the antitheses of strongly typed. It describes an implementation that uses strings where more strongly-type options are available.
Try, Catch, Forget
An empty catch block, no tracing, not even a comment. No attempt to resolve the error and of course the catch block is not at all specific on the exception type.
Tags: , , , , , , | Categories: Development Posted by bsstahl on 6/7/2011 5:46 PM | Comments (0)

FxCop, the built-in code-analysis tool in Visual Studio, is the first thing I check when doing a code review.  If Code Analysis is enabled for a project, setup properly, and its rules have not been overridden, this tool will help maintain consistency in the code, even if that code is worked on by multiple developers.  FxCop also does a good job of identifying if some common mistakes have been made, such as not disposing of an IDisposable object, and can identify things that will help the compiler do its job better, such as ensuring that assemblies which expose public objects identify whether or not they are intended to be CLS compliant.

In order to get these benefits, code analysis must be enabled for each project and a rule set must be selected.  Because adding code-analysis to existing assemblies can be a bit painful, it is recommended that you enable this analysis as soon as a project is created in Visual Studio.  To enable code analysis for an assembly, select the project properties, go to the Code Analysis tab, and check the “Enable Code Analysis on Build (defines CODE_ANALYSIS constant)” box.

image

The default rule set that will be run during code analysis is called “Microsoft Minimum Recommended Rules”.  This is a very small set of rules that is a good one to enable if you are starting to do code analysis on a previously coded assembly.  If however, you are starting clean, I highly recommend starting with either the “Microsoft All Rules” rule set, or your own version of that set, since this rule set will provide the most benefit in all areas of analysis.  To create your own rule sets, select the set you wish to modify and press the “Open” button next to the rule set drop-down.  Once opened, you can make any changes you wish, and use the File –> Save-as menu item to save the rule set with a different file name.  New rule sets will automatically appear in the drop-down menu. You can use the properties tab to update the Name and Description of the set, and the rules editor to enable or disable individual rules.  You can also define, for each rule, whether failures are ignored, result in a warning, or generate a compilation error.  I highly recommend setting all rules that you want to enforce to cause errors since they can always be overridden if necessary but will likely be missed if they only result in warnings.

image

For my projects, I use one of several rule sets that I have set up, all of which are slight modifications to the “Microsoft All Rules” rule set.  I will detail the rule set changes I make and overrides that I allow in each set of circumstances below.  I encourage you to experiment with these rule sets to determine the optimum configuration for your projects.

All Projects

  • Modify the “Microsoft All Rules” rule set so that all rules result in an error.  The easiest way to do this is to use the “group by” drop-down to order all rules by “Target Type”.  The only type found here should be “Managed Code”.  With this single group collapsed, use the Action drop-down to select “Error” for all rules.

Entity Framework Projects

  • The Entity Framework requires navigation properties of entities to be read-write, a violation of rule CA2227, “Collection properties should be read only”.  For projects utilizing the Entity Framework, as well as those designed for use within the entity framework (such as entity POCO libraries), the action of this rule may be set to “Warning” to prevent compilation errors whenever entities with navigation properties are built.

Projects Deployed to Internal Company Servers (and not GAC’ed)

  • Assemblies that will not be deployed to the GAC and will remain on secure, internal servers do not need to have a strong name. Thus, rule CA2210, “Assemblies should have valid strong names”, can be permanently over-ridden or have its action set to “None”.

Non-Localized Projects

  • For projects that are never to be localized to a foreign culture, you can set the action for rule CA1303, “Do not pass literals as localized parameters”, back to “Warning”.  I find this rule to be especially incorrect when I am writing logging code within my methods (unless using aspect-orientation) because the logging code also serves as functional code-comments if the literals are included in the method calls.

Console Applications

  • Many console apps ignore the command-line parameters passed-in to the main method, a violation of rule CA1801, “Review Unused Parameters”.  Most of the time, this rule is valuable since you don’t want to have parameters to methods that are never used, however, since we cannot change the parameters to the main method of a console app, but may not wish to use them, this rule can be set to generate a warning in console applications, or can be simply overridden for the parameters to the main method of each console app.  This rule may also be violated temporarily when a method has been stubbed but not yet implemented.  In that case, the rule should be overridden in code similar to rule CA1822 below.

Other (More Temporary) Modifications

  • Rule CA1822, “Mark members as static”, is violated when a method in a class does not use any of the other non-static members of the class.  This is always true when the method has not yet been implemented (is only a stub).  Prior to the method being implemented, this rule should be overridden in code.  The override should be removed from the code once the method has been implemented.
  • Rule CA1040, “Avoid empty interfaces” is often violated temporarily in TDD/BDD because interfaces may be created without methods and then be built-up as needed by the use-case.  Prior to the interface being defined, this rule should be overridden in code.  The override should be removed from the code once the interface has been defined.

I have found using Code Analysis to be a good way to improve the maintainability of my applications, especially when the app is being worked on by multiple members of a project team.  The FxCop tool, built into Visual Studio’s Ultimate and Premium editions, is one of a number of tools and techniques I use to keep my code as maintainable and extensible as possible, resulting in the lowest possible total cost of ownership (TCO).  In future articles, I will explore additional tools and techniques I use for this purpose.

Tags: , , , | Categories: Development Posted by bsstahl on 4/29/2011 9:19 PM | Comments (0)

In a video interview about storytelling for currentTV, Ira Glass, the host of “This American Life”, details the lengthy process that he, and all creative people go through to close the quality gap between the work they are trying to produce, and what they are actually producing.

All of us who do creative work, we get into it, and we get into it because we have good taste… So you’ve got really good taste and you get into this thing that I don’t even know how to describe but it’s like there’s a gap. That for the first couple of years that you’re making stuff, what you’re making isn’t so good, ok, it’s not that great, it’s really not that great.  It’s trying to be good, it has ambition to be good, but it’s not quite that good. But your taste, the thing that got you into the game, your taste is still killer.  Your taste is still good enough that you can tell that what you’re making is kind of a disappointment to you…you can tell that it’s still sort-of crappy.  A lot of people never get past that phase, a lot of people, at that point, they quit. And the thing that I would say to you with all my heart is that most everybody I know who does interesting, creative work, they went through a phase of years where they had really good taste, they could tell that what they were making wasn’t as good as what they wanted it to be, they knew it fell short.  Some of us can admit that to ourselves and some of us are a little less able to admit that to ourselves.  But we knew it didn’t have this special thing we wanted it to have. And the thing I’d say to you is, everybody goes through that, and for you to go through it, if you’re going through it right now, if you’re just getting out of that phase, or if you’re just starting off and you’re entering into that phase, you gotta know, it’s totally normal and the most important possible thing you could do is do a lot of work.  Do a huge volume of work…

While Ira is specifically talking about TV and radio production, his statements also hold true for more analytic pursuits including software development. There have been many occasions during my career as a developer where I knew that the work I had done did not meet my own lofty expectations. There are a number of reasons for this, several of which I have detailed below:

  1. Ran out of time/money – We often take shortcuts while building a solution that we never get back to fixing because we ran out of time or money.  This is sometimes fine, and other times not.  It is important to know when it is acceptable to take shortcuts, and how to be certain to get back to them before they cause problems down the road.
  2. Techniques not yet defined/available – Often, when new technologies are released, the best practices for using those technologies are not known.  Sometimes, things that are best-practices with older technologies, or older versions of technologies, are no longer the right things to do with the current state-of-affairs.  There are times that you will need to develop those best practices, which can usually only be done through experimentation.
  3. Misunderstanding of best practices – Sometimes, we simply don’t know or misunderstand the best practices.  Occasionally, we will think we are using the best-known-method for dealing with a problem, only to find that we were mistaken, or misunderstood the problem or the solution.  Either way, we have to choose between fixing the problem through refactoring, scrapping our code and starting over, or accepting the less-than-optimal code.

Fortunately, the solutions to these problems are generally the same as Ira’s, that is, to keep doing it.  Keep building things, refining your skills, and techniques, and bringing in new tools and technologies to continually close the gap between the work you expect to be doing, and the work you are doing.  Continuously refactor your code to improve it, and to search for the best ways of solving the problems we face.  Build light frameworks when appropriate to help solve repeat problems, and keep those frameworks abstract and loosely-coupled enough so that when the technologies change, the solutions can change accordingly.  Finally, and most importantly, never stop learning.  Our industry is one where if you stop, or even slow your learning process, you are very quickly going to be left stuck with antiquated tools and techniques.  Always keep reading new articles and trying new things.  You are unlikely to ever reach the point where you are completely happy with all of your code, but by continuously learning and striving to improve, you can definitely reach the point that you understand your failings and know what you need to do to make things better whenever your work is not what you hoped for.  Then, armed with that knowledge, you have what you need to decide if it is worth it to make the code better, or if is it more valuable to move on to the next thing.