The list of TDD anti patterns

Published 12/4/2009 by Dave in Test
Tags:

when writting unit tests you may wonder, what im i actually doing? I follow the AAA pattern, well try to ;).

 anyway I found this link on StackOverflow, which has a list of anti patterns for TDD (Unit testing)

http://blog.james-carr.org/2006/11/03/tdd-anti-patterns/

well worth a look, just incase you think your test is not doing what it should be.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Unit testing presentation

Published 11/26/2009 by Dave in General | Test
Tags:

A small presentation to show how unit testing can be used to show/identify poor design (strong coupling).

Downloads:
Presentation: Unit testing.rar (2.89 mb) <BTW, screenshots which show the startbar are actually videos, just click on the video to make it run>
Code (before & after): UnitTesting Examples.rar (150.51 kb)

It covers

  • Simple shopping cart system
  • Simple unit test
  • Redesign
  • Unit test using Mocking

A generic simple domain, so the concept can be shown.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Rowtest with MbUnit

Published 6/30/2009 by Dave in Test
Tags:

I wrote a test which used the Row test attribute, which is a nice feature. This test looks at different states of a form and then tests if the correct email call is made. very similar to the previos post

[Test]
[Row(new object[] { "State Changed", "To: 2, from: 1", "bob", "message", 1, 2 })]
[Row(new object[] { "Another State Changed", "To: 3, from: 2", "bob", "message", 2, 3 })]
public void TestOfStateNtoifcation(string emailSubject, string emailMessage, string formName, string formMessage, int fromState, int toState)
{

    //Record
    var mocks = new MockRepository();
    IEmailService emailService = mocks.DynamicMock<IEmailService>();
    Expect.Call(() => emailService.SendEmail(emailSubject, emailMessage));
    mocks.ReplayAll();

    //Arrange
    Form form1 = new Form()
    {
        Name = formName,
        Message = formMessage,
        ProcessedState = (State)fromState,
    };

    IStateNotification sn = new MappedStateNotification();
    sn.SetInitalState(form1);
    sn.EmailService = emailService;

 

    //Action
    form1.ProcessedState = (State)toState;
    sn.Update(); //message was sent

    //Assert
    mocks.VerifyAll();
}

note some examples showed a Row test without the Test attribute, but Resharper does not pick up upon this... so I added it and bingo.

To pass this test, I wanted a flexible solution compared with the privious post (which used a switch statement) and came up with the use of a Dictionary. the Key would contain the To and From states, for example if the form changed from State.One to State.Two the key would look like

1->2

now the new update looks like this:

public void Update()
{
    //no change
    if (currentState == form.ProcessedState)
        return;

    //get the key
    string key = string.Format("{0}->{1}", (int)currentState, (int)form.ProcessedState);


    if (!rules.ContainsKey(key))
        return;


    NotifyRule rule = rules[key];

    EmailService.SendEmail(rule.Subject, string.Format("To: {1}, from: {0}", rule.FromState, rule.ToState));
}

VS2008 project MockingTestPart2.rar (133.36 kb)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

One thing I wanted to do was to ensure my code was calling a function with the correct inputs. However the function did not return anything (void) and I did not want to write a mock object from scratch which had a verify method was called (that seemed like re-writing the wheel). So I looked a little into Rhino Mocks (Ayende, you are a genius!), low and behold you can do this with this framework (quite easily)

Project Files TestVoidMethodMocking.rar (128.38 kb)  (VS 2008, using MBUnit)

Ok lets quickly look at what I am doing. I have a Interface, for sending emails.

public interface IEmailService
{
    void SendEmail(string subject, string body);
}

And I have a class which has an Update() method, which calls this method (when the State changes from State.One to State.Two), as follows

public void Update()
{
    switch (currentState)
    {
        case State.One:
            if (form.ProcessedState == State.Two)
            {
                EmailService.SendEmail("Status Change", string.Format("Form {0} has entered state 2", form.Name));
            }
            break;
        case State.Two:
            break;
        case State.Three:
            break;
        default:
            break;
    }
}

Within the Test project, I would like to verify that the SendEmail() method is being called with the correct information. So I have used Rhino Mocks Expect.Call to ensure this. For this test I am going to have a form.Name = "test", so I will expect the method call to look like

SendEmail("Status Change", "Form test has entered state 2")

Here is the Unit Test Code: 

[Test]
public void TestIfEmailWasCalledCorrectly()
{
    //Record
    var mocks = new MockRepository();
    IEmailService emailService = mocks.DynamicMock<IEmailService>();
    Expect.Call(() => emailService.SendEmail("Status Change", "Form test has entered state 2"));
    mocks.ReplayAll();

    //Arrange
    Form form1 = new Form()
    {
        Name = "test",
        Message = "test1",
        ProcessedState = State.One,
    };

    StateNotification sn = new StateNotification(form1);
    sn.EmailService = emailService;

    //Action
    form1.ProcessedState = State.Two;
    sn.Update(); //message was sent

    //Assert
    mocks.VerifyAll();
}

 

now when I run the test. I get all green

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Whilst working on open source project I am detracting away from MsTest in favour for MbUnit (plus this has awesome functionality). The thing was I still wanted to have code coverage within Visual Studio, Its a great way to see what code is being hit by the tests which have been written. Upon researching this I have found a couple of ways to get MbUnit Code Covered.

Way 1

Lets start with the Official Runner

if you open the XML of the Test project and change the Project GUID to"{3AC096D0-A1C2-E12C-1390-A8335801FDAB}" which signals to VS this is a test project, for a complete and CORRECT guide on this method please follow the steps detailed here (from the Lead Developer of MbUnit!)..... However he does mention doing this is Slow...

Way 2

After searching the Internet i found this CodePlex project, "VSTS CodeCoverage Runner - Get VS Code Coverage" from NUnit or MBUnit, located here. Which is a nice little project. The author Casey Charlton, has provided us with a great starting block (well more than that), at present the values are hard coded if you want to use the Command prompt (there is also a build task project), but you can "tweak" them so the cmd utility can be used within Studio (I will write a post about that soon).

The macanics of this project follow the basic flow

  • Add instrumentation to the Unit Testing DLL
  • Kick off the Code Coverage monitor
  • Run the unit tests, (I used MbUnit, but you can use any command line based Testing Framework)
  • Stop the monitor
  • Output the File, as a test.coverage file

thats a very quick over view of the process. However with the ".coverage" file, you can open this using the "Code Coverage Results" window and there you go!!

Here it is in action! (I now i can carry one and get some tests done!)

I was able to add coverage on the Test.dll's and all my domain ones too....

Got Ya's

After building the project you will have to add the following to you build folder 

these can be found here

c:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Performance Tools\

If these are not in the same Dir as the exe, or vise versa, the on the creation of the monitor object you will receive an error.

Further Reading

For some really interesting further reading on this topic i would suggest

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Struture of a Unit Test

Published 4/14/2009 by Dave in Test
Tags:

A Test fixture can be made of the following

Fixture (the following are optional)

  • FixtureSetUp - this is ran once before all the tests (set up the fixture)
  • FixtureTearDown - run after all the tests have completed (this can be used to clean up after all the tests)
  • SetUp - run before each test (set the test data to its default settings before each test)
  • TearDown - run after each test (clean up after each test)

the rest of the fixture is made up of Tests

here is a bear bone text fixture, using MbUnit 3.x

[TestFixture]
public class TestCodeFromAssembly
{
    [FixtureSetUp]
    public void FixtureSetUp()
    {
        //add code to set up the global test fixture
    }

    [FixtureTearDown]
    public void FixtureTearDown()
    {
        //Clean up the text fixure
    }

    [SetUp]
    public void TestSetup()
    {
        //run before every test
    }

    [Test]
    public void Test()
    {
        //
        // TODO: Add test logic here
        //
    }

    [TearDown]
    public void TestTearDown()
    {
        //cleans up after every test
    }
}

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Lets say you want to do some TDD, as you may know that you have in some/most test an Expected answer and an Actual answer. In the case of the expected/actual being a value type or string its easy just to use:

Assert.AreEqual<string> ("this is expected", Actual, "the string values did not match");

 However in the case where these varibles are business objects, you will need to override the "==" and/or the Equals operators. Thats perfect when all you business objects have this implemented, but what can you do when they don't. One thing that comes to mind is either going and adding overrided methods in all your object, or you could add an assert for every property in the class. Well I was a little bit lazy/curious to see if I could use reflection, and this is what I came up with:

public static bool isEqual(object Actual, object Expected)
{
    if (Actual.GetType() != Expected.GetType())
    {
        throw new ArgumentException
            ("both inputs have to be of the same type");
    }
    Type t = Actual.GetType();
    PropertyInfo[] ps = t.GetProperties();
    foreach (PropertyInfo p in ps)
    {
        //only test the value types and strings
        if ((p.PropertyType.IsValueType) ||
            (p.PropertyType == typeof(string)))
        {


            List<Type> paramTypes = new List<Type>();
            string PropertyName = p.Name;
            //not needed as they should not have parameters
            //foreach (ParameterInfo param in p.GetIndexParameters())
            //{
            //    paramTypes.Add(param.ParameterType);
            //}

            //get the first value
            object val1 = t.GetProperty(PropertyName,
                paramTypes.ToArray()).GetValue(Actual, null);
            //get the second value
            object val2 = t.GetProperty(PropertyName,
                paramTypes.ToArray()).GetValue(Expected, null);
            //make sure they are the same
            if (!val1.ToString().Equals(val2.ToString()))
            {
                return false;
            }
        }
    }
    return true;
}

The above uses reflection to test all the value type and string properties in the object to see if they are the same. This will take in 2 objects of the same type and return true if they contain the same values (a little like the assert.AreEqual<youObject>).

Take the following example:

static void Main(string[] args)
{

    person p1 = new person();
    person p2 = new person();
    person p3 = new person();
    person p4 = p1;

    p1.Name = "dave";
    p1.Age = 25;

    p2.Name = "dave";
    p2.Age = 25;

    p3.Age = 23;
    p3.Name = "troy";

    Console.WriteLine(string.Format("p1 = p2 : {0}", p1 == p2));
    Console.WriteLine(string.Format("p1 = p4 : {0}", p1 == p4));
    Console.WriteLine(string.Format("isEqual(p1, p2) : {0}", isEqual(p1, p2)));
    Console.WriteLine(string.Format("isEqual(p3, p2) : {0}", isEqual(p3, p2)));
    Console.ReadLine();
}

note the isEqual(p1, p2) is true, which is awesome for some cases of unit testing. (consider the saving and loading of an object to and from a DB, testing to see if it returned the same object)

 finally the code for the person class: (as you can see its a simple class)

class person
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    private int _age;
    public int Age
    {
        get { return _age; }
        set { _age = value; }
    }
}

but if you would like to know how to override the "==" and Equals take a look at this MSDN article:

http://msdn2.microsoft.com/en-us/library/ms173147.aspx

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

A Text file test trace listener

Published 2/4/2008 by Dave in dotNet | Test
Tags:

Testing your logging functionality, using the Enterprise library and a custom trace listener. As I was in need of a method to test some loggin functions, i googled away and found this exellent article

<http://blogs.msdn.com/ploeh/archive/2006/04/06/
UnitTestYourEnterpriseLibraryLoggingLogic.aspx
> by ploeh.

I have slightly modified this code to use a text file, allowing me to view the test data in a text file and read it back in. Here is my alterations (consider this a small tribute to a great article.)

 In the rest of this article i will go through the differences

the Write and WriteLine methods output the the textfile

/// <summary>
/// Overriden write menthod, this will write directly to
/// the log
/// </summary>
/// <param name="message"></param>
public override void Write(string message)
{
    StreamWriter sw = null;
    try
    {
        sw = new StreamWriter(CreateLog());
        sw.Write(message);
    }
    catch (Exception ex)
    {
       throw new Exception("cannot write to file :", ex);
    }
    finally
    {
        if (sw != null)
            sw.Close();
    }
   
}

/// <summary>
/// Write line
/// </summary>
/// <param name="message"></param>
public override void WriteLine(string message)
{
    StreamWriter sw = null;
    try
    {
        sw = new StreamWriter(CreateLog());
        sw.WriteLine(message);
        sw.WriteLine("<--End-->");
        sw.WriteLine("");
    }
    catch (Exception ex)
    {
        throw new Exception("cannot writeline to file :", ex);
    }
    finally
    {
        if (sw != null)
            sw.Close();
    }
}

The overriden TraceData method remins similar just removed the addtion to the collection

public override void TraceData(TraceEventCache eventCache,
    string source, TraceEventType eventType, int id,
    object data)
{
    LogEntry le = data as LogEntry;
    if (le != null)
    {
        if (Formatter != null)
        {
           
            WriteLine(Formatter.Format(le));
            return;
        }
    }
    base.TraceData(eventCache, source, eventType, id, data);
}

 now when you add this to your Logging as a listner it will produce a log which will look similar to this

[code]

Timestamp: 04/02/2008 15:58:04
Message: 3ef9ed0b-33a2-4701-8b98-c76b4ace8ae0
Category: General
Priority: 1
EventId: 123
Severity: Critical
Title:unit test 04/02/2008 15:58:04
Machine: machineName
Application Domain: UnitTestAdapterDomain_ForD:\TestLogging.dll
Process Id: 2296
Process Name: C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\vstesthost.exe
Win32 Thread Id: 344
Thread Name: AdpaterExeMgrThread1
Extended Properties:
<--End-->

Timestamp: 04/02/2008 19:04:34
Message: 33beaba7-4d21-4d55-a7ac-629877cdaac0
Category: General
Priority: 1
EventId: 123
Severity: Critical
Title:unit test 04/02/2008 19:04:33
Machine: machineName
Application Domain: UnitTestAdapterDomain_ForD:\TestLogging.dll
Process Id: 4276
Process Name: C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\vstesthost.exe
Win32 Thread Id: 5940
Thread Name: AdpaterExeMgrThread1
Extended Properties:
<--End-->

 So Now we need a function or two to get the results back as log objects, allowing us to write unit tests against the results. Using regular expressions, we can get all the information quite simply :

[code]

((?:Timestamp\:)(?<Timestamp> .*))
((?:Message\:)(?<Message>(.|[\n\r])*?))
((?:Category\:)(?<Category> .*))
((?:Priority\:)(?<Priority> .*))
((?:EventId\:)(?<EventId> .*))
((?:Severity\:)(?<Severity> .*))
((?:Title\:)(?<Title>.*))
((?:Machine\:)(?<Machine> .*))
((?:Application Domain\:)(?<ApplicationDomain> .*))
((?:Process Id\:)(?<ProcessId> .*))
((?:Process Name\:)(?<ProcessName> .*))
((?:Win32 Thread Id\:)(?<Win32ThreadId> .*))
((?:Thread Name\:)(?<ThreadName> .*))
((?:Extended Properties\:)(?<ExtendedProperties>(.|[\n\r])*?))

This regex will work for the default formatter which the Patterns and Practices uses. As you may have noticed it uses groups, allowing for us to easily reference the values in a method to retrive. The following takes the above regex and populates the values into LogEntry objects

/// <summary>
/// load all the log into an array
/// </summary>
/// <param name="fileLocation"></param>
/// <returns></returns>
public static List<LogEntry> GetAllLogEntries()
{
    Regex reg = new Regex(logRegEx, RegexOptions.Multiline);
    string log = File.ReadAllText(LogLocation);
    List<LogEntry> result = new List<LogEntry>();
    MatchCollection mC = reg.Matches(log);

    LogEntry l;
    Console.WriteLine("loading data");
    foreach (Match m in mC)
    {
        l = new LogEntry();
        l.Message = m.Groups["Message"].ToString().Trim();
        l.TimeStamp = DateTime.Parse(m.Groups["Timestamp"].ToString().Trim());
        l.Priority = int.Parse(m.Groups["Priority"].ToString().Trim());
        l.Title = m.Groups["Title"].ToString().Trim();
        result.Add(l);
    }

    Console.WriteLine("loaded " + result.Count.ToString() + "logs entries");

    return result;
}

Its simple to use, I placed this in a Class library built it and then referenced it from the logger and from my unit tests.

TextTraceListener.cs (6.34 kb)

Todo:

add this into a class library project. (give it the name :LoggingLibraryTest)
Compile the project (this will generate a DLL file.)

reference the DLL with in your TDD ptoject, and also set the Enterprise logging to custom and point the custom listner to a copy of the DLL.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5