Skip to content

fridujo/glacio

Repository files navigation

Glacio

Codacy Badge Build Status codecov Maven Central License

Multi-level Gherkin-like language.

What it is

Using Cucumber, you would write something like the following and let developers translate it however they want:

Feature: User login

    Scenario: Successful login

        Given a user on the login page
        When the user signs in with valid credentials
        Then the user is logged in

Except several concepts in this spec are subject to interpretation.

  • what browser is the user using to get to the login page? (firefox, chrome, etc.)
  • are we even executing this test on a fully deployed application or in the context of an integration test? (selenium, mocked application, etc.)
  • what does having valid credentials mean? (inserted into the database on the fly, created through the registration process, using an already existing account, etc.)
  • is real-user sign in required or is an HTTP post on the back API sufficient? (this leads also to test strategy, whether all tests should use a tool like selenium, or API calls are sufficient for most of them)
  • how do we know that the user is logged in? (check the url is /home, check the title of the page, check the presence of a cookie, etc.)

Using Glacio, you have room to answer these uncertainties together with all actors:

Feature: User login

    Scenario: Successful login

        Given a user with valid credentials
            Insert generated user with valid credentials in database
                Generate variable 'username'
                Generate variable 'password'
                Execute SQL
                """
                  INSERT INTO USERS(USERNAME, PASSWORD, ENABLED)
                    VALUES('${username}', '${password}', 1)
                """
        And the user in on the login page
            Open a 'Chrome' browser
            Navigate to 'https://www.yourapp.com'
            Click on the 'Sign In' button
        When the user signs in
            Fill 'username' input with '${username}'
            Fill 'password' input with '${password}'
            Click on the 'Sign In' button
        Then the user is logged in
            Relative URL is '/home'

In the end, like with Cucumber, developers will have to code some glue to make leaf-steps runnable.
You can choose how many levels of explanation you have for each step.
Go deep enough though and the code base will only contain generic little Lego pieces you can re-use to create new tests that are instantly runnable.

Where it starts

There is a common problem encountered using BDD tools like Cucumber.
This is:

  • non-technical actors write specs
  • developers write glue code containing hidden business specificities

That is an historic clivage which tends to leave grey areas undiscovered until implementation time.
Furthermore, non-technical actors can point out relevant aspects of implementation just as developers can do the same about the business part (aka specs).

As Seb Rose stated in this article, levels of readability can differ from the ones encountered in usual test segregation (unit, integration, acceptance, etc.).

Motivation

This project is intended to solve this issue by supplying a shared medium for all actors to contribute together.

The language is inspired by Gherkin as it has many qualities (expressiveness, i18n, support of many programming languages).
Substeps framework is also a source of inspiration, but the goal is to keep the Glacio language expressive by avoiding the need to switch between files to have the complete picture.

Vocabulary

You may want to gather your domain vocabulary in one place, to avoid duplication and ambiguous definition (same step labels in different scenarios but with different meanings).

For this specific use case, like with Substeps, you can write definitions in .vocabulary files.

user_login.feature

Feature: User login

    Scenario Outline: Successful login

        Given a user with valid credentials
        And the user is on the login page with a <browser_type> browser
        When the user signs in
        Then the user is logged in

        Examples:
          | browser_type |
          | Firefox      |
          | Chrome       |

application.vocabulary

Insert generated user with valid credentials in database
    * Generate variable 'username'
    * Generate variable 'password'
    * Execute SQL
      ```sql
      INSERT INTO USERS(USERNAME, PASSWORD, ENABLED)
        VALUES('${username}', '${password}', 1)
      ```

a user with valid credentials
    * Insert generated user with valid credentials in database

the user is on the login page with a <browser_type> browser
    * Open a '<browser_type>' browser
    * Navigate to 'https://www.yourapp.com'
    * Click on the 'Sign In' button

the user signs in
    * Fill 'username' input with '${username}'
    * Fill 'password' input with '${password}'
    * Click on the 'Sign In' button

the user is logged in
    * Relative URL is '/home'

Getting Started

Maven

Add the following dependency to your pom.xml

<dependency>
    <groupId>com.github.fridujo</groupId>
    <artifactId>glacio-junit-engine</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <scope>test</scope>
</dependency>

Gradle

Add the following dependency to your build.gradle

repositories {
	mavenCentral()
}

// ...

dependencies {
	// ...
	testCompile('com.github.fridujo:glacio-junit-engine:1.0.0-SNAPSHOT')
	// ...
}

Building from Source

You need JDK-8 to build Glacio. The project can be built with Maven using the following command.

mvn clean package

Tests are split in:

  • unit tests covering features and borderline cases: mvn test
  • mutation tests, to help understand what is missing in test assertions: mvn org.pitest:pitest-maven:mutationCoverage

Installing in the Local Maven Repository

The project can be installed in a local Maven Repository for usage in other projects via the following command.

mvn clean install

Using the latest SNAPSHOT

The master of the project pushes SNAPSHOTs in Sonatype's repo.

To use the latest master build add Sonatype OSS snapshot repository, for Maven:

<repositories>
    ...
    <repository>
        <id>sonatype-oss-spanshots</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </repository>
</repositories>

For Gradle:

repositories {
    // ...
    maven {
        url "https://oss.sonatype.org/content/repositories/snapshots"
    }
}