Bill Pierce pointed out a new OSS app that seemed to meld with nUnit better than nUnitAsp which I have tried unsuccessfully to implement before.  Wanting more "confidence" in the inherited mess that I've been given I set out to write up a few test tests (calling up google and performing a search), and then do some stuff with my web app.  Below I will document the setup procedure that I followed (which could be considered verbose, but I sometimes like that) to get things running.

I'm using WaTin version 0.9.5, nUnit version 2.2.8, Visual Studio 2003, with TestDriven.NET 2.0.1948 RTM.

I created a new Console Application with a name of Tests.

To configure WaTiN to interact with nUnit (nUnit uses the STA ApartmentState) you need to first add App.Config file to the project with the following XML inserted into the configuration tags:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="NUnit">
<section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
</sectionGroup>
</configSections>
<NUnit>
<TestRunner>
<!-- Valid values are STA,MTA. Others ignored. -->
<add key="ApartmentState" value="STA" />
</TestRunner>
</NUnit>

</configuration>

This XML will allow you to not have to put in "System.Threading.Thread.CurrentThread.ApartmentState = System.Threading.ApartmentState.STA;" into your Setup method below (which only works in a 1.1 app anyway).  [Note:The App.Config file will be copied upon a build to the same directory as your exe file under the name of Tests.exe.config.]

Once this is finished you then need to add a few references to the project.  Add both WatiN.Core and nunit.Framework references to the project.

I then created a TestBase class that would take care of opening and closing out my browser.  Since I have to authenticate through the system, I also added a function that would take care of this too.  The code follows:

using System;

using NUnit.Framework;

using WatiN.Core;

using System.Text.RegularExpressions;

 

namespace Tests

{

  public abstract class TestBase

  {

    protected IE ie = null;

    private bool logged = false;

 

    protected bool LoggedIn

    {

      get { return logged; }

      set { logged = value; }

    }

 

    [TestFixtureSetUpAttribute]

    public void SetUp()

    {

      ie = new IE();

    }

 

    protected void Login()

    {

      ie.GoTo("http://yours");

      ie.TextField(Find.ById("Login1_txtUserId")).TypeText("user");

      ie.TextField(Find.ById("Login1_txtPassword")).TypeText("pass");

      ie.Image(Find.ByName(new Regex("[a-zA-Z0-9]*btnLogin"))).Click();

      this.LoggedIn = true;

    }

 

    [STAThread]

    static void Main(string[] args)

    {

      // This is just a test project but there needs to be a Main method for compilation.

    }

 

    [TestFixtureTearDownAttribute]

    public void TearDown()

    {

      ie.Close();

    }

  }

}

My tests then for checking the helpdesk login, a bad login, inputting a helpdesk ticket, checking the data and cleaning up are as follows:

using System;

using NUnit.Framework;

using WatiN.Core;

using System.Text.RegularExpressions;

 

namespace Tests

{

  [TestFixture]

  public class HelpDesk : TestBase

  {

    [Test]

    public void CheckBadLogin()

    {

      ie.GoTo("yours");

      ie.TextField(Find.ById("Login1_txtUserId")).TypeText("user");

      ie.TextField(Find.ById("Login1_txtPassword")).TypeText("pass");

      ie.Image(Find.ByName(new Regex("[a-zA-Z0-9]*btnLogin"))).Click();

      Assert.IsFalse(ie.ContainsText("Stuff"));

    }

 

    [Test]

    public void CheckLogin()

    {

      this.Login();

      Assert.IsTrue(ie.ContainsText("Stuff"));

    }

 

    [Test]

    public void CheckHelpDeskTicket()

    {

      if(!this.LoggedIn)

        this.Login();

 

      ie.GoTo("otherurl");

      Assert.IsTrue(ie.ContainsText("stuff"));

      ie.TextField(Find.ById("txtTitle")).TypeText("A");

      ie.SelectList(Find.ById("ddlNewRequestType")).SelectByValue("0");

      ie.SelectList(Find.ById("ddlNewDepartment")).SelectByValue("2");

      ie.SelectList(Find.ById("ddlNewParentCat")).SelectByValue("16");

      ie.SelectList(Find.ById("ddlNewChildCat")).SelectByValue("21");

      ie.SelectList(Find.ById("ddlNewPriority")).SelectByValue("2");

      ie.TextField(Find.ById("txtNewDescription")).TypeText("A");

      ie.Image(Find.ByName(new Regex("[a-zA-Z0-9]*btnNewUpdate"))).Click();

      Assert.IsTrue(ie.ContainsText("Contains text"));

    }

 

    [Test]

    public void CheckHelpDeskTicketData()

    {

      if(!this.LoggedIn)

        this.Login();

 

      ie.GoTo("yoururl");

      Assert.IsTrue(ie.ContainsText("stuff"));

 

      // See if the data exists in the database

      Data r = new Data();

      r.Where.Title.Value = "stuff";

      r.Where.Title.Operator =  MyGeneration.dOOdads.WhereParameter.Operand.Equal;

      Assert.IsTrue(r.Query.Load());

 

      // Activity is a dependant record that is created with the request

      Data a = new Data();

      a.Where.DataID.Value = r.RequestID;

      a.Where.DataID.Operator =  MyGeneration.dOOdads.WhereParameter.Operand.Equal;

      Assert.IsTrue(a.Query.Load());

 

      // Clean up the data

      a.MarkAsDeleted();

      a.Save();

 

      r.MarkAsDeleted();

      r.Save();

    }

  }

}

From there, now that I have TestDriven.NET's plug in installed I can build the project and then right click and select "Test With..." and then select NUnit.

This will pop-up NUnit and allow me to click on the run button to run through the tests. Berry nice!

Caveat: This is the first ever batch of unit tests that I have written (successfully).  I'm sure there are better ways to organizing tests, files, and what not.  Me != "Unit Test Expert"