With the new features that are part of the DLR you can create plenty of cool stuff like Dynamic Method Bags, ExpandoObject, etc. More blogs, tutorials and articles will follow. And without doubt these new features have their place and will provide excellent value in those cases.
However, always keep this in mind: "To a kid who gets a hammer for Christmas, everything looks like a nail."
In economically challenging times you can prove your value even more by choosing carefully where, when and how you use new technology. Rumors has it that occasionally not using the newest features is the better choice ...
Friday, November 13, 2009
C# 4.0: MethodBag, ExpandoObject and other cool stuff
Sunday, November 08, 2009
IE8 and Selenium RC: Tests won't execute
Just noticed that running tests through Selenium RC in Internet Explorer 8 (IE8) displays a message containing an info to disable pop-up blocker. IE reports a script error and also says that it cannot load "...htmlutils.js".
The solution was simple: Run the Selenium RC server in admin mode. Launch the command line as administrator then start selenium RC using "java -jar selenium-server.jar". The scripts should then run. (Of course you would put all of this into a short, which in turn is set to run "As Administrator".
I observed this behavior on Windows Vista Ultimate 32 bit with IE8 and all of that updated to the latest patch level. The Selenium version was 1.0.1. The behavior might also present in other combination. The solution described above may or may not help on other tech stacks as well.
Saturday, November 07, 2009
ASP.NET Forms Based Authentication: Minimum Configuration
Where possible I try to implement functionality with the minimum code I can get away with. Yes, that means that I leave out all 'flexibilities' that are not needed right away even those that others would see as we will need them anyway tomorrow. Sometimes tomorrow never comes. Anyways.
ASP.NET offers several options for authentication. For one application I chose forms based authentication. The minimum working configuration that I found looks as follows:
<authentication mode="Forms">
</authentication>
<authorization>
<deny users="?"/>
</authorization>
Place this in your web.config file inside the system.web element.
Of course it is likely that for production scenarios you will use something more sophisticated. However, for development purposes sometimes all you want is the minimum to get you started. And that's all the above is about.
Sunday, November 01, 2009
ASP.NET, Master Pages and Selenium RC
Testing master pages in ASP.NET using Selenium can be tricky at the beginning since ASP.NET mangles the identifiers of controls on your pages.
For example: You might have a form with an input text box. You give that text box the id 'myTextBox'. Then your Selenium RC test might look as follows:
[Test]
public void MyTextBox() {
_selenium.Open("http://localhost:49583/");
_selenium.Type("myTextBox", "some content");
// ... rest of the test
}
The problem with this is that the test will fail if if you have given your textbox the correct id. The reason for that is that ASP.NET mangles the identifier to something like "ctl00_..._myTextBox". You can't be sure how it is mangled next time when you compile the page or next time ASP.NET is update.
The better approach is one that works regardless how the id is mangled so long as the original id is still included. So here we go:
[Test]
public void MyTextBox() {
_selenium.Open("http://localhost:49583/");
_selenium.Type("//input[contains(@name, 'myTextBox')]", "some content");
// ... rest of the test
}
Now of course you may need to locate an element more often so it makes sense to write a little method for this. With that method the test then becomes:
using csUnit;
using Selenium;
namespace MyWebSite.Web.Tests {
[TestFixture]
public class WebSiteTests {
private string XPathForInput(string identifier) {
return string.Format("//input[contains(@name, '{0}')]", identifier);
}
[Test]
public void MyTextBox() {
_selenium.Open("http://localhost:49583/");
_selenium.Type(XPathForInput("myTextBox"), "some content");
// ... rest of the test
}
// ... rest of the fixture
private ISelenium _selenium;
}
}
Although I found a few examples on the internet I thought that provide some concrete code might help you to get up to speed faster.
Saturday, October 31, 2009
WiX vs InstallShield
Until recently we used InstallShield for all our software packaging needs. It was never a love relationship as the product is complicated to use and we don't need the vast majority of its features anyways despite the fact we are deploying large enterprise systems consisting of multiple installers.
Not long ago we ran into problems with InstallShield and tried to get to support. Understandably support is not available for free, so I sent an email to their sales department ("sales@...") "threatening" to even spend money on purchasing a support contract. I never received a reply.
Since the issues we observed with the product didn't disappear and the information available on the internet, e.g. forums, didn't help either we look for alternatives. The packaging had been a long standing concern.
So we looked again at WiX (Windows Installer Toolkit). It took one of my engineers not more than one month to rewrite all installers using WiX, and our next monthly release in November will be shipped entirely on WiX.
Is WiX perfect? No, not at all. But we now have a tool that is much simpler to use and it fits very nicely with our other Visual Studio based tools. In addition: WiX is open-source and we don't have a licensing issue which is kind of nice as now not only all team members can use it at the same time but we can also always run our automated processes without even thinking about licensing issues.
So overall I'm glad we took a fresh look at WiX and that we phased out InstallShield. Given the available service levels, the associated cost, and in particular the fact I never heard back from their sales department although I was willing to spend money, WiX is the better choice for us overall.
And maybe it's also the better choice for your project?
Friday, October 30, 2009
Web user interface testing? Selenium!
Working on a web based user interface? New or existing? Need automated testing? No problem: Use Selenium. Yes, it's Java-based but that's no reason for not using it. It also works for web development based on .NET.
Selenium is nothing new for most .NET base developers. Still it might be worthwhile to have a brief look at how to integrate it with your solution. So here are the basic steps to make it work.
First, of course, you need to download Selenium from here. The version that you most likely want to use is Selenium RC. Once downloaded, installation is very simple:
- Create a folder for Selenium. I typically use c:\bin\selenium (I hate typing double quotes and stuff for command lines if folder names contain spaces)
- From the archive extract 'Selenium-Server-...' and 'Selenium-dotnet-client-driver-...' into the folder you create in step 1.
- Open a command prompt in the 'Selenium-Server-...' folder.
- Execute the command 'java -jar selenium-server.jar'
Next you'll need to write some tests using your favorite unit testing tool, e.g. csUnit. You'll need to add Selenium's client driver assemblies to your test project. The one you'll need is called 'ThoughtWorks.Selenium.Core.dll' which you can find in the 'Selenium-dotnet-client-driver-...' folder you created earlier.
Once adding the required reference writing the test is pretty simple. You can find some examples to start with here.
Friday, September 04, 2009
Path used in Assembly.LoadFrom()
One way of loading an assembly into an AppDomain is using the static method Assembly.LoadFrom(). An interesting aspect here is: Which folder is used when you supply a relative path?
You might be seduced to believing that it will use AppDomain.CurrentDomain.BaseDirectory and combine that with the relative path. That's, however, not correct.
Instead it is using Environment.CurrentDirectory, which can be an entirely different directory than the AppDomain's base directory! The online documentation states that it is using "the current directory" but this might still be misleading as it doesn't necessarily make the reader aware that this is different from AppDomain.CurrentDomain.BaseDirectory.
Therefore, if you want to be on the safe side construct an absolute path, e.g. by using Path.Combine() etc. Also consider that the location from where you (down)load might actually be an URL.