Homepage | About Me | Testing ASP.net Book | Best Blog Posts | Personal Projects | Follow me on Twitter | GitHub | SlideShare | RSS
Blog.BenHall.me.uk

Disable System.Diagnostics.Debug.Assert dialogs

Thursday, May 29, 2008

While executing my integration tests today, I was greeted with the excellent Assertion.Failed dialog which is displayed when using System.Diagnostics.  This dialog caused a problem on the build server as it was waiting for someone to click Ignore - that someone never came!

image

If you haven't saw the Debug.Assert code before, it basically looks like this:

[Test]
public void DebugAssert()
{
    System.Diagnostics.Debug.Assert(false);
}

When the Assert fails, the dialog is displayed.

The solution, add an App.Config file to your test suite.  Within the XML will clear the trace listeners, now when assert is called nothing happens because nothing is listening for it and the code continues. While executing unit tests this is fine - we just don't want the dialog being displayed.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.diagnostics>
        <trace>
            <listeners>
                <clear/>
            </listeners>
        </trace>
        <assert assertuienabled="false" />
    </system.diagnostics>
</configuration>

If you was interested in the debug.assert messages, you could have hooked up a different listener to write out the message to the console or a file.  This is what TestDriven.NET does, if an assertion is hit it writes the message to the output window.

Technorati Tags: ,

Labels: ,

An ASP.NET setting has been detected that does not apply in the Integrated managed pipeline mode

After installing CruiseControl.Net, CCNet, I attempted to load the web dashboard and got the following error display.

image

It said: "An ASP.NET setting has been detected that does not apply in the Integrated managed pipeline mode"

How confusing!! A quick look on the IIS7 documentation, blogs, forums etc I ran the following command.

%SystemRoot%\system32\inetsrv\appcmd migrate config "Default Web Site/".

I then refreshed the webpage and everything worked perfectly!

image

Technorati Tags: , ,

Labels:

Installing Subversion (SVN) 1.4.6 Server on Windows Vista

Tuesday, May 27, 2008

In this post, I just want to cover how to quickly install Subversion 1.4.6 on Windows Vista. Subversion is a free source control system, easy to use and has a strong user base.

The first task is to download Subversion 1.4.6 from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91. On this page you should find svn-1.4.6-setup.exe - Windows installer with the basic win32 binaries. I found this to be the easiest way to install svn.

Next, we need to setup the directory to store our source control repository. This will contain everything, including configuration and the revision database. On my E: drive, I have a folder called Source Control, in here I want a folder called svn\repos.

E:\Source Control>mkdir svn
E:\Source Control>cd svn
E:\Source Control\svn>mkdir repos
E:\Source Control\svn>

Next, we need to create our actual SVN database. We use the svnadmin create command which will take care of everything for us.

E:\Source Control\svn>svnadmin create "E:\Source Control\svn\repos"

The directory layout of our repos folder looks like this:

17/05/2008  13:35    <DIR>          conf
17/05/2008  13:35    <DIR>          dav
17/05/2008  13:35    <DIR>          db
17/05/2008  13:35                 2 format
17/05/2008  13:35    <DIR>          hooks
17/05/2008  13:35    <DIR>          locks
17/05/2008  13:35               234 README.txt

The next task is to create and start the Subversion service. Windows Vista includes a command called SC which we can execute to create our service. Sadly the first time I can this I got the error 'SC' is not recognized as an internal or external command, operable program or batch file. Turns out the problem was because my command prompt wasn't running as administrator.

Starting my command prompt as administrator, I could then enter the following command to create my service.

sc create svn binpath= "C:\program files\Subversion\bin\svnserve.exe --service -r \"E:\Source Control\svn\repos\"" DisplayName= "Subversion Server" depend= Tcpip start= auto

Notice, as part of the argument to the binpath, I include the repository directory I created before. I can then use 'net start svn' to start the service. From now on, it will start automatically with Windows.

C:\Windows\system32>net start svn
The Subversion Server service is starting.
The Subversion Server service was started successfully.

You can now use the command line or TortoiseSVN to connect to the repository.

Technorati Tags: , ,

Labels:

Rhino Mocks 3.5 - Goodbye Record and Playback!

Monday, May 26, 2008

Recently, Ayende released Rhino Mocks 3.5 Beta which includes a new Arrange, Act and Assert syntax style. This is a new syntax for creating your stubs and mocks. To take a deeper look into this new syntax, I'm going to migrate an old example I created for my article Beginning to Mock with Rhino Mocks and MbUnit - Part 2 which is a good read if you are new to the world of mock objects. As a quick refresher, the test I created was ensuring that the PaymentProcessor correctly communicated with the PaymentProcessingObject (in the system, this actually talked to PayPal).

[Test]
public void TakePaymentViaPaymentProcessorUsingMockService()
{
    MockRepository mocks = new MockRepository();
    IPaymentProcessing mockProxy = mocks.CreateMock<IPaymentProcessing>();

    using (mocks.Record())
    {
        Expect.Call(mockProxy.TakePayment(1, 1, 10.0)).IgnoreArguments()
                             .Return(true);
    }

    using (mocks.Playback())
    {
        PaymentProcessor pp = new PaymentProcessor(mockProxy);
        bool result = pp.TakePayment(1, 1, 10.0);
        Assert.IsTrue(result);
    }
}

The code this tested was:

public interface IPaymentProcessing
{ bool TakePayment(int paymentId, int customerId, double amount); }

internal class PaymentProcessor
{
    internal IPaymentProcessing wsProxy;

    public PaymentProcessor(IPaymentProcessing proxy)
    {
        wsProxy = proxy;
    }

    public bool TakePayment(int paymentId, int customerId, double amount)
    {
        return wsProxy.TakePayment(paymentId, customerId, amount);
    }
}

This is a very generic example, but demonstrates Rhino Mocks using the Record (Setup the mock object) and Playback (Test and use) approach to creating mock objects. Now we have our classic test, let's look at the changes for 3.5

CreateMock is Obsolete

The first change is that CreateMock has been marked as obsolete. Instead, we should be using StrictMock, this makes a lot more sense as it better defines the type of mock being created.

IPaymentProcessing mockProxy = mocks.StrictMock<IPaymentProcessing>();

But this still uses the same Record\Playback model.

AAA Syntax - Arrange, Act, Assert

This is where Rhino Mocks 3.5 is really interesting - for me at least.  We can now express our mock object is a much cleaner fashion, taking advantage of .Net 3.5 extension methods and lambda questions. Below, is the same test as above but using the Mock object.

[Test]
public void GenerateMock_TakePaymentViaPaymentProcessorUsingMockService()
{
    IPaymentProcessing mockProxy = MockRepository.GenerateMock<IPaymentProcessing>();  #1

    mockProxy.Expect(x => x.TakePayment(1, 1, 10.0))                                                                #2
                    .Constraints(Is.Equal(1), Is.Equal(1), Is.Equal(10.0)) 
                    .Return(true);

    PaymentProcessor pp = new PaymentProcessor(mockProxy);
    bool result = pp.TakePayment(1, 1, 10.0);
    Assert.IsTrue(result);

    mockProxy.VerifyAllExpectations();                                                                                       #3
}

#1  Here we tell Rhino Mocks to create us a mock object of type IPaymentProcessing.
#2  Next we define our mock. Here, we are saying we expect TakePayment to be called, we then add some constraints about what the parameters passed in much be, finally defining that true be returned when this is called.
#3  Finally, we verify the exceptions we set in #2 where correct.

I find this new approach to be much easier to read, explain and write. The first time I tried this, I actually mistaken Constraints for Return and as such the following exception was thrown.

mockProxy.Expect(x => x.TakePayment(1, 1, 10.0)).Constraints(Is.Equal(true));  = failed: System.InvalidOperationException : The number of constraints is not the same as the number of the method's parameters!

Just be aware of these new constraints on the parameters. 

But, not only can we use this for creating mocks, but we can also create Stubs.

[Test]
public void GenerateStub_TakePaymentViaPaymentProcessorUsingMockService()
{
    IPaymentProcessing stubProxy = MockRepository.GenerateStub<IPaymentProcessing>();  #1
    stubProxy.Stub(action => action.TakePayment(1, 1, 10.0)).Return(true);                           #2

    PaymentProcessor pp = new PaymentProcessor(stubProxy);
    bool result = pp.TakePayment(1, 1, 10.0);
    Assert.IsTrue(result);
}

#1  Generate the stub
#2  Define the stub 

How cool is that!! Two lines of code to create our stub!

[Test]
public void GenerateStub_AssertWasCalled_TakePaymentViaPaymentProcessorUsingMockService()
{
    IPaymentProcessing stubProxy = MockRepository.GenerateStub<IPaymentProcessing>();
    stubProxy.Stub(action => action.TakePayment(1, 1, 10.0)).Return(true);

    PaymentProcessor pp = new PaymentProcessor(stubProxy);
    bool result = pp.TakePayment(1, 1, 10.0);
    Assert.IsTrue(result);

    stubProxy.AssertWasCalled(x => x.TakePayment(1, 1, 10.00));                                                  #1
}

#1  With stubs, we can also verify that the method was called. Notice this AssertWasCalled is an extension method Rhino Mocks has added to the interface.  gain, this is helping with the readability and demonstrates an excellent use of Extension Methods.

If AssertWasCalled failed, then the following exception would be thrown and the test would fail.

Expected that IPaymentProcessing.TakePayment(1, 1, 10); would be called, but is was it was not found on the actual calls made on the mocked object  

I think the new AAA syntax is really cool. I used it to explain mock objects for my NxtGenUG Coventry session and upgrading my mock objects was a simple task and made the tests much easier to read. Really looking forward to the final release.

Download Examples Used: http://blog.benhall.me.uk/Code/RhinoMocks/RhinoMocks35Beta.zip

More examples of new syntax: http://www.ayende.com/Blog/archive/2008/05/16/Rhino-Mocks--Arrange-Act-Assert-Syntax.aspx

Download: Rhino Mocks 3.5

Technorati Tags: , , ,

Labels: , ,

Microsoft Pex - 0.5 Released

Friday, May 23, 2008

I've been waiting for today for too long! Peli has announced that Pex 0.5 has been released and is available to download today! In this post, I am just going to have a very quick look at the release.  Expect a lot more posts around this framework, best subscribe now so you don't miss any.

Pex is a Microsoft research project which generates tests that cover all possible inputs. It does this by a mixture of static\dynamic analysis while taking advantage of the CLR Profiler to analyse your .Net code to find all the possible paths. Pex can then creates a series of test inputs for a test YOU wrote, you write the test which Pex then uses to find all the possible routes. You can use these tests in order to find all the different possible combinations for your application, find the areas where their are problems and have Pex suggest possible fixes.

Copied from site:

Pex comes with a Visual Studio Add-in which only works with Visual Studio 2008 Professional (or higher).
Pex also works from the
command line without any Visual Studio on the machine.

Downloads

v0.5.30516.0, 05/21/2008, download pex.30516.0.msi (x86), release notes

The Installer:

Very simple msi - just click next a few times..

image image

Taking a look at the samples

The team has spent a long term putting together some documentation and samples on how to use Pex which is great (especially for a research project). The samples are installed as part of the main framework and are in a zip file linked off the Microsoft Pex start menu item. Within the zip there is a VS2008 solution, with a project Samples.Pex which appears to contain samples for a lot of the functionality (without researching more I can't tell what).

Within the samples, the first test I picked at random is the LuhnAlgorithmTestClass. This was of interest because I had a similar test scenario for Red Gate SQL Data Generator as that has a Credit Card Number Generator for the Luhn Algorithm.

The test itself, based on MSTEST, looks very standard. At the class level, we add a PexClass attribute and give the type of class we are testing against. The MaxRuns defines how many runs will be tried during the exploration.

[TestClass]
[PexClass(typeof(LuhnAlgorithm), MaxRuns = 100)]
public partial class LuhnAlgorithmTestClass

The test itself, we add a PexMethod and most importantly a parameter for the input to use. Pex will then use this test to generate more exploratory tests and use the parameter to inject the value to test against. 

[PexMethod]
public void CharactersAreNotValid(string input)

   string number = input + 'a'; 
   bool result = LuhnAlgorithm.Validate(number); 
   Assert.IsFalse(result);
}

Pex includes a Visual Studio plugin, I can write click and go Pex It!

image

This should run all of my unit tests, but after executing Pex It! I got an error ClrMonitorFail (-667) - "Exit code returned when the ExtendedReflection profiler encountered a fatal error." within the Pex Results dialog. I've logged this with the team, if I get a solution I will post it online.

image

Luckily, Pex comes with a console application so the post isn't over! The command line is simple Pex with the assembly containing the Pex tests. The following command executes Pex for me:

D:\Users\Ben Hall\Desktop\samples\Pex\Pex\bin\Debug>pex Samples.Pex.dll 

After executing this, we get a lot of information wrote to the console application and a nice HTML report outputted.  The console information looks like this:

Microsoft Pex v0.5.30516.0 -- http://research.microsoft.com/pex
Copyright (c) Microsoft Corporation 2007-2008. All rights reserved.

instrumenting... launched Pex 0.5.30516.0 x86 Edition on .net v2.0.50727
[reports] report path: reports\Samples.Pex.80522.232227.pex
00:00:00.0> starting execution
  00:00:00.6> reflecting tests
  00:00:04.9> Samples.Pex
    00:00:05.0> LuhnAlgorithmTestClass
      00:00:06.5> CharactersAreNotValid(String)
        [test] (run 1) CharactersAreNotValidString_20080522_232253_000
        [test] (run 4) CharactersAreNotValidString_20080522_232256_001
        [test] (run 6) CharactersAreNotValidString_20080522_232256_002
        [execution] imprecision at Samples.Pex.Implementations.LuhnAlgorithm.Validate, offset 0x55
        [execution]     9 runs (88.89 % unique paths), 9/14 blocks covered
        [test] (run 10) CharactersAreNotValidString_20080522_232256_003
        [test] (run 27) CharactersAreNotValidString_20080522_232257_004
        [test] (run 28) CharactersAreNotValidString_20080522_232257_005
        [test] (run 41) CharactersAreNotValidString_20080522_232258_006
        [test] (run 45) CharactersAreNotValidString_20080522_232259_007
        [test] (run 87) CharactersAreNotValidString_20080522_232301_008
        <boundary> maxruns - 100
        <boundary> MaxRuns, 1 times
        [coverage] 11/14 block (78.57 %)
<snip>
00:07:43.6> [finished] 269 generated tests (51 failures), 00:07:43.6011870
    -- 0 critical errors, 0 errors, 4 warnings
[reports] generating reports...
[reports] html report: reports\samples.pex.80522.232227.pex\pex.html 
  EXPLORATION SUCCESS

This is showing that Pex is working against the LuhnAlgorithmTestClass.CharactersAreNotValid(string input) test (as shown above), and is generating multiple different tests based on that initial test.

With the report looking like this:

image

The report contains a lot of information about the execution. Clicking the name of the test class takes you to some more information about what was executed. 

image

Clicking the parameter values link will display all of the values used for the different tests.  Each parameter sends the code down a different route.

image

Another link which interested me is the Coverage link for the LuhnAlgorithmTestClass. Clicking on this, you get a really nice Code Coverage report page.

WindowClipping (7)

Putting this a different way, by writing a single test with a parameter, Pex can create us a series of different tests to execute all of the possible routes in the method. This is great! As a developer, I can focus on creating a test which can exercise the method, but don't have to worry about all of those edge cases as Pex will help find those.

Hello World Pex'ed

Hopefully you are still with me, now I just wanted to create a very quick Hello World application.  The class I have developed is this HelloWorld class, it has three different paths different different values for each.

public class HelloWorld
{
    public string GetHelloWorld(int ID)
    {
        if (ID == 1)
            return "Hi";

        if (ID == 2)
            return "Hello";

        if ((ID != 1) || (ID != 2) && (ID % 2 == 0))
            return "Hello World";

        return string.Empty;
    }
}

The related test is this HelloWorld(int id).  Pex will input the required parameters as a argument, and then execute the test. We want to ensure Hello World is returned.

[TestFixture]
[PexClass(typeof(HelloWorld))]
public class HelloWorldTests
{
    [PexMethod]
    public void HelloWorld(int id)
    {
        HelloWorld h = new HelloWorld();
        string helloWorld = h.GetHelloWorld(id);
        Assert.AreEqual("Hello World", helloWorld);
    }
}

On the HTML report, it displays three different parameters which caused it to go down different routes.  For 0, it worked as expected. For 1 and 2, the test failed.

image

To prove this, I wrote a classic test which worked successfully. 

[Test]
public void HelloWorld()
{
    HelloWorld h = new HelloWorld();
    string helloWorld = h.GetHelloWorld(0);
    Assert.AreEqual("Hello World", helloWorld);
}

What has Pex done for us? Well, it has identified one working parameter and two parameters which will cause the test to fail.

Summary

This is a huge framework and I have only just scratched a very small surface area. I haven't even touched the more advance parts (I will need to read the documentation for that).  I will be posting more, writing more and generally seeing what this framework is actually all about. Still not 100% convinced about this framework, I'm saving that until I see more.  Not being able to use it against a commercial application might limit my venture.

Technorati Tags: ,,,

Labels: , ,

Linq to SQL Stored procedure vs Functions

Wednesday, May 21, 2008

When it comes to Linq to SQL, there is a very interesting difference between using a stored procedure or a table function (or user defined functions).  In this post, I want to discuss the similarities and differences between the two and which one should be used in a given scenario.

Stored Procedures

Stored Procedures can be dragged and dropped on the right hand side of the designer.  This will then add the stored procedure as a method on your Data Context. If the stored procedure accepts parameters, then these will be translated into parameters on the method.

image

The method code for CustOrderHis stored procedure would be:

[Function(Name="dbo.CustOrderHist")]
public ISingleResult<CustOrderHistResult> CustOrderHist([Parameter(Name="CustomerID", DbType="NChar(5)")] string customerID)
{
    IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), customerID);
    return ((ISingleResult<CustOrderHistResult>)(result.ReturnValue));
}

You could then call it in your code:

DataClasses1DataContext dc = new DataClasses1DataContext();
var sproc = dc.CustOrderHist("ALFKI");

If we look at the code produced, the first important part is the FunctionAttribute which defines which stored procedure will be called in the database. The next important part is the GetCurrentMethod which allows Linq to access the method to execute. According to the documentation, the method "Returns a MethodBase object representing the currently executing method". This is then passed into the ExecuteMethodCall which will result in the query being executed against the database.

Once the result has been returned, it is converted into a ISingleResult, which implements IEnumerable, and returned to the calling client. As ISingleResult is a generic class, an object with the same name as the sproc is created with the same properties as returned by the stored procedure.

However, if you know your stored procedure returns a object already in your system, for example GetCustomer might return a row from your Customer table, then you can use that object as the generic type - ISingleResult<Customer>. This saves having unnecessary objects in your system.

When using stored procedures they can only return items of type ISingleResult or IMultipleResult (discussed later). This causes a number of problems when using the created objects.  Firstly, in your client code you will have to manually convert the result to something like ToList() if you want to bind the objects to a data source. If you convert the objects to a list then they will not be change-tracked. Finally, you cannot benefit from deferred loading when using stored procedures as the call to the database is executed when the method is called.

If your stored procedure returns two record sets, for example something like below

SELECT * FROM Customers

SELECT * FROM Orders

Then there will be a problem with a method returning ISingleResult. This is where IMultipleResult comes in handy. However just dragging the stored procedure like above will not generate the correct code. Instead, you will have to add your own partial method for the code.

Given this code, we will need to convert it so it can work correctly.

[Function(Name="dbo.ReturnCustomerAndOrder")]
public ISingleResult<ReturnCustomerAndOrderResult> ReturnCustomerAndOrder()
{
    IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
    return ((ISingleResult<ReturnCustomerAndOrderResult>)(result.ReturnValue));
}

The code for it to correctly access two or more different tables would look something like this:

        [Function(Name="dbo.ReturnCustomerAndOrder")]
        [ResultType(typeof(Customer))]
        [ResultType(typeof(Order))]
        public IMultipleResults ReturnCustomerAndOrder()
        {
            IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
            return ((IMultipleResults)(result.ReturnValue));
        }

NOTE: Important to include this in a partial class otherwise the designer will override your changes.

To access one of the set of results, you need to explicitly request it using the GetResult<> method.

DataClasses1DataContext dc = new DataClasses1DataContext();
IMultipleResults sproc = dc.ReturnCustomerAndOrder();
List<Order> orders = sproc.GetResult<Order>().ToList();

foreach (Order o in orders)
{
    Console.WriteLine(o.OrderID);
}

This allows you to deal with both situations for stored procedures. This is also what you will need to do if your sproc returns a single object but of different types.

User Defined Functions

Like stored procedures, user defined functions can be added as a method on your data context.  User defined functions are similar to stored procedures, however you have the ability to defined what is being returned from the function, this allows Linq to correctly understand the sql and produce correct code to match.

The function below returned as table, as such it is called a table valued function.

CREATE FUNCTION [dbo].[AllOrdersInWeek52Function]()
    RETURNS TABLE
AS
RETURN (SELECT * FROM Orders
        WHERE DATEPART(ww, OrderDate) = 52)

When this code is added to the data context, the following code is produced.

[Function(Name="dbo.AllOrdersInWeek52Function", IsComposable=true)]
public IQueryable<Order> AllOrdersInWeek52Function()
{
    return this.CreateMethodCallQuery<Order>(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
}

As you can see, this returns an IQueryable object, unlike the sproc which returned ISingleResult.  This means that you can take full advantage of Linq when querying against this object in the database.

Other advantages of functions is that they can be executed against the database, inline with an existing linq to sql query.  This means that we can do more advanced queries solely in the database without having to bring everything in memory to perform the same task. For example, if we can the function below which takes a date and returns an int representing the week of the year.

CREATE FUNCTION WeekOfYear(@Date DateTime)
RETURNS Int
AS
BEGIN
RETURN (CAST(DATEPART(ww, @Date) AS INT))
END

Then we can use that within our linq query.

DataClasses1DataContext dc = new DataClasses1DataContext();
var q = from o in dc.Orders
        where dc.WeekOfYear(o.OrderDate) == 23
        select o;

foreach (var item in q)
{
    Console.WriteLine(item.OrderID);
}

Now, instead of WeekOfYear being performed in memory over the entire table as would be required without the function then its included within the generatored SQL.

SELECT [t0].[OrderID], [t0].[CustomerID], [t0].[EmployeeID], [t0].[OrderDate], [t0].[RequiredDate], [t0].[ShippedDate], [t0].[ShipVia], [t0].[Freight], [t0].[ShipName], [t0].[ShipAddress], [t0].[ShipCity], [t0].[ShipRegion], [t0].[ShipPostalCode], [t0].[ShipCountry]
FROM [dbo].[Orders] AS [t0]
WHERE [dbo].[WeekOfYear]([t0].[OrderDate]) = @p0

I've highlighted the important section, as you can see this will result in a much better execution.

Summary

In summary, user defined functions provide you with more flexibility and allow you to gain some great advantages over the queries being executed. Very powerful and something to keep in mind.  Stored procedures have some limitations, but can solve certain scenarios.

Technorati Tags: ,

Labels:

GTA IV too dark?

I was really looking forward to getting my hands on GTA IV for my xBox 360.  However, the first time I played the game I couldn't see a thing! The game has great lighting effects and at night it goes dark (as you would expect), but this meant I could only see things lit by my headlights - when I crashed, I couldn't see a thing.  I soon stopped playing.

Next time I played, I missed around with some of the settings. I bumped the Brightness and Contrast on the Display settings (press start) and I could see everything. There is actually a car on the Display settings which I couldn't see before - the game is now enjoyable!!

Just had to share this incase anyone else was suffering the game problems...

Technorati Tags: , ,

Labels:

NxtGenUG Coventry - Red, Green, Refactor

Monday, May 19, 2008

imageTonight, I gave my Red, Green, Refactor session to NxtGenUG Coventry. It was great to return to my 'home' user group and give the presentation. The session was similar to the one I had presented at DDD Ireland and DDD Scotland with a few minor tweaks in places.

There where some great questions being asked afterwards and while waiting for the Pizza, there was a problem at the pizza place so I had to 'fill' for a while but then just moved on with slides. I would like to say thank you to everyone who attended. The attendance was really impressive (40 people?) and I hope everyone had a great time - I really enjoyed myself. I look forward to reading your feedback...

Below, please find my code and slides.

Code: BenHall_RedGreenRefactor_CompletedSolution.zip

Slides: BenHall_RedGreenRefactor_Slides.zip

If you have any more questions, then please email me. For now, this session will go onto the back burner, but if any user groups fancy a test driven development session then please give me a shout!

Technorati Tags:

Labels:

IronPython - Classes within separate files

Wednesday, May 14, 2008

Tonight I was asked an interesting question regarding IronPython (well, Python) and how it handles the loose files when executing.  With languages like C#, everything is compiled into an assembly and you have namespaces in order to locate the classes.  However, in Python it is a little bit different.

With python, files can be either compiled into an assembly, or left loose within a directory depending on what you want to do.  If you have your files loose, then you will need to reference the different files (modules\classes).  In the example below, I have a Customer class in a file called CustomerFile.py.  I then have a main method which creates the Customer and calls the method within a file called main.py.  The code for the files are here:

customerfile.py
class Customer(object):
  def PrintHello(self):
    print "Hello World!"

main.py
from customerfile import Customer
def main():
    print 'Hello World'
    c = Customer()
    print 'Created Customer'
    c.PrintHello()

if __name__ == "__main__":
   print 'Hello'
   main()

In order for the main file to know about the Customer File, we use the syntax - from <fileWithoutPYExt> import <Classs>.  Here we say from the customerfile, import the Customer class at the top of the class. If we execute the file, everything is wrote out as expected.

IronPython-2.0B2>ipy.exe main.py
Hello
Hello World
Created Customer
Hello World!

It's important that both files are located in a directory defined in the path search variable, by default it is the main directory and the Lib directory.

>>> import sys
>>> print sys.path
['.', '...IronPython-2.0B2', '...IronPython-2.0B2\\Lib']

If for example, CustomerFile.py was moved into a directory called Customer within the main folder, we would need to add that to the path variable in order for IronPython to look in the directory for the file. The code below does this, note that before we can import os, we need to add a reference to the location of the standard library.

import sys
sys.path.append("C:\python25\Lib")
import os
sys.path.append(os.path.abspath("Customer"))

Now, when we call the same code, IronPython will also search the Customer directory.  The path would now look something like this:

['.', 'IronPython-2.0B2', 'IronPython-2.0B2\\Lib', 'C:\\python25\\Lib', 'IronPython-2.0B2\\Customer']

Not overly difficult, but I can see new users becoming confused by this.

Technorati Tags: ,

Labels: ,

Developer Day Scotland - Post Conference

Sunday, May 11, 2008

image_thumb2This weekend I was up in Glasgow for Developer Day Scotland! I was their presenting my Red, Green, Refactor session which covers TDD and Test Doubles, very similar session to the one I did last weekend at DDD Ireland - this one just had a few tweaks...

As for the conference, I think Colin Mackay and team did a great job, everything seemed to happen seamlessly and everyone seemed to really enjoy themselves. Everyone who attendee were very excited and passionate about the event which really improved the atmosphere and made it a lot easier for everyone involved.

As for my session, I was very happy with it. I discussed everything I wanted, all the demo's worked, and finished on time. It could have been better, but overall I was very happy with the outcome.

Slides: BenHall_RedGreenRefactor_Slides.zip

Code: BenHall_RedGreenRefactor_Code.zip

At lunch, I did a grok talk on Red Gate's SQL Data Generator. Red Gate were one of the sponsors, but I just wanted to give a good honest demo of the product - not any marketing! Everyone I spoke to afterwards was really impressed with the application which is always good.

Next up, NxtGenUG Coventry where I will be presenting the same session, if you are in the area why not come along.

Technorati Tags: ,,

Labels: ,

Using SQLCmd to output results

Wednesday, May 07, 2008

SQL Management Studio is a great application, however there are times when SQL Server Management Studio (SSMS) is unavailable (either too slow to start, or simply not installed). However, there is a really useful application called sqlcmd which is installed with SQL Server. This is a command line application, located in C:\Program Files\Microsoft SQL Server\90\Tools\Binn (SQL Server 2005), you should find that this location has been set in your %PATH% environment variable meaning you can execute it from anywhere, which allows you to connect to a server, execute SQL commands and for the results to be outputted in the console window.

Below, I am connecting to my local SQL Express instance, and querying the Customers table in the Northwind database.  The results of the query, in this case the amount of rows in the table is displayed.

Z:\>sqlcmd -S .\SQLEXPRESS
1> USE Northwind
2> SELECT count(*) FROM Customers
3> GO
Changed database context to 'Northwind'.

-----------
       1000

(1 rows affected)
1>

It's really quick and it's great if you just want to execute a simple command and don't want to wait 5 minutes for SSMS to load. A word of guidance, to execute the query you need to execute the GO statement, this will then execute everything in the batch.

Technorati Tags:

Labels:

Introducing the ADO.NET Entity Framework

For those of you who subscribe to VSJ, UK software journal, this month in the May edition hopefully you read my Introduction ADO.net Entity Framework article. It is a huge framework and the aim of my article was to demystify some of the terms and how they all link together, I feel it archives this aim.

For those of you who don't subscribe, you can find the article online at http://www.vsj.co.uk/articles/display.asp?id=720.

Technorati Tags:

Labels:

DDD Ireland - Post Conference

Sunday, May 04, 2008

imageThis weekend was the DDD Ireland conference in Galway. I was there presenting my Red, Green, Refactor presentation which outlines the concepts of Test Driven Development (TDD) and demonstrates some of the techniques via code. I think the session went down well, but it's always difficult to tell.

The conference itself was great! Based on the same idea as DDD in Reading, some of the leading presenters in the UK (and Germany) community where on display discussing the latest Microsoft technology. We also had Barry, Dave and John from NxtGenUG doing swaggily fortunes, which was interesting.... Big thank you to everyone involved for organising the event, and for actually inviting me to speak :)

As promised, my slide deck and the completed solution for the application can be found here:

Slides - Ben Hall_Red_Green_Refactor.zip

Code - BenHall_RedGreenRefactor_CompletedSolution.zip

Technorati Tags: ,

Labels: ,

SQL Server Reporting Services - rsReportServerDisabled error

Thursday, May 01, 2008

A while ago I had to test a report created with SQL Server 2000 Reporting Services.  After installing Reporting Services and uploading the reports, went I attempted to access them I was shown the following error message.

Error rsReportServerDisabled : The report server cannot decrypt the symmetric key used to access sensitive or encrypted data in a report server database. You must either restore a backup key or delete all encrypted content and then restart the service

A little bit scary as I had no backup! After a bit of searching, I worked out I had to execute this command:

C:\Program Files\Microsoft SQL Server\80\Tools\Binn> rsactivate -r -c"C:\Program Files\Microsoft SQL Server\MSSQL\Reporting Services\ReportServer\RSReportServer.config"

After which, everything worked just fine.

Technorati Tags:

Labels: