Skip to content

An opinionated test application to help you practice Specification by Example

Notifications You must be signed in to change notification settings

chutney-testing/chutney

Repository files navigation

Chutney

Spice up your spec , Better taste your app !

Build Codacy Badge Coverage Status Maven Central REUSE Compliance Check


Summary


Introduction

Chutney aims to test deployed software in order to validate functional requirements.

Chutney scenarios are declarative written with a kotlin dsl. They provide functional requirements and technical details (needed for automation) in a single view.

Chutney is also released as a standalone application including a test execution engine and a a web front end to consult test reports.

Technical details are provided by generic Actions (such as HTTP, AMQP, MongoDB, Kafka, Selenium, etc.)
Those Actions are extensions, and you can easily develop yours, even proprietary or non-generic one, and include them in your own release.

In addition, Chutney provide SpEL evaluation and extensible Function in order to ease the use of managing scenario data like JSON path or Date comparison.

Find out more in the documentation !

Still asking yourself "Why another test tool ?"


Installation

Locally

In order to install Chutney on your machine, you can use Java or Docker. See Start a server.

On premise

See installation on premise, for details if you want to customize your own version of chutney server.


Scenario Example

You can find all the documentation of how to write a scenario here

Example of a scenario

Here is an example of a scenario written in Kotlin.

    const val HTTP_TARGET_NAME = "HTTP_TARGET"

    const val FILMS_ENDPOINT = "/films"
    private val JSON_CONTENT_TYPE = "Content-Type" to "application/json";

    var FILM = """
    {
        "title": "Castle in the Sky",
        "director": "Hayao Miyazaki",
        "rating": "%rating%",
        "category": "fiction"
    }
    """

    val http_scenario = Scenario(title = "Films library") {
        Given("I save a new film") {
            HttpPostAction(
                target = HTTP_TARGET_NAME,
                uri = FILMS_ENDPOINT,
                body = FILM.trimIndent(),
                headers = mapOf(
                    JSON_CONTENT_TYPE
                ),
                validations = mapOf(
                    statusValidation(201)
                ),
                outputs = mapOf(
                    "filmId" to "#body".elEval()
                )
            )
        }
    
        When ("I update rating") {
            HttpPatchAction(
                target = HTTP_TARGET_NAME,
                uri = "$FILMS_ENDPOINT/\${#filmId}",
                body = """
                    {
                    "rating": "79",
                    }
                """.trimIndent(),
                headers = mapOf(
                    JSON_CONTENT_TYPE
                ),
                validations = mapOf(
                    statusValidation(200)
                )
            )
        }
    
        Then ("I check that rating was updated") {
            Step("I get film by id") {
                HttpGetAction(
                    target = HTTP_TARGET_NAME,
                    uri = "$FILMS_ENDPOINT/\${#filmId}",
                    headers = mapOf(
                        JSON_CONTENT_TYPE
                    ),
                    validations = mapOf(
                        statusValidation(200)
                    ),
                    outputs = mapOf(
                        "title" to "jsonPath(#body, '\$.title')".spEL(),
                        "rating" to "jsonPath(#body, '\$.rating')".spEL()
                    )
                )
            }
        Step ("I check rating"){
            AssertAction(
                asserts = listOf(
                    "title.equals('Castle in the Sky')".spEL(),
                    "rating.equals('79')".spEL()
                )
            )
        }
    }
  • In this example the scenario will save the content of FILM to an external server.
  • Then it will update it, fetch it and finally verify that the FILM has indeed been updated.
  • In this scenario we perform Http Actions, you can find all available Chutney Actions here
  • You can find some other example with jms, kafka, rabbit or sql here

Documentation

Get the official documentation for more information about how Chutney works.


Contributing ?

PRs Welcome

See the Getting started, which document how to install and setup the required environment for developing

You don't need to be a developer to contribute, nor do much, you can simply:

To help you start, we invite you to read Contributing, which gives you rules and code conventions to respect

To contribute to this documentation (README, CONTRIBUTING, etc.), we conform to the CommonMark Spec

Support

We’re using Discussions as a place to connect with members of our - slow pace growing - community. We hope that you:

  • Ask questions you’re wondering about,
  • Share ideas,
  • Engage with other community members,
  • Welcome others, be friendly and open-minded !

Contributors

Core contributors :

We strive to provide a benevolent environment and support any contribution.