Thursday, April 21, 2005

This blog has moved. My blog can now be found at:

http://www.benmonro.com/Blog

Monday, April 18, 2005

NUnitAsp Rocks!



I've been using NUnitAsp at work for the last week or so. I must say, at first I was not too impressed because it lacked some of the features I desired, namely support for Repeaters. However, it was the only web gui unit testing for C# so I figured what the hell, I'll be a hippy and contribute some code.

So in I went hunting through the code for the DataGrid to see how it handles rows. After a while I decided, ok, time to write a unit test. I ended up writing something like this:

(sorry for the code formatting, the <pre> tag jacks up blogspot's layout)


[Test]
public void TestRepeaterRowCount
{
RepeaterTester someRepeater = new RepeaterTester("someRepeater", CurrentWebForm);
//CurrentWebForm is defined in the NUnitAspTestCase.SetUp() method.

Assert.AreEqual(3, someRepeater.ItemCount);
}

Now let me ask you this? If you know a test is going to fail, do you actually run it in the nunit-gui? I usually don't.

Of course, by now I've resharper'd my code to compile. Which brings me to one problem with Resharper, it won't create or move classes in new files. Yeah, yeah, I know, IntelliJ will.

First things first, I have to define my constructor. I figured I'd use the same signature as all the other Testers already built; 2 parameters, the aspnet control name and the container object it resides in. Easy enough:

public RepeaterTester(string aspId, Tester container) : base(aspId, container)
{
_tagXpath = "*[starts-with(@id, '" + this.HtmlId + "__ctl')]";
}



Now where the heck did that _tagXpath come from? Well, it came a few iterations later when I realized that NUnitAsp is all about XPath. See, the AspControlTester base class takes care of almost everything for you. All you need to do is define how it finds the elements on a page which it has converted into XHTML. Nifty eh?

Another thing to note is that use of the HtmlId. This is also defined in the base class, and it takes care of all the naming and containers and what not. It comes out as the Id of the control in the HTML DOM as its rendered on the page.

So now I define my Repeater.ItemCount property. For you java hippies, a property is like a built in getter and setter with nicer syntax. For you Ruby ninjas, well you do it even better than C#. :)

so here's my Repeater.ItemCount:

public int ItemCount
{
get
{
int itemCount;
try
{
HtmlTag lastChild = Tag.Children(_tagXpath + "[position() = last()]")[0];

string childId = lastChild.Attribute("id");

Match m = Regex.Match(childId, this.HtmlId + @"__ctl(\d+)");

itemCount = Convert.ToInt32(m.Groups[1].Captures[0].Value) + 1;

}
catch (HtmlTag.ElementNotVisibleException)
{
itemCount = 0;
}
return itemCount;
}
}



Again, this came after a few red/green iterations, but I finally realized that the last child in the list of Repeater controls was named with __ctlX where X is the N-1 th element in the list. Not bad, though, I wish I had ruby/perl style regular expressions.

Of course this still fails, because of that pesky call to the Tag Property. The Tag property tells the base class how to find your html element containing your control. (in this case the repeater items). Again notice the re-use of my xpath:


protected override HtmlTag Tag
{
get
{
return new HtmlTag(Browser, "(//" + _tagXpath + ")[1]/..", this.Description);
}
}



Ok, well, that's great, I can get the row count, whip-dee-friggin-doo. What if I want to get access to a control in a repeater row? Oooh, now we're talkin action.

Let's write another failing test:


[Test]
public void TestLabelInRepeaterRow()
{
LabelTester label1 = new LabelTester("Label1", repeater2.GetItem(0));

NUnit.Framework.Assert.AreEqual("Go Suns!", label1.Text);
}

That little call to repeater2.GetItem(0) is the only thing causing this to fail. Ok, no problem, resharper it and get going.


public Item GetItem(int rowNum)
{
return new Item(rowNum, this);
}



public class Item : AspControlTester
{
private int _rowNum;
private RepeaterTester _container;

public int RowNum
{
get
{
return _rowNum;
}
set
{
_rowNum = value;
}
}

public Item(int rowNum, RepeaterTester container) : base(rowNum.ToString(), container)
{
_rowNum = rowNum;
_container = container;
}




}


Run the test again and presto, we're green again. All the Item class does is serve as a container for the items inside each Repeater Item. nothing more really. Though if you wanted to add something more (like the RowNum property, its pretty straight forward.

Its really as simple as that...

And guess what, this even supports Nested Repeaters. Go ahead, try it out, write a failing test!

Wednesday, April 06, 2005

Don't say nuttin'

Its amazing to me sometimes how silly people can be. The first thing you learn in kinergarten is "if you haven't got anything nice to say, don't say anything at all." Well, I suppose its the second thing to "don't poop on the sleeping mat." But anyway, apparently some people need a rule book to know they shouldn't be posting bad things about their employers. I personally love Apollo Group, they are a fantastic company (requires free registration) to work for!

Thursday, March 31, 2005

Ok, so in my search of the religion that is right for me, I take this quiz and find that I am a satanist agnostic with Athiestic, Buddhist and Jewish values. As I suspected. Satanist? wait a minute. I dont worship the devil, although I did go to ASU, oh no, Sun Devils. Ah crap, I'm cursed! What to do?

You scored as agnosticism. You are an agnostic. Though it is generally taken that agnostics neither believe nor disbelieve in God, it is possible to be a theist or atheist in addition to an agnostic. Agnostics don't believe it is possible to prove the existence of God (nor lack thereof).

Agnosticism is a philosophy that God's existence cannot be proven. Some say it is possible to be agnostic and follow a religion; however, one cannot be a devout believer if he or she does not truly believe.

agnosticism

92%

Satanism

88%

atheism

63%

Buddhism

42%

Judaism

33%

Islam

33%

Paganism

25%

Christianity

21%

Hinduism

13%

Which religion is the right one for you? (new version)
created with QuizFarm.com

Tuesday, March 22, 2005

I should probably take this again, just to be sure, but until then: