Interaction Tests

time to read 9 min | 1612 words

The Shade Tree Developer has a post about TDD Design Starter Kit - State vs. Interaction Testing. I found it interesting because I recently had to use a lot of interaction testing.

I want to test the UI back end, and since I can't get GUI testing to work I'm using the MVP*to seperate presentation and logic. This results in code that looks like this (Please ignore the absimal error message, it's temporary**):

public bool SaveQueryAs()

{

      string name = view.Title;

      string newName = view.Ask("Rename query to:", name);

      if (newName != null)

      {

            Query oldQuery = mainPresenter.CurrentProject.GetQueryWithName(newName);

            if (oldQuery != null)

            {

                  if(view.AskYesNo("Query exist, overwrite?", "Overwrite query?"))

                      mainPresenter.CurrentProject.RemoveQuery(oldQuery);

                  else

                        return false;

            }

            if(Query.OwnerProject==null)

                  mainPresenter.CurrentProject.AddQuery(Query);

            Query.Name = newName;

            view.Title = newName;

            mainPresenter.Repository.SaveQuery(Query);

            view.HasChanges = false;

            return true;

      }

      return false;

}

The UI is composed of forms that implement various IXXXVIew interface (IProjectView, IQueryView, etc). State base testing is nearly useless in this case. The tests I've for this method currently are:

  • Save As can be canceled.
  • Save As rename the query and save it.
  • Save As with conflicting name can be canceled.
  • Save As with conflicting name & user approval removes the old query, rename the query and save it.

In order to test each of those, I'm mocking the view (hard to test it) & the repository (avoid touching the database). The problem I've with those tests is that they feel too... intimate with the object. Then again, I'm not testing the results of a calculation, I'm checking the results of interaction with the user, so there is no easy way to do that using state based testing.

One problem that I'd with this is that refactoring the code cause the tests to break, because I'm using NMock and the refactoring doesn't touch the method names in strings (I understand that on the Java side they are sophisticated enough to do that safely, and Resharper 2.0 should've this capability as well). I'm testing EasyMock.Net right now, it has some Java yuckiness strapped on, but it seems to be a much better solution for refactoring and readability of code than NMock. Unfortantely, it's compiled against an NUnit version from 8 months ago. I'll report more when I done with it. I really liked the way it works.

* Model View Presenter, not related to Microsoft

** There is a saying in the IDF, "The temporary is here to stay, the permanent things go away"