21 February 2014

Assert or MatcherAssert

#9 differenceI regularly meet online with friends and practice remote pair programming. Last time, while working with my friend Thomas, one of us mistyped the static import for assertThat and we ended with an import of org.hamcrest.MatcherAssert instead of org.junit.Assert. I had never seen MatcherAssert before and Thomas asked me if I knew what the actual difference between them would be. I did not know but we are going to find out right now.

A little bit of history
The Hamcrest Matchers are part of JUnit 4 since version 4.4. JUnit up to version 4.10 shipped with Hamcrest 1.1 and on release 4.11 it switched to Hamcrest 1.3. Looking at the history of MatcherAssert it seems that it had been in the core already but had been moved out again before version 1.1 was released.
  • May 22, 2007 - Moved assertThat() into hamcrest-core.
  • May 23, 2007 - Moved assertThat() back into hamcrest-integration (really this time).
  • July 19, 2007 - JUnit 4.4 shipped including Hamcrest 1.1
  • November 25, 2008 - Moved MatcherAssert to core.
  • July 9, 2012 - Hamcrest version 1.3 released
  • November 14, 2012 - shipped JUnit 4.11
Show me the code!
Now let us compare the actual source code. JUnit's Assert.assertThat looks like
public static <T> void assertThat(T actual, Matcher<T> matcher) {
   assertThat("", actual, matcher);
}

public static <T> void assertThat(String reason, T actual,
                                    Matcher<T> matcher) {
   if (!matcher.matches(actual)) {
      Description description = new StringDescription();
      description.appendText(reason);
      description.appendText("\nExpected: ");
      description.appendDescriptionOf(matcher);
      description.appendText("\n     got: ");
      description.appendValue(actual);
      description.appendText("\n");

      throw new AssertionError(description.toString());
   }
}
whereas Hamcrest's MatcherAssert code is
public static <T> void assertThat(T actual, Matcher<? super T> matcher) {
   assertThat("", actual, matcher);
}

public static <T> void assertThat(String reason, T actual,
                                    Matcher<? super T> matcher) {
   if (!matcher.matches(actual)) {
      Description description = new StringDescription();
      description.appendText(reason)
                 .appendText("\nExpected: ")
                 .appendDescriptionOf(matcher)
                 .appendText("\n     but: ");
      matcher.describeMismatch(actual, description);

      throw new AssertionError(description.toString());
   }
}

public static void assertThat(String reason, boolean assertion) {
   if (!assertion) {
      throw new AssertionError(reason);
   }
}
assertThat(String, boolean)
The most obvious difference is that Hamcrest defines an additional assertThat method which accepts a boolean expression. The method is identical to Assert.assertTrue(String, boolean). No big deal.

<? super T>
The signatures of both classes are almost identical. Almost because Hamcrest has a variation of the generic type T. JUnit accepts matchers that have the same type as the actual value in the argument list T actual, Matcher<T> matcher, while Hamcrest also accepts them for super types of T in T actual, Matcher<? super T> matcher. Allowing parent types of T makes sense because what matches the parents of T will always match T too. Here is an example of a Matcher<Number> matching against an Integer which extends Number.
import org.hamcrest.CustomMatcher;
...

@Test
public void shouldAllowSuperTypeMatcherInAssert() {
   Integer actual = 3;
   Matcher<Number> matcher = new CustomMatcher<Number>("anything") {
      @Override
      public boolean matches(Object anything) {
         return true;
      }
   };
   MatcherAssert.assertThat(actual, matcher); // (1)
   Assert.assertThat(actual, matcher); // (2)
}
Line (1) binds <T> to <Integer> because <? super Integer> allows Number as type of the given matcher. On the other hand, line (2) compiles as well, setting <T> directly to <Number>. So the two signatures are equivalent.

Description of the Mismatch
The third difference is the way the two assertions describe the mismatch. While JUnit just appends the actual value with description.appendValue(actual), Hamcrest asks the matcher to describe its mismatch by matcher.describeMismatch(actual, description), which might give more information in case of failure. So let us dig into some more code.
@Test
public void shouldDisplaySimilarMessageForIsMatcher() {
   int actual = 1;
   Matcher<Integer> matcher = is(2);
   assertJUnitMessage(actual, matcher,
      "Message\nExpected: is <2>\n  got: <1>\n");
   assertHamcrMessage(actual, matcher,
      "Message\nExpected: is <2>\n  but: was <1>");
}
As the BaseMatcher's describeMismatch just returns "was " + actual there is no real difference in the output of both assertions. What about other matchers? Let us look for implementations of describeMismatch that do more than just return the actual value. The only matcher I found was org.hamcrest.TypeSafeMatcher, which has several subclasses in the Hamcrest library, e.g. HasProperty, IsEmptyIterable and IsCloseTo.
import org.hamcrest.beans.HasProperty;
import org.hamcrest.collection.IsEmptyIterable;
import org.hamcrest.number.IsCloseTo;
...

@Test
public void shouldDisplaySimilarMessageForHasPropertyMatcher() {
   Object actual = "abc";
   Matcher<Object> matcher = HasProperty.hasProperty("prop");

   assertJUnitMessage(actual, matcher,
      "Message\nExpected: hasProperty(\"prop\")\n  got: \"abc\"\n");
   assertHamcrMessage(actual, matcher,
      "Message\nExpected: hasProperty(\"prop\")\n  but: no \"prop\" in \"abc\"");
}

@Test
public void shouldDisplaySimilarMessageForIsEmptyIterableMatcher() {
   Iterable<String> actual = Collections.<String> singletonList("a");
   Matcher<Iterable<String>> matcher = IsEmptyIterable.<String> emptyIterable();

   assertJUnitMessage(actual, matcher,
      "Message\nExpected: an empty iterable\n  got: <[a]>\n");
   assertHamcrMessage(actual, matcher,
      "Message\nExpected: an empty iterable\n  but: [\"a\"]");
}

@Test
public void shouldDisplaySimilarMessageForIsCloseToMatcher() {
   double actual = 2.0;
   Matcher<Double> matcher = IsCloseTo.closeTo(1, 0.1);

   assertJUnitMessage(actual, matcher,
      "Message\nExpected: a numeric value within <0.1> of <1.0>\n  got: <2.0>\n");
   assertHamcrMessage(actual, matcher,
      "Message\nExpected: a numeric value within <0.1> of <1.0>\n  but: <2.0> differed by <0.9>");
}
Hamcrest creates slightly more detailed error messages, but only for these three cases.

The Same DifferenceConclusion
org.hamcrest.MatcherAssert is not a replacement for org.junit.Assert because it does not come with all the assertions which we are used to. But MatcherAssert contains a slightly different assertThat. Using that method could potentially give better error messages because the matcher is called to describe the mismatch. When using a complex, custom matcher this could improve the error messages and speed up error diagnosis. Currently only three matchers implement their own descriptions. These come with the Hamcrest library which is not included with JUnit right now.

6 February 2014

Write about what you do

This is the third part of my series about personal branding. It started with some advice for a friend but the content kept growing and growing. This is supposed to be a step by step guide for software developers to build their own personal brand. The first steps are branding all accounts and defining a motto. The next steps to get some reputation are sharing content using Twitter and contributing to Stack Overflow. Now it is time to talk about writing.

Dear DiaryMaintain a Technical Blog
Blogging is a huge area and many things have been written about it. I am no social media export nor an expert blogger so I recommend you first do some research about how to write blog posts. Start with Scott Hanselman's excellent article how to Keep Your Blog from Sucking. And yes, I feel badly promising information about blogging and then sending you STFW. Instead I will only comment on a few rules you will find.

Blogging Frequency
I have seen advice to create at least eight blog posts a month, or even more, to keep readers engaged and attract new ones as well. But let's face it, blogging is hard work. Even if you are a natural writer you still need to collect the information, maybe add code samples, put it all together and format it nicely. This takes time and unless you are writing blog posts on company time, you likely do not have that much spare time. Compared to sharing on Twitter, blogging is more heavy-weight and therefore more likely to be postponed. If you are disciplined you could set up a time in your weekly schedule to work on the next blog post. I am not and I barely manage to write two posts per month. I keep telling myself that a blog posts needs as much time to write as it needs, there is no point in forcing it. I would rather not publish anything than a poorly written or badly formatted post.

Content is King
Obviously content is king, so what should you write about? If there is something you want to say, just write it. While being authentic, you write mainly for yourself. For example write a rant to get over something that made you angry. (But blog rants should not be most of your writing.) Next write for your readers and for search engines. Dan North once said: "If you did something and it worked, then write about it. If it did not work, write about it as well, you never know how other people will use it." Following this advice creates the most useful articles which share insight or teach new skills. Especially how-to posts are helpful to people and get a lot of traffic from search engines.

WritingSome other things you could write about are recaps of conferences or events, reviews of books or a little fun post from time to time. A great source for blog content is your mailbox. Some of your email-conversations do not need to be private and might be useful for other people as well. In such a case just write a blog post. Even if you need to write the email, you can always reuse the content and put it on your blog, too. I used this technique while working for a past employer. Whenever I wrote some technical email or wiki page, I considered reusing the content on my blog. For example here is an email I wrote to the whole team some time ago. Companies like IBM even encourage you to cross post internal content to your public blog, but you really need to be careful about sharing internal information.

Size Does Matter
More content is not always better. I got feedback from one of my readers that he likes my posts because they are short and he is able to read them quickly. Although I do not mind longer articles myself, I do not read them immediately when checking my feeds. They stay in the list of articles to read, but this list is ever growing and there is a probability that I might never read them at all. So a total of 500 words seems to be a reasonable size for a blog post. 500 words equal 3500 to 4500 characters, which is exactly the average size of my blog posts and this one is at this very sentence crossing the boundary.

Focus on Quality
As while sharing, while writing never focus on the number of followers. There are plenty of articles in the web promising you to attract many followers. Do not waste your time with these. Instead care for the quality of your blog, e.g. come back to update your blog in case of mistakes. Also focus on the overall interaction. Answer comments timely and follow up on questions.

Write a Technical Article
If you enjoy writing, you could consider writing full blown articles for technical magazines or developer portals. These reach a different audience and are more reputable because they are real publications considered in an academic sense. But they are also much harder to create. First your topic needs to fit the current theme of the magazine. Not all ideas are welcome, if the editor thinks your topic is not of interest to many readers, your proposal will be rejected. On the other hand, on your blog you can publish whatever you like. So given your area of specialisation or interest, finding a publisher might be difficult. Publishers have strict guidelines for the content and (the ones I worked with) expect at least 2500 words per article, so five times more work than a regular blog post. You might have to revise your article several times until it is accepted. The articles I wrote some years ago took me between 20 and 30 hours each to get them published.

That ends my description of the basic steps you should take to build your own personal brand. There are some more advanced topics you could do, e.g. public speaking, but I will leave them for another time.

3 February 2014

Gain Reputation by Sharing

In the previous article I talked about the foundation of your personal brand, your reputation. Reputation means to be recognized for something, at least by your peers. But to be known for something you actually have to do something, e.g. create or share things of interest.

SharingSo Just Start Sharing
The easiest way to share is to re-share. Start using Twitter and follow some people related to your interests. These may be authors of books you consider important or well known members of the community or just people you know and want to listen to. If they share something you consider worth reading, then re-share (re-tweet) it. Also share links whenever you find an interesting article or useful tool. There exists a bookmark widget that makes sharing to Twitter very easy. If you do all that then I am already interested in your Twitter stream because you aggregate information about a certain topic and reduce noise.

Do Not Over-share
Start slowly and do not over-share. Be sensitive about what you share. For example political or religious topics might be controversial and will not help you - unless that is what you want to be known for. I especially like the rules given by Martin Nielsen: "Would your (hypothetical) grandchildren be proud of what you share? If not then probably you should not share it. And if you do not smile while writing it, you should not share it at all." I have violated these rules myself a few times as you can see in my blog rants, but exceptions prove the rule. ;-)

Promote Yourself
Many social media tools, like Twitter, Facebook or Google+ allow you to promote content by sharing links or snippets of text. Using these tools you can and should promote yourself and tell the world what you are doing to build your own brand. But if all your content is (self)-marketing it will not work. People will lose interest because there is no benefit in following you. While working for IBM I had the opportunity to listen to a presentation by Luis Suarez, the email-less man, about social media and he advised that eight out of ten messages should not be (self)-marketing, but interesting and useful information.

SharingEngage Others and Communicate
After some time, when you feel comfortable with sharing interesting things via social media tools, it is time to communicate directly with others. This can be a simple as answering tweets or commenting on blog posts you read. Saying thanks or asking questions is a great way to start a conversation. This is exactly how I got in touch with the great people organizing my most favourite conference. While preparing to visit GeeCON I shared some ideas for the community day on the GeeCON blog. It was not a big thing, just one or two sentences. Then during the conference, when I passed Adam of the GeeCON staff, he stopped and we had a nice chat. He had recognized the Code Cop logo on the sleeve of my T-shirt. (By the way, GeeCON 2014 is coming up and they have great speakers announced, so you might consider going there.)

Be Authentic (Again)
I already mentioned in the first part that you need to be authentic. If you have nothing to say then do not try to make up fake conversations. If you read a blog post and do not have anything to add or discuss, then just leave it alone. I rarely add comments to blog posts. If I have nothing to say, I just shut up.

Create Genuine Content
After sharing and commenting the next step is creating stuff on your own, which usually means maintaining a programmer blog. While this is true I recommend something easier to start: Stack Overflow. I am sure that you use Stack Overflow. So why not register an account and start contributing? Even if you are just reading answers, you should vote on questions and answers that are useful to you. Then you could make a habit of fixing badly formatted questions and (given some reputation) adding tags. Sooner or later you will have some reasonable question to ask or even know some answers to existing questions. Stack Overflow is an excellent training area for future writers because questions and answers should be correct, concise and properly formatted, just like your blog posts, only much shorter. See a recent presentation by Jeff Atwood about how to be a good Stack Overflow citizen for details on how to work best with Stack Overflow.

The next part will be on maintaining a technical blog. While I am busy writing about it, I expect a lot of interesting material to appear in your Twitter stream.