Homepage | About Me | Mayday | Testing ASP.net Book | Follow me on Twitter | GitHub | SlideShare | RSS | DropBox referral link
Blog.BenHall.me.uk

Alt.Net.Uk Registration opens January 2nd

Friday, December 28, 2007

Just a quick announcement that the registration for Alt.Net.UK will open on January 2nd. We are doing the registrations in two batches, we will announce when the 2nd round of registration opens at a later date.

Ian has posted more information - Registration for altnetconf opens January 2nd

Keep an eye on the blogs/site...

Technorati Tags: ,

Labels: ,

Merry Christmas

Tuesday, December 25, 2007

Merry Christmas readers!!   Hope everyone is enjoying themselves and got everything they wanted.

http://xkcd.com/361/

Labels:

Installing Windows 2008 Enterprise Core Server RC1

Saturday, December 22, 2007

Based on my previous post, I wanted to see what the difference was when installing the core edition of Windows server.  With the 2008 release, Microsoft have included a really streamlined version of Windows 2008 which you must configure manually based on what you actually want it to do for maximum performance. This is going to be great for splitting tasks (database, mail, web) over multiple virtual machines as they will all be really lightweight.

The install is the same, however you just need to select the core instead of full. When the server boots up, you will be shown the standard login screen.

 5CoreLogin

Pressing Ctrl alt del, no users will be listed but you will be allowed to login as Other User (confusing).

5OtherUser

Clicking that, you are shown the screen below. So, I gave it a go and entered Administrator as the username and left the password blank and entered myself a new password.  This worked and logged me in.

5ChangePwd

I was then shown a cmd prompt.

6Cmd

Thats it! That is Windows Server core.  Everything is done via the cmd - it's so Linux! Time to get those scripting/command line skills back out. 

Technorati Tags:

Labels:

Red Gate SQL Data Generator 1.0 Beta

Thursday, December 20, 2007

SplashToday, Red Gate have released the beta for SQL Data Generator 1.0. This is a product I have been working on for the past few months and its great to release a beta for everyone to use.

"This tool is aimed at generating test data for SQL Server databases. It can either generate data from scratch or import from existing sources of data.(Like SQL tables or CSV files.)
Features:
- Full SQL Server 2000 and 2005 support
- All data types supported except CLR types
- Pre & Post Scripts execution
- Command-line access version
- Import data from CSV or SQL tables
- Customizable generator settings that allow configuring the amount of nulls, unique values, minimum and maximum values, etc..
- Diverse range of inbuilt generators
The product is not yet complete, and we are looking for user feedback about what features and or functionality you would like in the final product.
*The beta version is set to work until 11 Apr 2008. "

This is a free open beta with the application due to expire on 11 April 2008 with a planned final released sometime before then. 

What we really want now is for everyone to use the software and provide us with feedback for the final version.  Please let us know on the forums what you like and don't like about the software and what we could do to solve all of your data generation problems!

Visit http://www.red-gate.com/MessageBoard/viewtopic.php?t=6140 for the announcement and download URL

Product page - http://www.red-gate.com/Products/SQL_Data_Generator/

Forums: http://www.red-gate.com/MessageBoard/viewforum.php?f=76

UPDATE: We have just released Beta 2 of the application, please visit the product page for more information and to download.

Technorati Tags: ,

Labels: ,

Model View Controller (MVC) Pattern - The core concept

Everyone is talking about the Model View Controller, or MVC, pattern.  In this post I'm going to focus on the pattern itself and the concepts around it for anyone who hasn't come across this pattern before, or who just wants a simply refresher.  The pattern itself has been around for many years, way back to the days of smalltalk, however has become popular and came into the limelight over the last number of years with different web frameworks 'encouraging' the use of the pattern.

The pattern describes how to separate your business logic (what the application should do) and the UI (how it looks).  There are huge advantages to this:

  • It promotes code reuse as code isn't isolated in a button's click action
  • Maintenance of the application is easier as changing one side of the system doesn't have the additional noise of the other side.  When changing your business rules, you don't have to interact with the code which displays everything on screen.
  • UI is difficult to test, if you remove the UI then testing becomes easier.  As everything is more separated and has cleaner interfaces, it becomes easier to write your automated test cases.
  • Having everything separated means different parts can be interchanged/replaced easier.

What the pattern is really attempting to achieve is a separate of concerns with the different parts of the system just dealing with their own responsibilities.

However, most applications do not follow this pattern and mix up all the layers together. Microsoft samples are quite bad for doing this where they have SQL connections and queries in a button click event. However, the current architecture of WebForms doesn't fit well with the MVC approach (of course part from the new MVC framework).  The reason it doesn't fit well is because you can have SqlDataSource and DataGrids on the webpage which contain sql statements and database connections resulting in just a single UI layer.  This is fine for Rapid Application Development (RAD) and very quick sites, but for enterprise level applications this approach is not maintainable.

By following the MVC pattern, your application will be architected in a very different manner. There are three main components to the system:

  • Model - Object representing data or state within the system.  This could be an 'Order' object which represents a row in the database or maybe an arm on a robot.
  • Controller - This handles the application flow.  This handles which views should be rendered, which data to display and any validation which is required.  This is most definitely not a God Class and its important not to put everything into a single controller. 
  • View - The single role of a view is to correctly display the data.  It takes the model given to it from the controller and outputs it in the correct way.

With an application separated in this way, we can replace different parts of the application without affecting too much of the application.  How we actually implement the pattern is dependent on the platform building upon. It is possible to implement this pattern in any system, however the new ASP.net MVC Framework will definitely help in managing the interaction.

Technorati Tags: ,

Labels:

Installing Windows 2008 Enterprise Server RC1

Tuesday, December 18, 2007

Over the weekend, I decided to have a quick look at Windows 2008 Enterprise Server as RC1 has been recently released.  You can download a free 30 day trail from here.  What I'm going to cover in this post is just how to get started and install the OS. I'm using VMWare 6 to install the operating system.

1) After booting of the DVD, the first task is to select your language and keyboard layout. Much like with Windows Vista.

1Install 

2) Enter your license key information, leave it blank for the 30 day free trail.

2Key

3) Select the version of Windows 2008 to install, notice the difference between Full and Core. You can select three editions, Standard, Enterprise, Data centre based on the Enterprise ISO I downloaded.  Web sever is a separate download.

3Edition

4) Windows will then go ahead and install the OS.

4Installing

5) Done! The operating system is now full installed, it just needs a bit of config.  The first thing it does when it boots up is tell you that you need to change the Administrator password by entering a new password.

5ChangePwd

5aChangePwd

6) After setting the password, you will be logged in and an Initial configuration tasks dialog is displayed.  This is where you can configure the server, give it a correct name, turn of Windows Update (which is off by default) and configure the roles for the server.

6InitalSetup

7) If you select to add roles, you will be shown a list of possible roles the server can perform. For example, active directory domain servers, web server, DHCP server so you can mix and match to meet your requirements.

7AddRole

8) The other option is Select features.  This is where you can add different features, such as .Net 3.0 as only 2.0 is installed by default, and other stuff server type stuff!

8RoleSettings

Best feature: Desktop Experience - Make your Windows 2008 Enterprise Server look and act like Windows Vista!! Aero all the way baby!

That's really it.  To get started with 2008 is really simple.  You can easily tell 2008 and Vista are closely related.

One thing I did notice, the Administrator account does not get prompted for UAC, but you can create a standard user which will have UAC.

Technorati Tags:

Labels:

Process.Start and first time launching Firefox

Monday, December 17, 2007

I was going over the MbUnit issue list and came across Issue 97. This had a really interesting scenario.  Basically, Firefox was the default web browser but didn't have a profile associated with it (it hadn't been executed yet) and when you try and launch it via Process.Start it will load firefox correctly however also throw a Win32Exception.

If you did something like this:

Process.Start(http://www.google.co.uk);

The exception would be:

System.ComponentModel.Win32Exception was unhandled
  Message="The system cannot find the file specified"
  Source="System"
  ErrorCode=-2147467259
  NativeErrorCode=2
  StackTrace:
       at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
       at System.Diagnostics.Process.Start()
       at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
       at System.Diagnostics.Process.Start(String fileName)
       at ConsoleApplication1.Program.Main(String[] args) in ......\Program.cs:line 13
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

Very strange, if anyone knows the extract reason why it decides to thrown an exception please leave a comment. Definitely something to be aware might happen.  Wonder how many applications would crash because of this...

When testing your applications, if you want to reproduce this without having to load a clean VM, go into your %AppData% and move the Mozilla directory to another location.  Next time you load Firefox, the dialog will be displayed and the exception will be thrown.

Technorati Tags:

Labels:

'System.Web.Mvc.Controller' is defined in an assembly that is not referenced

Sunday, December 16, 2007

While I was playing around with the Mvc framework, I received this error message:

The type 'System.Web.Mvc.Controller' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Web.Extensions, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. 

What this simply means, is that I forgot to reference the System.Web.Extensions within my code,  in this case it was by test harness/project.

image image

However, when I looked in the .Net reference table, I couldn't see the 3.6.0.0 assembly listed.  I went into the GAC (C:\Windows\Assembly) and there it was listed but it wouldn't let me reference the assembly. Finally, I went to C:\Program Files\Reference Assemblies\Microsoft\Framework\ASP.NET 3.5 Extensions\ and added the reference from there.

Remember, if your creating your own test project with NUnit or MbUnit then you will need to reference System.Web.Extensions within that project as well.

Technorati Tags: ,

Labels:

First play with ASP.net MVC

Thursday, December 13, 2007

(UPDATE: Cheers LiveWriter - Post to weblog as draft causes it to publish. Sorry for any mistakes in first attempt, this I have fixed them all) In this post, I'm going to discuss my experience while having a play with the ASP.net MVC framework. Over the next series of posts, I'll go back over some of the items discussed and deep dive into them to provide more information. Tonight, I just wanted to get my initial thoughts out while it was still hot.

The installation and download was quite simply and didn't have any problems with the install.

image

However, this brings me onto problem number one. The assemblies are required to be installed into the GAC! This is impossible with Shared Hosters (unless some hosters out there are willing to install CTPs on production servers). This means I can't deploy samples / test sites until its RTM! Guess I'll just have to publish the code. If anyone knows any hosters offering ASP.net MVC hosting, please leave a comment.

Once installed, you will have a number of new templates within your Visual Studio new project dialog.

image

There are two main projects, one is ASP.NET MVC Web Application and Test with the other being ASP.NET MVC Web Application. The first project includes the second project type (just the web app) which will setup the correct folder directory and give you the base template to fill in. It will also create a MSTest project to start writing your unit tests.

After creating the projects. the layout is below.

image

A few things I wanted to point out. The content directory has the stylesheet for the site, this is where images etc will go. The controllers folder will contain the controller classes which will have all the methods for the application. The models will contain any objects related to storing your data. Views will contain the ASPX pages (and master pages).

The other thing you notice is that there is a default.aspx in the root directory. If you open the file, it has the following message.

<!-- Please do not delete this file. It is used to ensure that ASP.NET MVC is activated by IIS when a user makes a "/" request to the server. -->

This makes sense, bit of a hack but never mind. If we load the website, then it will look like below.

image

Great, now lets start having a play. First thing I want to do, add a text box. Hit F5 and I got an exception.

System.Web.HttpException was unhandled by user code Message="Control 'ctl00_MainContentPlaceHolder_TextBox1' of type 'TextBox' must be placed inside a form tag with runat=server." Source="System.Web" ErrorCode=-2147467259

As I added the control in code view, it didn't automatically add a form tag for me. Easily fixed.

Hit F5 again and I got another exception.

System.NullReferenceException was unhandled by user code Message="Object reference not set to an instance of an object." Source="App_Web_t1migfpo"

This was because Visual Studio had pointed me to the full path for the ASP.net page (WebForms style - http://localhost:64701/Views/Home/Index.aspx). However, with MVC this doesn't work as you navigate the site via defined routes, if I go directly to the root of the website and it works fine.

Now, the main thing I want to look at first is how to test the controller.

Testing the controller

The first task I wanted to do was delete the test project and re-created it with a C# class library referencing the MbUnit.Framework assembly.

After I had it correctly building, I wanted to test the Index action on the test controller. This is the first method called in our code and deals with what should happen when the homepage / index is visited. At the moment, all it does it tell the Index page to render.

Just to get an idea, I just wrote the simple test below to see what happened (and changed) when Index() was called.

[Test] public void IndexTest() { HomeController controller = new HomeController(); controller.Index(); }

However, this throw an exception.

[failure] HomeControllerTests.IndexTest TestCase 'HomeControllerTests.IndexTest' failed: Object reference not set to an instance of an object. System.NullReferenceException Message: Object reference not set to an instance of an object. Source: System.Web.Extensions

Instant mistake. All the methods on the Controller have the [ControllerAction] attribute and a number of dependencies exist behind the scenes.

At this point, I referred to Phil Haack's post on Writing Unit Tests for Controller Actions (sounds like what i'm doing). What Phil describes is to use a 'Test specific subclass'. Using his approach, I change my test to interact with HomeControllerTester

[Test] public void IndexTest() { HomeControllerTester controller = new HomeControllerTester(); controller.Index(); }

I then create the HomeControllerTester which overrides the RenderView method and stores the name in a property.

internal class HomeControllerTester : HomeController { public string RenderViewAction { get; private set; } protected override void RenderView(string viewName, string masterName, object viewData) { RenderViewAction = viewName; } }

I can then include a Assert.AreEqual("Index", controller.RenderViewAction); to ensure the correct view is called. This is easy, but it is additional work just to verify that the correct view is being called.

Another approach he mentioned was using Rhino Mocks, which I have used once or twice before in previous posts. However, it appears as if that support for mocking the RenderView method in this CTP is broken. The only approach is to use the subclass above.

Outputting data

Next thing I wanted to try was creating data within the controller and passing it to the view for outputting.

Within my index method, I just create a dummy generic list of strings which I want to output.

[ControllerAction] public void Index() { List<string> topics = new List<string>(); topics.Add("My String 1"); topics.Add("My String 2"); topics.Add("My String 3"); topics.Add("My String 4"); RenderView("Index", topics); }

When calling RenderView, I pass in the generic list as an argument. Now, I just need to output the data. Within index.aspx, I added the following code snippet. This

<h3>Outputting data</h3> <form runat="server"> <ul> <% foreach(string s in ViewData as System.Collections.Generic.List<string>) { %> <li> <%= s %> </li> <% }

%> </ul> </form>

However, with this I got a compiler error message.

Compiler Error Message: CS0039: Cannot convert type 'System.Web.Mvc.ViewData' to 'System.Collections.Generic.List<string>' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion

Looking at the ViewData within the debug view, it has added a _data block and each element within my list is a separate item. However, I couldn't find a way to extract that data as _data is a private member. The only way to extract the data is based on a name.

image

Within my controller, I changed the code to setup the ViewData

ViewData["Topics"] = topics; RenderView("Index");

I then changed my output code to be the following:

foreach(string s in ViewData["Topics"] as System.Collections.Generic.List<string>)

The data is then correctly outputted to the screen.

image

The debug window then looks as I expect with _data containing the generic list.

image

I'm guessing the ViewData constructor is used for something else or its a bug in the rendering. In the documentation, it does say we this is valid syntax:

[ControllerAction] public void Categories() { List<Category> categories = northwind.GetCategories(); RenderView("Categories", categories); }

Strange! Moving on, referring object is so .Net 1.1. I want to work with strongly typed objects. The first thing I want to do is create the object

public class TopicsViewData { private List<string> topics = new List<string>(); public List<string> Topics { get { return topics;} } }

This will store all of my view data. I can then change my Index code to use the ViewData object.

[ControllerAction] public void Index() { TopicsViewData viewData = new TopicsViewData(); viewData.Topics.Add("My String 1"); viewData.Topics.Add("My String 2"); viewData.Topics.Add("My String 3"); viewData.Topics.Add("My String 4"); RenderView("Index", viewData); }

I then pass in the viewData object as the parameter, which works fine. Within Index.aspx.cs (yes, MVC still has code behind, its just used less often) I change what the page is inheriting from. In the previous version, it simply inherited from ViewPage.

public partial class Index : ViewPage

However, to use a custom View Data object we need to use the generic ViewPage and pass in the ViewData object.

public partial class Index : ViewPage<TopicsViewData>

We can now access all the properties of TopicsViewData from within Index.aspx

<% foreach(string s in ViewData.Topics) { %> <li> <%= s %> </li> <% } %>

Bit of additional work, but does make it a lot easier to work with.

MVCToolkit

The MVCToolkit has the following (according to the readme):

"- Rendering helpers which make it easier to output various HTML tags in MVC Views

- Dynamic Data support: this gives ASP.NET MVC a powerful and extensible scaffolding architecture. The toolkit also adds metadata pluggability, which allows the metadata used by Dynamic Data to use alternate stores (instead of the default attribute based mechanism)."

One thing not mentioned is that it includes the Blog sample application which uses the Dynamic Data support controls. Subject for another post...

Documentation

There is a bit of documentation over at http://quickstarts.asp.net/3-5-extensions/

Summary

In summary, this was just a very quick look at wjats om the CTP, the framework is still very early in the development. Some of the concepts are there and its at the level I expected for thisw CTP. Still worth looking at and having a play. I'll post more as I find things out.

One thing I have quickly realised is that I have a lot of reading and work to do to get up to speed with MVC, IoC and how to other MVC frameworks (Monorail) interact. Don't worry - I'll be blogging my learning and experience.

Download MVC: http://www.microsoft.com/downloads/details.aspx?FamilyId=A9C6BC06-B894-4B11-8300-35BD2F8FC908&displaylang=en

Download MVC Toolkit: http://asp.net/downloads/3.5-extensions/MVCToolkit.zip

Technorati Tags: ,

Labels: ,

Gift from Microsoft - Visual Studio 2008 Thank you

Wednesday, December 12, 2007

Last night when I got back home from a NxtGenUG session I had a gift from Microsoft for helping with the Visual Studio 2008 Beta (I think it was due to submitting a few bugs). The gift was a glass cube with an engraving.  Looks cool.

The Box

IMAGE_005 

The message

IMAGE_006

The Cube

IMAGE_008

The engraving doesn't really come out but its got Visual Studio 2008 and .Net framework.  It's now happily sitting on my desk.  Thanks team!

Technorati Tags:

Labels:

Red Gate Exception Hunter

Monday, December 10, 2007

Today, the .Net division at Red Gate released a brand new tool called Exception Hunter.  Exception Hunter allows you to load in any .Net assembly and reports back any possible exceptions the function might throw.  This allows you to locate unhandled exceptions quickly, down to the line of code where the exception is being thrown - even if its within the framework itself.

Red Gate Exception Hunter

I've been playing around with it while it was being developed and really think it's a great application. Well done to the team!

Visit http://www.red-gate.com/products/exception_hunter/index.htm for more information, screenshots, demo and a 14 day trail.

Data Sheet - http://www.red-gate.com/products/Exception_Hunter/Exception_Hunter.pdf

UPDATE: Bart worked hard on this, read his post - http://www.simple-talk.com/community/blogs/bart/archive/2007/12/10/40742.aspx

Technorati Tags:

Labels:

How to: Break when an exception is thrown.

Saturday, December 08, 2007

While helping me to solve a threading issue, Robert mentioned this little gem.  Within Visual Studio, you can set it so that it breaks on all Exceptions (not just the unhandled exceptions). No longer do I need to keep stepping over code to see when an exception was thrown, I can simply bring up the exceptions dialog (ctrl + alt + E, or Debug > Exceptions) and tell it to break when a CLR Exception is thrown!  Now, as soon as an exception is thrown it will break at the point the exception was thrown.  You can then enable editing and see what was actually happening.

image

I knew it could be done, but had completely forgotten how/where to set it, where to the point I had forgotten it could be done...

Happy debugging!

Technorati Tags: ,

Labels:

Screencast: Getting started with MbUnit

Last weekend I decided it would be great fun to do a simple screencast about getting started with MbUnit.  It's just a very quick, create project, add reference, execute screencast but hopefully it will be useful if this is your first time to a unit testing framework and you want to get started. It also gave me chance to play around with Camtasia.

Well, it wasn't as much fun as I first thought. I had a number of attempts to find out how to actually create a screencast and I think I fall into most pitfalls along the way (but its all experience right?), that can be another post.

The outcome was that I managed to created a screencast on Getting Started with MbUnit.

Download: Screencast_GettingStartedWithMbUnit.wmv

Length: 8 Mins 56 seconds

Size: 8.71MB

Now I have a better understanding of what to do, I might create a few more! Next ones will be better...

Technorati Tags: , ,

Labels: , ,

Connect with Me - Windows Live Button

Friday, December 07, 2007

Today I saw on Steve Clayton's blog a little Connect with Me image which linked to his MSN/Windows Live account.  I thought it was cool so I added it onto my sidebar.  Feel free to add me!

Add your own button to your blog: http://www.gowindowslive.com/Messenger/Button/Default.aspx

Technorati Tags: ,,

Labels:

Alt.Net.UK Conference - 1st/2nd February 2008

Thursday, December 06, 2007

I'm really pleased to announce that there is going to be an Alt.Net conference in the UK - called Alt.Net.UK!  For those of you who haven't heard of Alt.Net, read David Laribee's post to better understand the term - What's ALT.NET

The conference will be held on Friday 1st and Saturday 2nd February 2008 at the Conchango offices in London and is being organised by Ian Cooper, Alan Dean, Robert Grigg (Conchango), Michelle Flynn (Conchango) and myself!

As for the agenda, well that is up to the people who attend.  We will be following an open spaces format, similar to the Austin Texas conference earlier in the year, where the agenda is decided by the conference participants.  Anyone can lead sessions on particular topics of interest, participate as an attendee or just hang around and chat with interesting people.

Please note that registration is not open yet!  I will blog more when we have information on this, hopefully it will open shortly. I can say that the conference will be free of charge.

If you have any questions, please feel free to contact us. I'm really looking forward to this, should be a great event!

Keep an eye on the conference site and the blogs for more information - www.AltNetUK.com

Thank you to our sponsors:

conchango_logo    

RedGate_logo

Technorati Tags: ,,

Labels: ,

WatiN Integration into MbUnit\Gallio Reports

One of the cool items I didn't mentioned in my announcement post is that we now have the ability to integrate screenshots from a WatiN test into the reports.

Here we have a simple test which searches for MbUnit on Google and then asserts to check that NUnit is mentioned on the page (this fails).

[Test]
public void DemoCaptureOnFailure()
{
    using (Log.BeginSection("Go to Google, enter MbUnit as a search term and click I'm Feeling Lucky"))
    {
        ie.GoTo("
http://www.google.com");

        ie.TextField(Find.ByName("q")).TypeText("MbUnit");
        ie.Button(Find.ByName("btnI")).Click();
    }

    // Of course this is ridiculous, we'll be on the MbUnit homepage...
    Assert.IsTrue(ie.ContainsText("NUnit"), "Expected to find NUnit on the page.");
}

Normally, it would be hard to find out what was actually on the webpage at that point to see why the test decided to fail. In the tear down method, there is a check if the test passed or failed, if it failed then it takes a snapshot and includes it in the report.

[TearDown]
public void DisposeBrowser()
{
    if (Context.CurrentContext.Outcome == TestOutcome.Failed)
        Snapshot("Final screen when failure occurred.", LogStreamNames.Failures);

    if (ie != null)
        ie.Dispose();
}

When you view the report, on the test that failed you can see that the screenshot of the webpage has been included.  This will make debugging the error a lot easier, making the tests more useful.

image 

I think this is a great feature, well done to Jeff and the team for implementing this.

Technorati Tags: ,

Labels: ,

T-Mobile (UK) Release Windows Mobile 6

Tuesday, December 04, 2007

This made me very happy yesterday when Jason Langridge posted this.  T-Mobile have officially released Windows Mobile 6 for a range of their Windows Mobile phones, including my MDA Vario II.

All you need to do is go to the Download Site and grab the release.

Few comments I have after installing it.

  • WM6 wipes everything on your phone
  • Very hard to find a good backup program. I gave up, copied all the files onto my laptop and numbers onto my sim card (I found an option in one of the menus to do this).  Meant I lost all SMS messages.
  • Install is very easy.  Plug phone in over USB, run the installer and it will install happily
  • WM6 looks very nice
  • Its faster

It will keep me happy until a iPhone with 3G and built in GPS is released.  Having said that, Windows Mobile 6.1 is on some of the new phones.  Screenshots are at http://www.boygeniusreport.com/2007/12/03/windows-mobile-61-standard-in-100-pictures/

I also installed TouchPal which is very cool. 

Technorati Tags: ,,

Labels:

Finding assemblies\modules currently in use

Sunday, December 02, 2007

Today I was trying to debug a problem and needed to see if locking was the issue.  Quick search online and I came across the tasklist command line application.  This lists all of the applications currently open together with the modules they have loaded.

To execute the list, open a command line window and type

tasklist -m

This will return everything.  If you want to stop and see everything you will need to use the more pipe.

tasklist -m | more

If you want something a bit more useful, type in the module your interested in.  This will then return only the applications open which has the module loaded.

tasklist -m MbUnit.Framework.dll

Finnally, to see a particular application with all the modules loaded you need to use a filter based on the IMAGENAME.

tasklist /FI "IMAGENAME eq MbUnit.GUI.vshost.exe" -m

I thought it was cool! :)

Technorati Tags: ,

Labels: ,

How to Unit Test - WatiN, MbUnit and ASP.net

Saturday, December 01, 2007

Today, I am going to be looking at WatiN, which stands for Web Application Testing in .Net, and seeing how well it actually works with an ASP.net web application.

WatiN is a type of record and playback framework to allow for automating the UI testing for web applications.  It uses IE and allows you to interact with the page, for example clicking buttons and typing in text.

A simple example from their documentation shows how to search for WatiN on google and assert you got the correct results back.

[Test]
public void SearchForWatiNOnGoogle()
{
using (IE ie = new IE("http://www.google.com"))
{
  ie.TextField(Find.ByName("q")).TypeText("WatiN");
  ie.Button(Find.ByName("btnG")).Click();
  Assert.IsTrue(ie.ContainsText("WatiN"));
}
}

You can use any test framework to get started, with MbUnit you simply write the tests as normal, but in your test fixture attribute you need to set the ApartmentState to STA. ApartmentState is part of .Net which states how the thread should execute. STA means that the thread will create and enter a single threaded apartment, everything will just be kept on the single thread. 

[TestFixture(ApartmentState = ApartmentState.STA)]

If you don't have this set, when you run your tests you will receive the following exception:

Message: The CurrentThread needs to have it's ApartmentState set to ApartmentState.STA to be able to automate Internet Explorer.

Type: System.Threading.ThreadStateException
Source: WatiN.Core
TargetSite: Void CheckThreadApartmentStateIsSTA()

Now we have running tests, we can start to look at testing a 'real' application. Below is the screenshot of the application under test (AUT).

image

Entering information would cause the page to look like this:

image

Very simple.  To test this worked correctly, we would want to simulate what the user is doing and to verify it worked the same way a person would, in this case that it displayed the search term typed into the text box.

First we need to find the text box (called searchText) by it's name and enter a string.  We then find the button (by its value - the text displayed to the user and not the ID, the button ID is in fact Button1) and click it.  We then verify the response.

[Test]
public void WatiNSearchText_SearchWatiN_TextDisplayedOnScreen()
{
    IE ie = new IE("
http://localhost:49992/WatiNSite/");

    // Find the search text field and type Watin in it.
    ie.TextField(Find.ByName("searchText")).TypeText("WatiN");

    // Click the search button.
    ie.Button(Find.ByValue("Search")).Click();

    //Verify it contains search term.
    bool result = ie.Text.Contains("WatiN");
    Assert.IsTrue(result);
}

The URL points to the ASP.net development server for the solution, with a static port set.

image

That works with simply html, but what happens when ASP.net is pain with the naming. When using a master page with ASP.net, you place all of the pages content within a ContentPlaceHolder. When ASP.net renders this, to ensure naming of elements does not clash it prefixes the IDs.

Without using the placeholder, the textbox html is:

<input name="searchText" type="text" id="searchText" />

However, after using master pages it becomes:

<input name="ctl00$ContentPlaceHolder1$searchText" type="text" id="ctl00_ContentPlaceHolder1_searchText" />

Not great! All the elements are referred as strings, by moving to master pages all of our tests would break. WatiN will report this as:

Message: Could not find a 'INPUT (text password textarea hidden) or TEXTAREA' tag containing attribute name with value 'searchText'

One solution has been provided by James Avery in his WatiN Test Pattern post.  Here, he basically says that each page in the website should have a adapter in the test code which we code against which in turn calls the page (this is not mocking the page).  It means that changes to the website, such as naming, requires only changing the adapter class to match.  Following his pattern, the test would be:

[Test]
public void WatiNSearchText_SearchWatiN_TextDisplayedOnScreen2()
{
    Default page = new Default("
http://localhost:49992/WatiNSite/");

    page.SearchText.TypeText("WatiN");

    page.SearchButton.Click();

    bool result = page.Text.Contains("WatiN");
    Assert.IsTrue(result);
}

Its a lot easier to read as everything is referred to as the page and you can easily imagine what is happening.  The adapter looking like this:

public class Default : IE
{
    public TextField SearchText
    {
        get { return TextField(Find.ByName("searchText")); }
    }

    public Button SearchButton
    {
        get { return Button(Find.ByValue("Search")); }
    }

    public Default(string url) : base(url)
    {

    }
}

We could even take this a step on and abstract the searching into its own method which we call in the test.

    public void SearchFor(string term)
    {
        SearchText.TypeText(term);
        SearchButton.Click();
    }

The test would then be:

[Test]
public void WatiNSearchText_SearchWatiN_TextDisplayedOnScreen3()
{
    Default page = new Default("
http://localhost:49992/WatiNSite/");

    page.SearchFor("WatiN");

    bool result = page.Text.Contains("WatiN");
    Assert.IsTrue(result);
}

This does solve some of the problems as it makes the tests less dependent on the application code.  However, the ASP.net naming is still getting in the way. If we add another container or the element is inside a custom control we are still going to have a problem.  The answer is RegEx!

In our adapter, I change the way we find the element to use a method RegExName. Now its Find - ByName - RegExName - ElementName.

public TextField SearchText
{
    get { return TextField(Find.ByName(RegExName("searchText"))); }
}

Our RegExName method just takes in the elementname and return a regex which will ignore all of the ASP.net prefixes.

private Regex RegExName(string elementName)
{
    return new Regex(".*" + elementName + "$");
}

By using an adapter and RegEx we can abstract away from the real implementation and make our tests a lot more beneficial.  The tests are quite easy to write as long as you keep things focused. By arranging your tests as above, you should have a lot more long term success.

But having an automated test run for the UI will never replace a human tester as there are other scenarios to test for, cross browser, usability, wording which a test framework cannot test.

Technorati Tags: , , ,

Labels: , , ,

MbUnit v3 and Gallio Automation Platform Alpha 1 - Released

I'm pleased to say that MbUnit v3 Alpha 1 has been released.  This is our first release and contains some really cool concepts, however don't rush and migrate all of your unit tests just yet. If you want to know more about what we have planned in the future take a look at our Roadmap.

Within Alpha 1, there are a few core features which I want to pick out.

Gallio Lcarus

As we are building on top of the Gallio Automation Platform, we take advantage of their UI.

image

Gallio has the ability to execute MbUnit v2.4, MbUnit v3, NUnit and XUnit tests all within the same user interface.  In this screenshot we have all four frameworks executing as a single test run.

image

Over time the GUI will only improve and we have got some great plans going forward.  I think its already an improvement over the GUI today.

Gallio Echo

Like with the UI, we also have a new command line.  Again, this has the ability to execute tests from the four different frameworks. The command below simply loads in all the test assemblies, and outputs a html report to \Reports.

E:\Source Control\MbUnit\v3\build\bin>Gallio.Echo.exe "E:\Users\Ben Hall\Desktop\Gallio Test Resources\MbUnit\Gallio.TestResources.MbUnit.dll" "E:\Users\Ben Hall\Desktop\Gallio Test Resources\MbUnit2\Gallio.TestResources.MbUnit2.dll" "E:\Users\Ben Hall\Desktop\Gallio Test Resources\NUnit\Gallio.TestResources.NUnit.dll" "E:\Users\Ben Hall\Desktop\Gallio Test Resources\XUnit\Gallio.TestResources.Xunit.dll" /rd:"E:\Users\Ben Hall\Desktop\Gallio Test Resources\Reports" /rt:Html

When executing, failing tests are displayed in red.

image

At the end, you will be shown a summary to the test run.

image

Reports

Go go with this, Gallio has a new report design.  I really like these, think they look much better than previously.  The report gives you all the information about the test run, such as assemblies loaded, statistics and summary.

image

Then it goes into detail on each of the test run, highlighting failures.

image

This is really useful and provides a great way to keep track of each test run. The new report actually makes it really simply to see what is going on.  Notice, that in the above screenshot, we have the xml documentation for the method inline with the test report.  Very cool! :)

Nice work Jeff and team.  I haven't spoke about what's new within MbUnit v3.  Well its still very early days for the framework itself as Gallio was originally MbUnit v3 until decided to release it as a separate framework.  As such, the framework hasn't had some much attention, however from the release notes we have completed the following work:

- Dogfood.
- Initial draft of the attribute extensibility model.
- Supports [Test] and [TestFixture] attributes.
- Assertions ported from MbUnit v2 in the interim.

More information:

www.mbunit.com

Jeff's post - MbUnit v3 Alpha 1 Release

Andrew's post - MbUnit v3 and Gallio alpha 1

Download: http://mb-unit.googlecode.com/files/MbUnit%20v3%20Alpha%201%20Setup.exe

Release Notes: http://mb-unit.googlecode.com/files/MbUnit%20v3%20Alpha%201%20Release%20Notes.txt

Technorati Tags: ,

Labels: ,