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
For BDD there is also Specter http://specter.sourceforge.net/ written in the fantastic Boo.