Glimmer DSL for Specification - Specification-First Engineering
Tags: ruby, testing, dsl
Published: 2021-11-23 03:00:24

Despite Ruby's highly expressive nature, most testing toolkits written in Ruby are either imperative (e.g. using `assert` or `expect`), thus losing expressiveness and focusing software engineers on the wrong thing, or mix non-Ruby code with Ruby (e.g. cucumber & gherkin), thus missing out on the simplicity of Ruby.

[Glimmer DSL for Specification](https://github.com/AndyObtiva/glimmer-dsl-specification) aims to provide a simple minimalistic and noun-based declarative syntax. No more verbs! It is time to think declaratively not imperatively!

As such, software engineers focus on [Requirements Specification](https://en.wikipedia.org/wiki/Software_requirements_specification) at the [Use Case](https://en.wikipedia.org/wiki/Use_case) level whereby each use case is composed of multiple scenarios. No need to specify scenario steps. The code is the steps!!!

Also, no need for extra DSL constructs for making comparisons in verification statements. Just use plain old Ruby and let the library figure out the rest!

For example:

```ruby
scenario 'Same-content strings are equal' do
  'string' == 'string'
end
```

That tells me the whole story without needing either `assert` or `expect`. It just contains plain Ruby code for performing the comparison.

Another example:

```ruby
scenario 'person name consists of first name and last name' do
  person = Person.new(first_name: 'Bob', last_name: 'Winfrey')
  
  fact { person.first_name == 'Bob' }
  fact { person.last_name == 'Winfrey' }
  person.name == 'Bob Winfrey'
end
```

That states a few extra facts in addition to the last statement in the scenario denoting the final verification. Software engineers will not have to write awkward verification code they hate anymore (e.g. assert or expect) as even software verification code is written with basic Ruby.

Upon failure of a fact with a String equality/inequality comparison, the library will automatically print the values of the two compared String objects.

[Glimmer DSL for Specification](https://github.com/AndyObtiva/glimmer-dsl-specification) emphasizes the idea of Specification-First Engineering. The library was written specification-first utilizing itself. In fact, here is the initial specification of [glimmer-dsl-specification](https://rubygems.org/gems/glimmer-dsl-specification) to prove it!

```ruby
# From: https://github.com/AndyObtiva/glimmer-dsl-specification

require 'glimmer-dsl-specification'

class Person
  attr_reader :first_name, :last_name
  
  def initialize(first_name: , last_name: )
    @first_name = first_name
    @last_name = last_name
  end
  
  def name
    "#{first_name} #{last_name}"
  end
end

module Glimmer::Specification
  specification('Glimmer DSL for Specification') {
    use_case('Compare Two Objects for Equality') {
      scenario 'Same-content strings are equal' do
        'string' == 'string'
      end
      
      scenario 'Different-content strings are not equal' do
        'string1' != 'string2'
      end
      
      scenario 'Same-number integers are equal' do
        1 == 1
      end
      
      scenario 'Different-number integers are not equal' do
        1 != 2
      end
    }
    
    use_case('Verify Multiple Facts') {
      scenario 'person name consists of first name and last name' do
        person = Person.new(first_name: 'Bob', last_name: 'Winfrey')
        
        fact { person.first_name == 'Bob' }
        fact { person.last_name == 'Winfrey' }
        person.name == 'Bob Winfrey'
      end
    }
  }
end
```

Note that the library is very new and experimental, so it might change course significantly. Also, despite the bold ambitious statements, there might be obvious blind spots that your feedback would help shine light upon to improve the library. As such, ideas and suggestions are greatly welcome.