Glimmer DSL for Specification - Specification-First Engineering

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.

As such, software engineers focus on Requirements Specification at the 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:

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:

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.

# 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.

19