# Friday, November 28, 2008

My friend Ray and I were talking about the growing mobile development market the other day, which got me looking into mobile development again, but this time for fully featured (and connected) phones.

For sure the biggest player at this point is the iPhone, which has even surpassed sales of the once popular and much cheaper Razor.  Now if I only had a Mac Book Pro and an iPhone...  At least 2grand to get started developing.  Then there's the fact that I would have to learn Objective-C along with Apple's proprietary runtime library. 

I did learn a little Objective-C last night "From C++ to Objective-C", which compares C++ and Objective-C syntax, and then installed the Objective-C  NeXTStep libraries and compiler for gcc. 

What a pain, the Objective-C syntax is so foreign to me, but there's a lot of features I do like about the language, especially compared to C++.  The shortened header declarations, single inheritance, interfaces (protocols), reflection, garbage collection, and message based calling.  There's definitely a lot of dynamic runtime flexibility here for something that is a superset of C.

On the other hand I've been looking at Android development... which looks to be so much easier, at least for me.  You can develop on Windows or Linux using Java and Eclipse.  Wait, I've already done this!  I've already created a J2ME app for my Razor and my Palm.  The barrier for entry, at least from my point of view is much lower.

Now, does that mean iPhone development is worse?  No, its probably more lucrative, especially at this point.  The one remaining question I have, is Android or iPhone development in demand in the Seattle market where I live?

Friday, November 28, 2008 5:04:25 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Sunday, November 23, 2008

I was going to do some quick coding this morning on a project.  Haha...  2 hours later I still haven't started to write any code.  Why?  Visual Studio 2008 updates which I needed to be able to open the solution and be productive.

  1. Installed the TFS client, which took a while.
  2. Installed VS 2008 SP1.
  3. I had to reinstall VS 2008 checking the "Unit Testing Tools" checkbox (see image).
  4. Upgraded ReSharper 4.0 to 4.1
  5. Installed the VS 2008 SP1 hotfix (KB958502) to add JScript intellisense support from "-vsdoc.js" files.

Number 3 was a bit strange.  I opened the solution only to find VS complaining about an unsupported project type.  I guess when I initially installed VS 2008 I figured I would never be using MSTest.  If only that were still true.

image

I installed KB958502 to get intellisense specifically for JQuery, since there is now a -vsdoc.js file available on the JQuery site.

You know, it seems like VS 2008 isn't all that far behind VS 2005 in regards to the number of installation steps/packages required to get a usable environment (at least for this project).

Sunday, November 23, 2008 7:58:20 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Tuesday, November 11, 2008

The other day I asked a coworker whether one our proprietary GUI based tools had a command line interface, to which he replied no.  I said that's cool, we don't really need one to run the tool headless from the command line anyway.  Command lines are antiquated.

Before the days of Windows command shells were the only way to run applications.  Command lines allow us to pipe input and output, batch programs, and otherwise automate repetitive tasks.  In *nix-land they are especially sharp tools.  However they are not without their own problems, foremost in my mind is argument processing.  Using a command line version of an application can be a pain, especially for any non-trivial app. 

If you look at any serious application that allows automation, they have their own automation framework.  Office allows you to write VBA, .NET, and also exposes a COM automation interface.  Maya has its own scripting language (Mel script, guess what Mel stand for) embedded in it along with the ability to run C++ plugins.  Now I bet you're thinking, yes big applications use automation frameworks and scripting languages, but I don't have that kind of time to invest in my little app.  Good, me neither.

In recent years Microsoft has provided less heavy handed approaches to consuming .NET assemblies. There are a couple different approaches that I can think of to use our .NET objects from the command line without writing a console application: Windows PowerShell and the DLR. 

PowerShell is more geared towads sysadmins, as such I like to use the DLR, more specifically IronPython.  Python is a very easy language to pickup, widespread (at least in the *nix world), and powerful.  I like to think of IronPython as C# without all the typing (OK, I stole that from Boo, but remember Boo syntax is based on Python).  Both have one important ability which we will need, the ability to use .NET assemblies and types from the command line (or script).

As an example I have a .NET library assembly that will run JSUnit tests, however I now need a way to run these unattended from the command line as part of a BVT.  Instead of writing a command line app for it I decide to write a quick little IronPython script which behaves very much like a console application.

import clr
import sys

clr.AddReferenceToFile("Sneal.JsUnitUtils.dll")
from Sneal.JsUnitUtils import *
from Sneal.JsUnitUtils.Browsers import *
from System.Collections.Generic import List
from System.IO import Path

# usage
if sys.argv.Count < 3:
	print "Usage: ipy IPJsUnit.py c:\source\mywebroot jsunittest1.html jsunittest2.html"
	sys.exit(False)

# command line params
webRootDirectory = sys.argv[1]

testFiles = List[str]()
for arg in sys.argv[2:]:
	testFiles.Add(Path.Combine(webRootDirectory, arg))

# create an execute test runner
mgr = JsUnitTestRunnerFactory()
runner = mgr.CreateRunner(testFiles, webRootDirectory, With.InternetExplorer)
success = runner.RunAllTests()

# print all results
if not success:
	print "Test run failed."
	for error in runner.Errors:
		print error.TestPage
		print error.FunctionName
		print error.Timing
		print error.Message
else:
	print "Yay!  All tests passed."

You'll notice that the application in fact takes two+ command line parameters, the webroot and the test files.  The advantage of this script over a console application from my point of view is:

  1. Less code to write.
  2. Documentation by example.
  3. Starting script for an end user to modify to their needs.

Number 3 I think is particularly important.  Within a minute or two an end user can modify this script to their needs and desires.  They could hardcode the arguments if they wanted, or pass additional arguments without the headache of launching Visual Studio and recompiling a console application.  Almost anyone with a text editor could modify this and quickly get on with their life.

Here instead of a well meaning (but over-complicated) console application, its been replaced with just enough glue to bootstrap us into business.  Gluing components together is what scripting languages are good at, so lets take them into consideration instead of always reaching for another console app.

Tuesday, November 11, 2008 2:20:47 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [4]  | 
# Sunday, November 02, 2008

Generating test data for your application is not an uncommon task, but there are definitely many different ways to seed your application.  Probably one of the most common ways is to use SQL scripts to directly import data into the database, although while fast this lacks the control and validation that your middle tier code provides.

Loading data directly using SQL works best when your business logic resides in stored procedures near the database, but in a modern application where business logic is generally found in the middle tier application layer written in C#, this doesn't work quite as well.  Loading data directly could potentially cause data corruption since its perfectly plausible your data may very well be invalid.  Besides of the possible side effects of invalid data you're likely skipping some of the automatic management of data your middle tier affords you.  In other words, loading data using your middle tier API is probably more robust and easer to script.

To script the middle tier API to load data we could create data using C# or some other static language, but unfortunately that requires a compile and is much more rigid than a malleable SQL script.  Making the C# "script" data driven does help, but it lacks the flexibility that a native scripting language provides.

With a scripting a language the only part to manage is the script itself which gets checked into source control (or even a My Documents folder).  The other nice benefit is that we can have a nice GUI tool (test suite manager?) that dynamically picks up user scripts from one or more predefined script folders making them a available to run at the click of a button.  No recompile, or reloading, just edit-save-and-go.

So, given that we have a C# middle tier layer that's perfectly capable of persisting data into a database, how do we go about writing a script against it?  There are a few ways, but one of the easiest ways is to use IronPython.  If you're not familiar with IronPython:

IronPython is a new implementation of the Python programming language running on .NET. It supports an interactive console with fully dynamic compilation. It is well integrated with the rest of the .NET Framework and makes all .NET libraries easily available to Python programmers, while maintaining full compatibility with the Python language.

That's exactly what we need!  Something light weight and easy to mange like SQL, but interacts with our middle tier.  We could even embed the interpreter in our GUI runner if we so desired which gives us the full power of a real scripting language and .NET from our own tools.

I created a small spike that tests out how IronPython could be used to load data directly through the middle tier API.  First of all I created a Customer domain object, an Address component, and a CustomerRepository in C#.  From here we directly write Python against this.  Here's what my little spike project looked like:

image

For my purposes I've created a Scripts folder to hold my Python scripts (in a real environment these would probably be located elsewhere).  As you might have inferred, the 10Customers.py script creates 10 customers in my customer repository.  I could potentially add other scripts in this folder, and even chain them together to do other more substantial things, but for now this will do.  Now for the interesting part, the python script which loads ten semi-random customers.

import sys
import clr

sys.path.append(r"E:\Source\spikes\IronPythonSpike\IronPythonSpike\bin\debug")
clr.AddReferenceToFile("IronPythonSpike.dll")
from IronPythonSpike import *
import System.Random as Rand

rand = Rand()
names = ["Joe", "Bob", "John", "Smith", "Hank", "Aaron", "Neal", "Pat", "Tim", "Jones", "Bill"]
streets = ["128th St. W", "Main St.", "1st Ave.", "A.B.D. Rd.", "Lonely Lane", "Pacific Ave.", "6th Ave.", "Foobar Ct."]
states = ["WA", "OR", "CA", "NY", "AK", "NV", "AL", "TX", "FL"]

repository = InMemoryCustomerRepository()
	
for i in xrange(10):
	c = Customer()
	c.Id = i;
	c.FirstName = names[rand.Next(names.Count)]
	c.LastName = names[rand.Next(names.Count)]
	c.Address = Address()
	c.Address.Id = i
	c.Address.HouseNumber = rand.Next(32767);
	c.Address.Street = streets[rand.Next(streets.Count)]
	c.Address.State = states[rand.Next(states.Count)]
	c.Address.PostalCode = rand.Next(10000, 99999).ToString()
	
	repository.SaveOrUpdate(c)

The first thing we do is import sys which we use to add the path to our C# DLL to the available path's for the interpreter to search for our DLL in. 

sys.path.append(r"E:\Source\spikes\IronPythonSpike\IronPythonSpike\bin\debug") 

From here we can use the clr object to add a reference to our C# middle tier assembly.  This assembly of course provides our domain objects.  From there its just a matter of randomly generating the customer and address attributes from a predefined list of possibilities: names, streets, states.

Certainly you could create a separate generator script which would provide for much more varied data, you could even pull these bits from another database or even a web service.  You could even write the script so that the data was not random but always the same.  For my purposes though, this works just fine.  A more realistic domain would have more validation rules and would probably require a more intelligent script.

To verify that everything was added to the repository I can just make a quick call at the end of the script

for c in repository.GetAll():
	print c.ToString()
	print ""

Which on this run prints out:

Tim Tim
959 Lonely Lane
AL, 96094

John Pat
19577 Pacific Ave.
FL, 62699

Pat John
2194 Lonely Lane
OR, 58176

Smith Neal
6430 Pacific Ave.
AL, 88910

Jones John
11059 Pacific Ave.
TX, 67800

Smith Smith
24162 6th Ave.
CA, 81493

Neal Hank
4054 Pacific Ave.
WA, 33392

Smith Jones
32012 Pacific Ave.
FL, 44461

Tim Hank
28812 Foobar Ct.
AL, 98069

Neal Joe
1751 Main St.
NV, 52048

Not bad for a few lines of script!

I think the important part to remember is that we're using the middle tier to load data complete with validation and any other business logic that normally executes on save, all the while keeping things flexible and lightweight.

Sunday, November 02, 2008 11:50:23 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  |