Tuesday, April 20, 2010

ALM Practices Part 6: Code Analysis & Guidelines

What is it?
Coding guidelines, or coding standards if you will, are documents consisting of rules and recommendations on the use of C# in enterprise systems. They deal with code layout, naming guidelines, the proper use of the .NET Framework, tips on writing useful comments and XML documentation, and often also include guidance on proper object-oriented design. Visual Studio’s Static Code Analysis (a.k.a. FxCop) can automatically verify a majority of those rules and recommendations by analyzing the compiled assemblies. You can configure to do that at compile time or as part of a continuous or daily build. The Aviva Solutions Coding Guidelines for C# 3.0 and 4.0 adds additional rules and recommendations and provides a list of Code Analysis rules that are applicable for Line-of-Business applications and frameworks.

Why would you do it?
Because not every developer

  • is aware of the potential pitfalls of certain constructions in C#.
  • is introduced into certain conventions when using the .NET Framework (e.g. IDisposable)
  • is aware of the impact of using (or neglecting to use) particular solutions on aspects like security, performance, multi-language support, etc.).
  • knows that not every developer is as capable in understanding an elegant, but abstract, solution as the original developer.


What’s the usual thing to do?
Ensure that all code, including unit tests, complies with your coding guidelines and the Code Analysis rules selected for your project.

How do you do that?

  • Ask all developers to carefully read the Coding Guidelines at least once. This will give them a sense of the kind of guidelines the document contains.
  • Make sure there are always a few hard copies of the Quick Reference close.
  • Include the most critical coding guidelines on the checklist and verify the remainder as part of your Peer Review.
  • Decide which CA rules are applicable for your project and write these down somewhere, such as your TFS team site. The C# Coding Guidelines site on CodePlex offers Visual Studio 2010 rule sets for both Line-of-Business applications and more generic code like frameworks and class libraries.
  • Add a custom Code Analysis Dictionary containing your domain- or company-specific terms, names and concepts. If you don’t, Static Analysis will report warnings for (parts of) phrases that are not part of its internal dictionary.
  • Configure Visual Studio to verify the selected CA rules as part of the Release build. Then they won’t interfere with normal developing and debugging activities, but still can be run by switching to the Release configuration.
  • Add the verification of the CA rules part of your Continuous or Daily Build.
  • Add a rule to your team that the first one who comes in the office in the morning will check the build for CA warning and will make sure somebody (not necessarily himself) solves it as soon as possible.
  • Add an item to your project checklist to make sure all new code is verified against CA violations, or use the corresponding Check-in Policy if you want to prevent any code from violating CA rules at all.
  • ReSharper has an intelligent code inspection engine that, with some configuration, already supports many aspects of the Coding Guidelines. It will automatically highlight any code that does not match the rules for naming members (e.g. Pascal or Camel casing), detect dead code, and many other things. One click of the mouse button (or the corresponding keyboard shortcut) is usually enough to fix it.
  • ReSharper also has a File Structure window that shows an overview of the members of your class or interface and allows you to easily rearrange them using a simple drag-and-drop action.
  • Using GhostDoc you can generate XML comments for any member using a keyboard shortcut. The beauty of it, is that it closely follows the MSDN-style of documentation. However, you have to be careful not to misuse this tool, and use it as a starter only.
  • Consider reading the book Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin. It provides excellent guidance on writing elegant and simple code that is easy to maintain and to extend. His ideas have evolved into a new quality standard maintained by many well-known community members.

Friday, April 16, 2010

Interaction Design according to Alan Cooper

I've recently finished the book The Inmates Are Running The Asylum by Alan Cooper, a well known proponent for interaction design. To be honest, I never really saw the purpose of interaction design in our projects. But after reading this book, I now know I didn't really understand what it was about and why it is so important.

One of my colleagues, Stefan Bookholt, has mentioned the need for some good interaction design many times, but his persistence was often met by laughter. This post is not really a review of the book, but rather my public apologies to him for not listening earlier.

First of all, this book is really worth its money and very easy to read. It's so full of real life cases and anecdotes, it really helps you to gain a solid understanding of why interaction design is so important.

Some highlights you should remember the next time you have a discussion about the functional design of your application.

  1. Less is more. It's better to have just a few well-designed features that get the job done, than hundreds of options that confuse the end-user.
  2. Your product should be goal-oriented. That sounds obvious, but it is quite difficult to understand the actual goals an end-user is trying to accomplish. Tasks are not goals, just the steps to reach it. Without knowing the goal, it is very difficult to build a system that helps the user to reach that point.
  3. Users don't like to feel stupid because your product is too complex for them to use (but they'll never admit that).
  4. Users are only beginners for a short time. The biggest share of the market consists of intermediate users (who might or might end up as experts)
  5. User forums don't work either because users are bad in making decisions about functionality. They don't know what is and what is not possible and usually miss the big picture or the vision your system is supposed to reach.
  6. Developers should not do interaction design. Why? Because they have their own way of looking at things and are known for confusing the needs of end-user with their own.
  7. Interaction design should not happen concurrently with programming because it can have a radical impact on the design of your application.
  8. Industrial Design is not interaction design because it deals with the look-and-feel of a product, not its usability.
  9. User Interface design is not interaction design. Like Industrial Design, UI design focuses on the look-and-feel and positions of buttons. Interaction design looks at the way an application should fulfill a goal.
  10. UI style guides are not necessarily a good thing, because they restrict creativity. It is okay to have a common standard for coloring, icons and font styles. But an interaction designer should be able have the freedom to create an application that solves the goals of its end user, even if that means that the guide is violated.

Monday, April 12, 2010

Fluent Assertions 1.2 has been released

It has been only 6 weeks since I first released Fluent Assertions to the public, followed by version 1.1 a week later. In the weeks thereafter, I received some nice ideas from the community which caused me to start working on the next version.

But it was not easy. I found that designing a small framework like this really requires you to carefully design the syntax you want to offer. For instance, I underestimated the limits of the current version of C# and had to make some tough decisions along the way. But I'm done now, so get version 1.2 from CodePlex. However, please read this post before you start introducing it in your project. Those tough decisions will cause some minor inconvenience.

New collection assertions

The collection assertion methods now include a BeNull() and NotBeNull() to ensure that a collection is initialized or not. I’ve also made sure that the Contains() method of a generic collection takes an object of the right type instead of System.Object (this breaks existing usages though). And if that is not enough, you can also pass in a lambda expression to specify that the collection should contain a specific instance. Something like this:

dtoCollection.Should().Contain(dto => dto.Id != null);

Similarly, you can also use a lambda when asserting the count of a collection:

collection.Should().HaveCount(c => c >= 3);

If the subject-under-test does not comply with the expression, it will include the actual expression of the lambda in the error message. As a matter of fact, this applies to all assertion methods that take a lambda expression.

Comparing objects by their properties

I’ve added the possibility to assert the equality of entire objects by comparing their properties by name. This even works if the types of the properties differ but a built-in conversion exists (through the Convert class). As an example, consider a Customer entity from some arbitrary domain model and its DTO counterpart CustomerDto. You can assert that the DTO has the same values as the entity using this syntax:

dto.ShouldHave().AllProperties().EqualTo(customer);

As long as all properties of dto are also available on customer, and their value is equal or convertible, the assertion succeeds. You can, however, exclude a specific property using a lambda, such as for instance the ID property:

dto.ShouldHave().AllPropertiesBut(d => d.Id).EqualTo(customer);

The other way around is also possible. So if you only want to include two specific properties, use this syntax.

dto.ShouldHave().Properties(d => d.Name, d => d.Address).EqualTo(customer);

Comparing dates and times

In addition to simple assertions between two DateTime objects, I’ve added a whole bunch of methods for asserting that two dates or times differ a specific amount of time (specified using a TimeSpan). With these you can do things like:

dt1.Should().BeWithin(TimeSpan.FromHours(50)).Before(dt2);
dt2.Should().BeLessThan(TimeSpan.FromDays(1).After(dt2);

It supports BeMoreThan(), BeAtLeast(), BeExactly(), BeWithin() and BeLessThan() before or after a specific date and/or time.

Other improvements

In addition to fixing several minor bugs reported by the community, I have spend a considerable amount of time in making sure the assertion failure messages clearly explain why it failed. For instance, a date/time assertion might return the following (lengthy) exception message:

”Expected date and/or time <2010-04-08 09:59:59> to be within 2d and 2h before <2010-04-10 12:00:00> because 50 hours is enough, but it differs 2d, 2h and 1s.”.

The part after the because is the part that you need to add using one of the many overloads. It really helps to keep the developer from the need to start the debugger.

One particular bug I fixed was when asserting that a collection of strings contained a particular string, it was interpreted as an IEnumerable of Char. Obviously it never succeeded, regardless of the fact that the original string was part of the collection.

I also looked at extensibility a bit more by making classes public and ensuring you can override an assertion class at the right spots. I still have to do some work here, but whenever somebody has a problem, I’ll fix it soon enough.

So what did you break?

As a result of some important feedback from the community, my desire to remove a lot of noise from the syntax, and limitations of the language I ran into, I decided to introduce some changes that will break existing code. Fortunately, it is just a cosmetic change, so some smart search/replace should get you back on track easily.

First of all, I’ve renamed almost all Equal() methods to Be(). So instead of myString.Should().Equal(“hello”) you now have to write myString.Should().Be(“hello”). The only exception to this is the one for comparing two collections for equality, since it’s purpose to see if they have the same items.

Also, I’ve renamed the Satisfy() method for asserting an arbitrary object against a lambda expression to Match(). Apparently, the word satisfy was a bit to technical. On the flipside, you now get multiple overloads which allows you to do the following.

o.Should().Match(obj => obj == null)
o.Should().Match<CustomerDto>(d => d.Name.Length > 0);
o.Should().Match((CustomerDto d) => d.Name.Length > 0);

The whole exception throwing assertion syntax was way too noisy, so I removed some unnecessary parts and changed the overall syntax. For instance

someObject.ShouldThrow(x => x.SomeMethod()).Exception<SomeException>();

has been changed into

someObject.Invoking(x => x.SomeMethod()).ShouldThrow<SomeException>();

Which doesn’t really remove noise, but feels more natural to me when invoking a lambda expression. When using an Action<T>, the syntax has changed as well. Consider a class with a method Foo() that should throw an instance of SomeException:

Action act = () => someObject.Foo();

In 1.1 asserting that Foo() really threw that specific exception with specific values for its Message and a custom property SomeParam had to be done like this:

act.ShouldThrow().Exception<SomeException>().
   And.WithMessage(“Something went wrong”).
   And.ValueOf.SomeParam.Should().Equal(23);

In 1.2 I’ve changed it into:

act.ShouldThrow<SomeException>().
   WithMessage(“Something went wrong”).
   And.SomeParams.Should().Equal(23);

You can download version 1.2 from here.