Is MSpec an Internal DSL?…And is that okay?

March 3rd, 2010
In my last post on MSpec, John Sonmez commented:
When I see the MSpec code, I think about it being an internal DSL for doing the testing, and I start to think that perhaps it should just go ahead and be it’s own language instead of trying to live inside of C#. On the other hand, I wonder about the value of using another language to unit test C# code…
I think John was spot-on with his instinct – in my opinion, MSpec is an internal DSL.  I also think that is the beauty of the framework.  Domain-specific languages are meant to solve a target problem in a particular domain.  MSpec’s problem domain is testing .NET code.  By convention, it constrains you to its limited language to help you test your code in a meaningful yet powerful manner.

What is an Internal DSL?

According to Martin Fowler:
“Internal DSLs are particular ways of using a host language to give the host language the feel of a particular language...Internal DSLs are also referred to as embedded DSLs or FluentInterfaces”  (from Bliki article: Domain Specific Language) “Internal DSLs use the same general purpose programming language that the wider application uses, but uses that language in a particular and limited style.” (from DSL-WIP section: Using Domain Specific Languages)
But, as John wondered, is there value in using another language (external DSL) to test C# code? Perhaps.  Yet, I believe there is more value in using external DSLs to test user interfaces (e.g., WatiR, WatiN, and Selenium), or for build scripting (e.g.,Rake, psake). Let’s look at that question a little differently: Is there value in using an internal DSL (like MSpec) to test C# code? To that I give a resounding YES! MSpec’s host language is C#…which provides great value to me.  I get all the benefits of intellisense, refactoring, and (R#) navigation in my IDE.  I don’t have to worry about the impedance mismatch between my code and an external DSL.

You Probably Use DSLs All the Time

In fact, I use several DSLs every day when I code. Consider the following table of frameworks. You may not have thought any of these in the context of a domain-specific language, but each has a specific purpose with its own limited language constructs. Some are internal, some external.
DSL Type Host Language Problem Domain
StructureMap Internal C# Dependency injection Inversion of control
AutoMapper Internal C# Object-to-object mapping
RhinoMocks Internal C# Proxy object interaction and verification
Moq Internal C# Proxy object interaction and verification
jQuery Internal JavaScript Document traversal Event handling Animation
Cascading Style Sheets External English Presentation semantics
Rake External Ruby Build/task automation
psake External PowerShell Build/task automation
nAnt External XML Build/task automation
SQL External English Data management
Cucumber External Gherkin Behavior-driven development
When considering a framework within your host language: If the framework has a fluent interface with language devoted to a specific problem domain, it is probably an internal DSL. So is MSpec an internal DSL? Yes. And is that okay? Definitely.

Further Reading

Check out Martin Fowler’s articles on domain-specific languages: http://www.martinfowler.com/bliki/DomainSpecificLanguage.html http://martinfowler.com/dslwip/UsingDsls.html http://martinfowler.com/dslwip/InternalOverview.html