Giter Club home page Giter Club logo

aloe's Introduction

CD Build codecov stability-beta

Aloe

Scenario description and test runner for Herbs

Installing

$ npm install @herbsjs/aloe

Using

const { spec, scenario, given, check, samples } = require('@herbsjs/aloe')

const taskCountSpec = spec({
    'Change count for the task': scenario({
        'Given a valid task': given({ task: 'do it', count: 0 }),
        'When increase count': when((ctx) => (ctx.count++)),
        'Must have a increased count': check((ctx) => { assert.ok(ctx.count === 1) }),
    }),
})

How to use

Basic Spec

A spec represents the primary structure where the scenarios will be placed. It can have one or several scenarios:

const updateUserSpec = spec({
    'Update valid User': scenario({ ... }),
    'Do not update invalid User': scenario({ ... }),
})

A scenario represents a context with input (given), action (when) and the output validation (check).

const taskCountSpec = spec({
    'Change count for the task': scenario({
        'Given a valid task': given({ task: 'do it', count: 0 }),
        'When increase count': when((ctx) => (ctx.count++)),
        'Must have a increased count': check((ctx) => { assert.ok(ctx.count === 1) }),
    }),
})

It is possible to have many given and check on the same scenario.

const billingSpec = spec({
    'Calculate a valid bill': scenario({
        'Given valid items': given({ ... }),
        'Given a discount': given(async () => { ... }),
        'When calculate the bill': when((ctx) => ...),
        'Must have a valid bill': check((ctx) => ...),
        'Must have a discount': check((ctx) => ...),
    }),
})

It's also possible to run only a specific scenario.

const taskCountSpec = spec({
    'Change count for the task': scenario.only({
        'Given a valid task': given({ task: 'do it', count: 0 }),
        'When increase count': when((ctx) => (ctx.count++)),
        'Must have a increased count': check((ctx) => { assert.ok(ctx.count === 1) }),
    }),
})

Use Case Spec

When informed a use case the spec will assume all the scenarios are about this use case.

This will change the behavior of each scenario since it will not necessary to declare a when.

In order to run, the scenario expects a given returning a object with request, user (for use case authentication) and injection.

The result of the use case execution is stored in ctx.response.

const updateUser = require('./updateUser')

const updateUserSpec = spec({

    usecase: updateUser, 
    
    'Update a existing user when it is valid': scenario({
        'Given a valid user': given({
            request: { id: 1 },
            user: { can: true },
            injection: { userRepo: ... },
        }),
        // when: default for use case
        'Must run without errors': check((ctx) => { assert.ok(ctx.response.isOk) }),
        'Must confirm update': check((ctx) => { assert.ok(ctx.response.ok === true) })
    }),
})

Samples

If instead of validating the scenario with just one input you want to validate the set of inputs it is possible to use samples.

const updateProjectSpec = spec({

    usecase: updateProject,
    
    'Update a existing project': scenario({
        'Projects with due dates': samples([
            { duedate: ... },               // item 1
            { duedate: ... },               // item 2
        ]),
        'Projects with tasks': samples([
            { tasks: [] },                  // item 1
            { tasks: [{ task: ... }] },     // item 2
        ]),
        'Given a valid project': given((ctx) => ({
            request: ctx.sample,  // each item in `samples()`
            ...
        })),
        'Given a repository with a existing project': given((ctx) => ... ),
        'Must run without errors': check((ctx) => ... ),
        'Must confirm update': check((ctx) => ... )
    })
}),

In the above scenario 'Update a existing project' it will run four times, one for each item in each samples. The content of each run is available on ctx.sample.

Context

The context is created by samples or givens.

const updateUserSpec = spec({

    'Update a existing user': scenario({
        'Given a valid user': given({ name: 'Claudia' }),
        'Print user name': check((ctx) => { console.log(ctx.name) }),
        ...

Or

const updateUserSpec = spec({

    'Update a existing user': scenario({
        'Valid users': samples([
            { name: 'Claudia' },               // item 1
            { name: 'Claudio' },               // item 2
        ]),
        'Given a valid user': given((ctx) => ctx.sample),
        'Print user name': check((ctx) => { console.log(ctx.name) }),
        ...

Assertion

To validate a scenario it is necessary to go through checks with its assertions. If an assertion throws an exception, it is understood that that check failed.

It is possible to use any assertion library, including native node.js assertion.

const createUserSpec = spec({

    usecase: createUser, 
    
    'Create a new user': scenario({
        'Given a valid user': given(...),
        'Must run without errors': check((ctx) => { 
            assert.ok(ctx.response.isOk) 
        }),
        'Must return the created user': check((ctx) => { 
            assert.ok(ctx.response.ok === aGivenUser()) 
        })
    }),
})

Runner

The runner is responsible for executing the scenarios and showing the results.

const { runner } = require('@herbsjs/aloe/runner')

// running a set of pre-loaded specs
await runner({ specs })

// or

// load specs from herbarium
await runner({ herbarium })

// or

// load specs from the current directory (*.spec.js)
await runner() // specsPath can be especified

TODO

  • doc on web site
  • CLI: doc spec command
  • skip
  • only
  • todo / pending
  • nested scenarios
  • tests for runner
  • TAP protocol https://testanything.org/

Contribute

Come with us to make an awesome Aloe.

Now, if you do not have technical knowledge and also have intend to help us, do not feel shy, click here to open an issue and collaborate their ideas, the contribution may be a criticism or a compliment (why not?)

If you would like to help contribute to this repository, please see CONTRIBUTING

The Herb

The gel inside of the leaves of the Aloe plant can be used externally to treat minor burns, sun burn, cuts, scrapes and poison ivy. Aloe gel is good for moisturizing the skin and is a main ingredient of many skin care products.

https://www.herbslist.net/

https://en.wikipedia.org/wiki/Aloe_vera

License

Aloe is released under the MIT license.

aloe's People

Contributors

dalssoft avatar semantic-release-bot avatar jhomarolo avatar jhomarolo-vortx avatar italojs avatar

Watchers

 avatar  avatar

aloe's Issues

Documentation

The documentation does not explain how the test function should be exported, nor the herbs spec command that is used to run the tests, nor does it explain whether herbarium is necessary or not to use Aloe.

Aloe doesn't work when use case has no authorization method

Describe the bug

I'm testing a usecase with no authorization and got an error because ALOE doesn't validate if the usecase has authorization.

To Reproduce
Steps to reproduce the behavior:

  1. Create a usecase without authorization method
  2. Create a test scenario without authorization

Expected behavior

Not authorized error.

Screenshots

image

image

Additional context

I have created an issue to request a creation of hasAuthorization method to validade if usecase has authorization before run.

Aloe should have the skip feature

Is your feature request related to a problem? Please describe.
One of the most common actions when writing or debugging tests, regardless of the framework used, is being able to ignore some tests.
That is especially true if you practice TDD, or tend to first list the placeholders for the tests you plan to write.

Describe the solution you'd like
The skip() feature should have inside the aloe library as the similar in mocha https://danielkorn.io/post/skipping-tests-in-mochajs/

Aloe should have code coverage

Is your feature request related to a problem? Please describe.
Code coverage is a metric that can help you understand how much of your source is tested. It's a very useful metric that can help you assess the quality of your test suite.

Describe the solution you'd like
Aloe should have the code coverage feature.

Describe alternatives you've considered
Maybe an integration with Istanbul (https://github.com/istanbuljs/nyc) or similar should resolve the problem.

Run only one scenario on ALOE test runner

Is your feature request related to a problem? Please describe.

Is not possible to run only one scenario when the test is running.

Describe the solution you'd like

Implement the scenario.only function to run only one scenario.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context

Many test runners like mocha or jest have this function, which is very important to debug tests.

Doc improvements

Is your feature request related to a problem? Please describe.
The aloe documentation should be more extensive, complete and user friendly.

Today the existing documentation encompasses only a few scenarios and needs more detail, especially in real project uses.

Additional context
Benchmark: https://mochajs.org/#getting-started

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.