views:

920

answers:

8

I need to build a scripting interface for my C# program that does system level testing of embedded firmware.

My application contains libraries to fully interact with the devices. There are separate libraries for initiating actions, getting output and tracking success/failure. My application also has a GUI for managing multiple devices and assigning many scripts to be run.

For the testers (non-programmers, but technical), I need to provide a scripting interface that will allow them to come up with different scenarios for testing and run them. They are just going to call my APIs and then return a result to my program (pass/fail and message).

A very basic example of what I want:

TURN_POWER_ON
TUNE_FREQUENCY frequency
WAIT 5
IF GET_FREQUENCY == frequency
  REPORT_PASS "Successfully tuned to " + frequency
ELSE
  REPORT_FAIL "Failed to tune to " + frequency
ENDIF
TURN_POWER_OFF

Where the reporting, power and frequency functions are provided by my C# libraries.

Will something like IronRuby or IronPython be good for this, or should I just build my own very basic language?

Does the Ruby/Python code get messy when trying to include a bunch of .NET compiled assemblies? I want it to be easy to learn and code for non-programmers and programmers alike.

EDIT:

Thanks for all the great responses. I chose IronPython as the answer since it had the most support, but I'll spend a bit of time with each of IronPython, Boo and IronRuby to see what the testers would prefer to write scripts in.

+15  A: 

I've heard very good things about IronPython for exactly this type of scenario. I'd certainly risk spending a few hours on a quick proof-of-concept, to see how it pans out.

Michael Foord will happily wax lyrical about the success of IronPython in similar cases (most specifically for him, for spreadsheet savvy users), and his book covers (IIRC) a few pointers about hosting it from .NET.

Marc Gravell
beat me to it :)
johnc
That's great :) Are there any good examples/tutorials out there for this kind of integration? I'd love to see what the end Python code for something like this looks like.
cgyDeveloper
I'm pretty sure IronPython In Action covers some (although being dead trees it may be out of date); you could look here: http://blogs.msdn.com/srivatsn/archive/2008/09/16/hosting-ironpython-made-easier.aspx
Marc Gravell
I have an example that shows how to use Python for scripting C# (or VB.NET) on my blog at http://www.gotnet.biz/Blog/post/Mixing-Static-and-Dynamic-dotNET-Languages-November-2008-Update.aspx
W. Kevin Hazzard
I'm curious - wouldn't Lua+C# combo be good for this too?
Arnis L.
+2  A: 

I agree with Marc G, though it's worth mentioning that the general concept is a Domain Specific Langugage. While IronRuby/IronPython aren't strictly domain-specific, they are full-featured and it would leave you to get on with your implementation.

Visual Studio has the DSL tools, and there's the 'M' Grammar stuff you can look into.

But yeah, IronPython.

Neil Barnwell
I learn a new acronym everyday... DSL is now in my vocabulary (twice). Thanks, you've helped my google searches a ton just with that :)
cgyDeveloper
+10  A: 

You may want to look at Boo, another managed language that runs on the CLR, and which is particularly well suited to build DSL and make your applications scriptable.

The compilation pipeline is directly extensible from the language itself.

Reading the Boo Manifesto is a good starting point if you want to learn more about it.

[Edit] I forgot to mention that Ayende Rahien is writing a complete book on the topic: Building Domain Specific Languages in Boo

Romain Verdier
+1 Oh now that looks cool....
RCIX
Very interesting... looks like I'll be playing with Boo and IronPython tomorrow.
cgyDeveloper
+4  A: 

It might be worth considering PowerShell for this sort of task. That can call into .Net just as any of the DLR languages, and has a more natural language type chunking for tasks in its cmdlet (command-let) concept. You have to write the cmdlets in a compiled language at v1 -- in v2 which is being rolled out starting with Win7 and working to older releases in the next few months (v2 for Vista/Win2k8 is at RC now), you can build those in PowerShell directly.

Steve Gilham
+2  A: 

From the DSL you're going for, I'd recommend to use CUCUMBER with IronRuby.

With Cucumber, testers write tests that look something like that:

Scenario: See all vendors
Given I am logged in as a user in the administrator role
And There are 3 vendors
When I go to the manage vendors page
Then I should see the first 3 vendor names

It is very easy to make this language fit your needs. Just google "Cucumber and IronRuby" and you'll find several guides and blog posts to get you started.

Shay Friedman
+1  A: 

We are using embedded Iron Python for pricing formula in one of our project. This is how a real sample on how it looks like.

E_DOCUMENT_CHECK = DCPAV * ADS_NUM
E_SPECIFIC_TAX = STV
E_RESOURCE_DEV = RDV
E_LP_ISSUANCE = LPIV
E_ANNUAL_FEES = APFCV * SA * SIDES_NUM
E_SERVICE_FEES= MAX(
MINSFV,
E_DOCUMENT_CHECK+E_SPECIFIC_TAX+E_RESOURCE_DEV+E_LP_ISSUANCE+E_ANNUAL_FEES)
TOTAL= E_DOCUMENT_CHECK+E_SPECIFIC_TAX+E_RESOURCE_DEV+E_LP_ISSUANCE+E_ANNUAL_FEES+E_SERVICE_FEES

It is really straightforward to implement. The Max() function for example is just one of the custom C# method that we import to the IronPython engine and it looks natural to use in a configuration settings.

DodyG
This looks really great. How were you able to make the MAX() function look so native to the script? My problem now is that I don't want .NET style classes all over the place. Every example looks like SomeClass.Max() and I just want basic scripting like you have...
cgyDeveloper
If you happen to see this comment, perhaps you could contribute an answer to my new/related question at http://stackoverflow.com/questions/1348188/simplfying-dsl-written-for-a-c-app-with-ironpython
cgyDeveloper
A: 

You could just use C# itself as the scripting language as described here CrowsProgramming - Runtime Scripting in .Net

Chris
I've done this in the past, and it's really not what I'm looking for.There's no way to have a script that looks like my example using C# as you need to declare at least one class and one member function using C# style syntax.
cgyDeveloper
A: 

IronRuby is the most powerful for creating domain-specific languages, because it's syntax is much more flexible and forgiving than python's (your users are going to screw the whitespace up and get annoyed by the mandatory () to call methods).

You could write your sample script in IronRuby and it would look like this:

TURN_POWER_ON
TUNE_FREQUENCY frequency
WAIT 5
if GET_FREQUENCY == frequency
  REPORT_PASS "Successfully tuned to " + frequency
else
  REPORT_FAIL "Failed to tune to " + frequency
end
TURN_POWER_OFF

Here's a sample of a DSL our Testers are currently using to write automated tests against our UI

window = find_window_on_desktop "OurApplication"
logon_button = window.find "Logon"
logon_button.click

list = window.find "ItemList"
list.should have(0).rows

add_button = window.find "Add new item"
add_button.click
list.should have(1).rows

However, as things stand right now IronPython is much more mature and has much better performance than IronRuby, so you may prefer to use that.

I'd strongly recommend going with either IronPython or IronRuby over creating your own custom language... You'll save an unimaginable amount of effort (and bugs)

Orion Edwards
Thanks for the answer. I personally wanted to go with IronRuby (for the bracket free syntax), but IronPython's maturity won out in the end. Both are really great options, but I just ran into more issues with IronRuby during my initial testing phase.
cgyDeveloper