Coder Social home page Coder Social logo

elm-spec's Introduction

elm-spec

Build Status Npm Version Documentation

End-to-end testing for your Elm apps and components.

Features

  • Can test apps or separate components
  • Task based steps and assertions (allows createing custom ones easily)
  • Create composite steps from other steps
  • DOM steps and assertions (click, containsText, valueEquals, etc...)
  • Mock HTTP requests and report not mocked requests
  • before / after hooks
  • Run tests in the console (via jsdom)
  • Run tests with elm-reactor with console report
  • Run files one at a time elm-spec spec/SomeSpec.elm
  • Run tests one at a time elm-spec spec/SomeSpec.elm:2

CLI

You can install the CLI with either of the following commands:

npm install elm-spec -g or yarn global add elm-spec

elm-spec [glob pattern or file:testID] -f format

Options:
  --format, -f  Reporting format
                [choices: "documentation", "progress"] [default: "documentation"]
  --help        Show help                                               [boolean]

Adding the package

Add gdotdesign/elm-spec as a dependency to your elm-package.json.

  "dependencies": {
    "gdotdesign/elm-spec": "1.0.0 <= v < 2.0.0"
  }

And then install with elm-github-install using the elm-install command.

Quick Start

Here is an exmaple of testing a simple component:

import Spec exposing (..)

import Html.Events exposing (onClick)
import Html exposing (div, text)

type alias Model
  = String

type Msg
  = Set

init : () -> Model
init _ =
  "Empty"

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
  case msg of
    Set ->
      ( "Something", Cmd.none )

view : Model -> Html.Html Msg
view model =
  div [ onClick Set ] [ text model ]

specs : Node
specs =
  describe "Example"
    [ it "clicking on the div should change the text"
      [ assert.containsText { text = "Empty", selector = "div" }
      , steps.click "div"
      , assert.containsText { text = "Something", selector = "div" }
      ]
    ]

main =
  runWithProgram
    { subscriptions = \_ -> Sub.none
    , update = update
    , view = view
    , init = init
    } specs

And open the file in elm-reactor or run it wit the elm-spec command:

$ elm-spec spec/ExampleSpec.elm
◎ spec/ExampleSpec.elm
  Example
    ✔ clicking on the div should change the text
      Element div contains text "Empty"
      Clicked: div
      Element div contains text "Something"

1 files 1 tests:
 3 steps: 3 successfull, 0 failed, 0 errored
 0 requests: 0 called, 0 not called, 0 unhandled

Defining tests

You can define tests with the it or test functions:

it "does something"
  [ step1
  , assertion1
  , step2
  , assertion2
  ]

Each test can have an unlimited number of steps (Task Never Outcome) which are executed in sequence.

Before every test the given application is reset and a fresh DOM is created.

Defining Groups

You can define groups that can have an tests, hooks and groups. There are three functions that do the same thing: group, context, describe.

context "Something"
  [ describe "Something else"
    [ it "does something"
      [ step1
      , assertion1
      ]
    ]
  ]

Hooks

Elm-spec allows you to append and prepend steps and assertions before each test with the before and after functions.

These functions can be defined in a group and it will add it's steps to each test in that group and it's descendant groups tests (recursively).

context "Something"
  [ describe "Something else"
    [ before
      [ preparationStep1
      ]
    , after
      [ cleanupStep1
      ]
    , it "does something"
      [ step1
      , assertion1
      ]
    ]
  ]

Steps and Assertions

The following steps are available in the steps record:

{ dispatchEvent : String -> Json.Value -> String -> Step
, getAttribute : String -> String -> Task Never String
, setValue : String -> String -> Step
, getTitle : Task Never String
, clearValue : String -> Step
, getUrl : Task Never String
, click : String -> Step
}

And the following assertions are available in the assert and assert.not records:

{ attributeContains : AttributeData -> Assertion
, attributeEquals : AttributeData -> Assertion
, inlineStyleEquals : StyleData -> Assertion
, valueContains : TextData -> Assertion
, classPresent : ClassData -> Assertion
, containsText : TextData -> Assertion
, styleEquals : StyleData -> Assertion
, elementPresent : String -> Assertion
, elementVisible : String -> Assertion
, titleContains : String -> Assertion
, valueEquals : TextData -> Assertion
, titleEquals : String -> Assertion
, urlContains : String -> Assertion
, urlEquals : String -> Assertion
}

Step groups

You can define a new step that is composed of many other steps but appear as one step in the results with the stepGroup function. If any of the defined steps fails the new step fails as well.

myStep =
  stepGroup "Descripiton of the step"
    [ step1
    , assertion1
    ]

spec =
  it "does something"
    [ myStep
    , step2
    ]

Examples

You can see examples of tests written in elm-spec in here:

elm-spec's People

Contributors

ceddlyburge avatar gdotdesign avatar george-g avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

elm-spec's Issues

Error: Cannot find module 'cssstyle'

There is the error when I execute elm-spec:
module.js:327
throw err;
^

Error: Cannot find module 'cssstyle'
at Function.Module._resolveFilename (module.js:325:15)
at Function.Module._load (module.js:276:25)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object. (C:\Users\me\AppData\Roaming\npm\node_modules\elm-spec\bin\lib\cssstyle.js:1:91)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)

I believe this is because of lack of "cssstyle" in dependencies of this package.

Workaround - copy cssstyle package in to C:\Users\me\AppData\Roaming\npm\node_modules\elm-spec\node_modules

program init with commands

Firstly, it's a great library and works superb with my sandbox project. I'm trying to use it in my real-life project but I've got an issue. My application on start runs some commands (ie. Http GET) which trigger Refresh message - this message populates the model and initializes sub-models. I can't find a way to do similar thing with elm-spec.
In Runner.elm, line 184, there is
, perform (Next Nothing)
which makes it rather impossible.
Is there any other way to trigger some commands on app init?

Thanks a lot,
Maciej

Mocking time

Hi,

Firstly thanks for this great package!

I'm trying to test an Elm component that does some funky things with HTTP requests and time. I'm running with the unmerged PR #4 in order to be able to run with some initial commands like this:

module Main exposing (..)

import GeneralStats.Main as M
import Spec exposing (Node, context, describe, it, assert, runWithProgram, http, steps)


specs : Node msg
specs =
    describe "GeneralStats"
        [ context "with HTTP mocks"
            [ http
                [ { method = "GET"
                  , url = "/api/v1/general_stats/min_date"
                  , response = { status = 200, body = "\"2015-04-01\"" }
                  , entity = ""
                  }
                ]
            , it "has label"
                [ assert.containsText
                    { text = "Assigned members", selector = "table" }
                ]
            ]
        ]
...

main =
    let
        model =
            M.initialModel
        cmd =
            M.initialCmd model
    in
        runWithProgram
            { subscriptions = (\_ -> Sub.none)
            , update = M.update
            , view = M.view
            , init = \_ -> model
            , initCmd = cmd
            }
            specs

M.initialCmd model will first get the current date (via Task.perform ReceiveMaxDate Date.now, then work out the start of the month five months ago and end up issuing two HTTP requests as seen in the output from elm-spec here:

image

I need to mock that second HTTP request which is dependant on the current date.. tricky!

  1. is it possible to mock Date.now .. I'm guessing not without some work to this package.. so

  2. I figure I need to do something to receive the Date.now in a custom update function within this test program and use that alter the behaviour of the specs function.. but I have no idea how to approach this.

Support elm 0.19

Hi There

I've been using this framework, and its basically great.

However it is stopping me moving to elm 0.19, which I'm gradually becoming keener to do.

I'm assuming that this framework is end of life (the author has moved on to other things, and it uses a lot of native code that will take time to migrate), and hence that elm 0.19 support is unlikely to happen, but please correct me if I'm wrong.

Thanks

Cedd

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.