Wednesday, November 24, 2010

Zen Testing Extension Methods

After my last Zen Testing presentation, numerous requests have come in to share the unit test extension methods I use. They are attached at the end of this post (this class is currently setup to use MSTest, but it can be easily adapted to use other test frameworks).

The intent for creating these extension methods was to make for more readable assertions in my unit tests. So rather than:

//arrange
string expected = "Testing123";
Person person = new Person();
person.Name = expected;

//act
string result = person.Name;

//assert
Assert.AreEqual(expected, result);
I wanted my assertions to read like:
//assert
result.ShouldBe(expected);
The usage.ShouldBe(easy to follow).

I do want to point out one special case for testing exceptions. The normal way of testing an exception and its message looks something like this:
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void Save_InvalidPerson_ThrowsInvalidOperationException()
{
//arrange
PersonService service = new PersonService();

try
{
//act
service.Save(new Person());
}
catch (Exception exp)
{
Assert.AreEqual("Person is invalid", exp.Message);
throw;
}
}
This is a very simple example, but it is also rather verbose for what you get. Using a simple delegate reduces the amount of test code required to achieve the same result and increases the readability:
[TestMethod]
public void Save_InvalidPerson_ThrowsInvalidOperationException()
{
//arrange
PersonService service = new PersonService();

//act
Action action = () => service.Save(new Person());

//assert
action.ShouldThrow<InvalidOperationException>("Person is invalid.");
}
Just include the UnitTestExtensions class in your unit test project and take it for a spin. I hope that this will help you on the path to Zen Testing.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Envoc.Core.UnitTests.Extensions
{
public static class UnitTestExtensions
{
public static void ShouldBe<T>(this T actual, T expected)
{
ShouldBe(actual, expected, string.Empty);
}

public static void ShouldBe<T>(this T actual, T expected, string message)
{
Assert.AreEqual(expected, actual, message);
}

public static void ShouldNotBe<T>(this T actual, T expected)
{
ShouldNotBe(actual, expected, string.Empty);
}

public static void ShouldNotBe<T>(this T actual, T expected, string message)
{
Assert.AreNotEqual(expected, actual, message);
}

public static void ShouldContain(this string actual, string expected)
{
ShouldContain(actual, expected, string.Empty);
}

public static void ShouldContain(this string actual, string expected, string message)
{
Assert.IsTrue(actual.Contains(expected), message);
}

public static void ShouldNotContain(this string actual, string expected)
{
ShouldNotContain(actual, expected, string.Empty);
}

public static void ShouldNotContain(this string actual, string expected, string message)
{
Assert.IsFalse(actual.Contains(expected), message);
}

public static void ShouldBeSameAs<T>(this T actual, T expected) where T : class
{
ShouldBeSameAs(actual, expected, string.Empty);
}

public static void ShouldBeSameAs<T>(this T actual, T expected, string message) where T : class
{
Assert.AreSame(actual, expected, message);
}

public static void ShouldNotBeSameAs<T>(this T actual, T expected) where T : class
{
ShouldNotBeSameAs(actual, expected, string.Empty);
}

public static void ShouldNotBeSameAs<T>(this T actual, T expected, string message) where T : class
{
Assert.AreNotSame(actual, expected, message);
}

public static void ShouldBeEqual<T>(this T actual, T expected)
{
ShouldBeEqual(actual, expected, string.Empty);
}

public static void ShouldBeEqual<T>(this T actual, T expected, string message)
{
Assert.AreEqual(actual, expected, message);
}

public static void ShouldNotBeEqual<T>(this T actual, T expected)
{
ShouldNotBeEqual(actual, expected, string.Empty);
}

public static void ShouldNotBeEqual<T>(this T actual, T expected, string message)
{
Assert.AreNotEqual(actual, expected, message);
}

public static void ShouldBeLessThan<T>(this T actual, T expected) where T : IComparable
{
ShouldBeLessThan(actual, expected, string.Empty);
}

public static void ShouldBeLessThan<T>(this T actual, T expected, string message) where T : IComparable
{
Assert.IsTrue(actual.CompareTo(expected) < 0, message);
}

public static void ShouldBeGreaterThan<T>(this T actual, T expected) where T : IComparable
{
ShouldBeGreaterThan(actual, expected, string.Empty);
}

public static void ShouldBeGreaterThan<T>(this T actual, T expected, string message) where T : IComparable
{
Assert.IsTrue(actual.CompareTo(expected) > 0, message);
}

public static void ShouldBeNull(this object value)
{
Assert.IsNull(value);
}

public static void ShouldNotBeNull(this object value)
{
Assert.IsNotNull(value);
}

public static void ShouldThrow<T>(this Action action) where T : Exception
{
ShouldThrow<T>(action, string.Empty);
}

public static void ShouldThrow<T>(this Action action, string message) where T : Exception
{
string failMessage = string.Format("did not throw expected exception {0}.", typeof(T).Name);

try
{
action();
Assert.Fail(failMessage);
}
catch (Exception ex)
{
if (!string.IsNullOrWhiteSpace(message))
{
Assert.AreEqual(message, ex.Message);
}

Assert.AreEqual(typeof(T), ex.GetType(), failMessage);
}
}
}
}

Wednesday, November 17, 2010

History of the World Part IV

History of the World Part I - Douglas Engelbart
History of the World Part II – Ada Lovelace
History of the World Part III – H. Edward Roberts

This time I want to talk about one of the most misunderstood, over-adopted methodologies in software development, and the man who inadvertently introduced us to it – Winston Royce.

Dr. Winston W. Royce (1929–1995) was a computer scientist, director at Lockheed Software Technology Center in Austin, Texas, and the man who described the Waterfall model for software development.

Agile, SCRUM, and XP were a response to the failures of traditional software design and development methodology commonly referred to as waterfall. How the waterfall methodology came to be used as the central software development method used by most companies is an interesting tale. In the 1970′s, the DOD (Department of Defense) was researching methods to handle software development to better report on where money and resources were being spent. A member of the team assigned to this task went to the Institute of Electrical and Electronics Engineers (IEEE), to look for articles on the subject. He found an article named “Managing the Development of Large Software Systems: Concepts and Techniques”. He opened the first diagram – a graph representing the waterfall method – titled “Implementation steps to develop a large computer program for delivery to a customer”. It was from this that the DOD established the Military Standard 2167 which used the waterfall graph as a template – without actually having read the article.

All the vendors that supported the DOD had to accept the new standard of developing software. NATO was also looking for a way to work with software and found the DOD had done a research project on the subject and they too adopted waterfall. Soon, the software industry also followed suit and before you knew it, everyone was working with this new method, called the Waterfall method.

Had they taken the time to actually read the article, they would have found that Dr. Royce goes into detail about why the waterfall method does not work. Namely, waterfall has testing and documentation at the end of the project. It assumes that all the preceding stages are accurate. It also assumes that the estimate of work is exact. We know, however, that when the schedule starts to slip, those things at the end of the project are done hastily or dropped. What’s at the end of the project? Testing and documentation.

For the next several decades the DOD recorded a 60-90% failure rate on software development projects. Eventually, they rescinded the Military Standard 2167.

For the rest of his life, Dr. Royce fought to clear his name. Below is a video that nicely illustrates what happened. Enjoy.

Waterfail

Tuesday, November 16, 2010

Upcoming Speaking Engagements

SELU Department of Computer Science and Industrial Technology 
Tales from the Code 
3:30-4:30pm
Fayard Hall Room 218
Southeastern University Campus

Wednesday, November 10, 2010

History of the World Part III

History of the World Part I - Douglas Engelbart
History of the World Part II – Ada Lovelace

Today we honor Henry Edward "Ed" Roberts (September 13, 1941 – April 1, 2010), commonly referred to as "the father of the personal computer". He co-founded Micro Instrumentation and Telemetry Systems (MITS) in Albuquerque in 1969 and served as its president. The company made and sold rocket kits and then calculators, but their true contribution was the Altair 8800 personal computer that used the new Intel 8080 microprocessor. popular-electronics-january-1975It was featured on the cover of the January 1975 issue of Popular Electronics, and hobbyists flooded MITS with orders for this $397 computer kit. It so inspired Bill Gates and Paul Allen that they moved to Albuquerque and joined MITS to develop software and Altair BASIC, Microsoft's first product. Roberts sold MITS in 1977 and retired to Georgia where he farmed, studied medicine, and eventually became a small-town doctor. He died on April 1, 2010 of pneumonia, but the effect of his contribution to our industry cannot be measured.

He may not have invented the PC, but he surely invented the PC industry.

Monday, November 8, 2010

Upcoming Speaking Engagements

SELU Department of Computer Science and Industrial Technology
Zen Coding
12:00-1:00pm
Fayard Hall Room 205
Southeastern University Campus
More Info

Wednesday, November 3, 2010

History of the World Part II

In the first article of this series, we talked about why learning about our history as developers is an important endeavor, and introduced Douglas Engelbart.

This time we will talk about the person attributed with the distinction of being the first software developer, Ada Lovelace.

Ada Lovelace wrote a paper in 1843 that anticipated the development of computer software, artificial intelligence, and computer music. Daughter of the poet Lord Byron, Ada Lovelace was known as the "enchantress of numbers" who collaborated with Charles Babbage, the inventor of the first mechanical thinking/calculating machine.

At the age of 17, Ada was introduced to Mary Somerville. It was at a dinner party at Mrs. Somerville's in November 1834 that Ada first heard Babbage's ideas for a new calculating machine, the Analytical Engine. What if a calculating engine could not only foresee but could act on that foresight?

Babbage worked on plans for this new engine and reported on the developments at a seminar in Turin, Italy in the fall of 1841. Luigi Menabrea wrote a summary of what Babbage described and published an article about the development. Ada translated Menabrea’s memoir, appending her own notes, including a method for calculating Bernoulli numbers with the machine – and is attributed as the first computer program.

Understanding that computers could do a lot more than just crunch numbers, Ada suggested that the Analytical Engine “might compose elaborate and scientific pieces of music of any degree of complexity or extent”, produce graphics, and would be used for both practical and scientific use.

She never had the chance to fully explore the possibilities of either Babbage’s inventions or her own understanding of computing. She died at age 36 on 27th November 1852 of cancer.

Her contribution to our profession is so significant, in 1979 the U.S. Department of Defense developed a computer language named "Ada" in her honor, March 24th is recognized as “Ada Lovelace Day”, and a movie about her life called “Enchantress of Numbers” is slated for release in 2011.