Is MSpec an Internal DSL?...And is that okay?
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# | DependencyInjection 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 | T-SQL/P-SQL | 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