Skip to content

Releases: wesovilabs/exkorpion

v0.0.3

27 Sep 03:49
Compare
Choose a tag to compare

Exkorpion

An Elixir framework to do testing in a BDD way

Installation

Library is available in Hex, the package can be installed as:

  1. Add exkorpion to your list of dependencies in mix.exs:

    def deps do
      [{:exkorpion, "~> 0.0.2"}]
    end

In case of you don't have a elixir environment ready to code, please have a look at the below links:

Exkorpion goals

  • It wraps ExUnit and enhances their features providing developers with a BDD syntax.
  • It helps us to write tests wasy-to-read.
  • It is completely compatible with ExUnit.
  • It force us to structure our tests in steps (given-when-then)
  • It is based on a functional syntax, organization our tests steps by anonymous functions.
  • It is not coupled to any other framework.

Getting started

Exkorpion syntax

As was mentioned on the above Exkorpion is mainly oriented to a bdd syntax:

scenario: A scenario groups multiple cases that test a functionality works as expected. By using scenario we achieve the below:

  • Better documentation for other developers.
  • Test are better organized and structured
  • Working under an agile methodology we can match scenarios to acceptance criteria

it: Exkorpion provide with a reserved word It to represent any of the cases inside a scenario.

      scenario "testing sum operation works as expected" do

         it "sum positive numbers works as expected" do

         end

         it "sum negative numbers and it should work as expected" do

         end

      end

with/given/when/then: These word are the ones that provide us with s BDD syntax. Actually even when we write some unit tests we should thinkg about them.

  • Given: It defines the input data for performing the tests. (It's an optional step, it could be not neccessary sometimes)

  • When: It performs the action to be tested.

  • Then: It ensures the result in the preoviuos step are the expected.

      it "Ensures that get tracks service returns always 2 elements" do
        %{
          when: fn _ ->
            %{result: build_conn() |> get("/tracks", "v1") |> json_response |> Poison.decode! }
          end,  
          then: fn ctx ->
            assert 2 === length(ctx.result)
          end   
        }
      end

    we could make us of with* step if we pretend to run the some tests for multiple input

      it "Ensures that add new track service works as expected" do
        %{
          with: fn ctx ->
              [
                %{new_track: %{"title" => "Runaway", "singer" => "John Bon Jovi"}},
                %{new_track: %{"title" => "Let her go", "singer" => "The passenger"}},
              ]
          end,
          given: &(%{new_track_json: &1.new_track |> Poison.encode!, previous_tracks: build_conn() |> get("/tracks", "v1") |> json_response |> Poison.decode! }),
          when: fn ctx ->
            %{result: build_conn() |> put_body_or_params(ctx.new_track) |> post("/tracks", "v1") |> json_response |> Poison.decode! }         
    
          end,  
            then: fn ctx ->
              assert length(ctx.previous_tracks)+1 === length(ctx.result)
              assert true === Enum.member?(ctx.result, ctx.new_track)
            end   
        }
      end

before_each: Before each will be inside of a scenario and provices with a reusable set of data for our tests.

    scenario "testing sum operation works as expected" do

      before_each do
        %{a: 10}
      end

      it "sum positive numbers works as expected" do
        %{
          given: &(%{a: &1.a, b: 3}),
          when: &(%{c: &1.a + &1.b}),
          then: fn ctx ->
            assert ctx.c === 13
          end
        }
      end

      it "sum negative numbers and it should work as expected" do
        %{
          given: &(%{a: &1.a, b: -2}),
          when: &(%{c: sum(&1.a ,&1.b)}),
          then: fn ctx ->
            assert ctx.c === 8
          end
        }
      end

    end

First steps

  • Once we have added exkorpion dependency to our test we can run the below command. This will creae a scenario directory on our poejct with a file named scenario_helper.exs.

      mix exkorpion.init
  • By default Exkorpion will search files ended by ".._scenario.exs" inside directory scenarios. This could be easyly customized (We explain in following articles.)

  • We can write one or more scenarios per file

  • To run the exkorpion scenarios we just need to run

      MIX_ENV=test mix exkorpion
  • Exkorpion provides with a friendly resume about our tests execution.

    Success execution
    exkorpion success

    Something went wrong!
    exkorpion error

Samples

It's highly recommendable you to have a look at some samples already developed:

Contributors

v0.0.2

13 Sep 15:42
Compare
Choose a tag to compare

Build Status
Hex version
Hex downloads

Exkorpion

An Elixir framework to do testing in a BDD way

Installation

Library is available in Hex, the package can be installed as:

  1. Add exkorpion to your list of dependencies in mix.exs:

    def deps do
      [{:exkorpion, "~> 0.0.2"}]
    end

In case of you don't have a elixir environment ready to code, please have a look at the below links:

Exkorpion goals

  • It wraps ExUnit and enhances their features providing developers with a BDD syntax.
  • It helps us to write tests wasy-to-read.
  • It is completely compatible with ExUnit.
  • It force us to structure our tests in steps (given-when-then)
  • It is based on a functional syntax, organization our tests steps by anonymous functions.
  • It is not coupled to any other framework.

Getting started

Exkorpion syntax

As was mentioned on the above Exkorpion is mainly oriented to a bdd syntax:

scenario: A scenario groups multiple cases that test a functionality works as expected. By using scenario we achieve the below:

  • Better documentation for other developers.
  • Test are better organized and structured
  • Working under an agile methodology we can match scenarios to acceptance criteria

it: Exkorpion provide with a reserved word It to represent any of the cases inside a scenario.

      scenario "testing sum operation works as expected" do

         it "sum positive numbers works as expected" do

         end

         it "sum negative numbers and it should work as expected" do

         end

      end

with/given/when/then: These word are the ones that provide us with s BDD syntax. Actually even when we write some unit tests we should thinkg about them.

  • Given: It defines the input data for performing the tests. (It's an optional step, it could be not neccessary sometimes)

  • When: It performs the action to be tested.

  • Then: It ensures the result in the preoviuos step are the expected.

      it "Ensures that get tracks service returns always 2 elements" do
        %{
          when: fn _ ->
            %{result: build_conn() |> get("/tracks", "v1") |> json_response |> Poison.decode! }
          end,  
          then: fn ctx ->
            assert 2 === length(ctx.result)
          end   
        }
      end

    we could make us of with* step if we pretend to run the some tests for multiple input

      it "Ensures that add new track service works as expected" do
        %{
          with: fn ctx ->
              [
                %{new_track: %{"title" => "Runaway", "singer" => "John Bon Jovi"}},
                %{new_track: %{"title" => "Let her go", "singer" => "The passenger"}},
              ]
          end,
          given: &(%{new_track_json: &1.new_track |> Poison.encode!, previous_tracks: build_conn() |> get("/tracks", "v1") |> json_response |> Poison.decode! }),
          when: fn ctx ->
            %{result: build_conn() |> put_body_or_params(ctx.new_track) |> post("/tracks", "v1") |> json_response |> Poison.decode! }         
    
          end,  
            then: fn ctx ->
              assert length(ctx.previous_tracks)+1 === length(ctx.result)
              assert true === Enum.member?(ctx.result, ctx.new_track)
            end   
        }
      end

beforeEach: Before each will be inside of a scenario and provices with a reusable set of data for our tests.

    scenario "testing sum operation works as expected" do

      beforeEach do
        %{a: 10}
      end

      it "sum positive numbers works as expected" do
        %{
          given: &(%{a: &1.a, b: 3}),
          when: &(%{c: &1.a + &1.b}),
          then: fn ctx ->
            assert ctx.c === 13
          end
        }
      end

      it "sum negative numbers and it should work as expected" do
        %{
          given: &(%{a: &1.a, b: -2}),
          when: &(%{c: sum(&1.a ,&1.b)}),
          then: fn ctx ->
            assert ctx.c === 8
          end
        }
      end

    end

First steps

  • Once we have added exkorpion dependency to our test we can run the below command. This will creae a scenario directory on our poejct with a file named scenario_helper.exs.

      mix exkorpion.init
  • By default Exkorpion will search files ended by ".._scenario.exs" inside directory scenarios. This could be easyly customized (We explain in following articles.)

  • We can write one or more scenarios per file

  • To run the exkorpion scenarios we just need to run

      MIX_ENV=test mix exkorpion
  • Exkorpion provides with a friendly resume about our tests execution.

    Success execution
    exkorpion success

    Something went wrong!
    exkorpion error

Samples

It's highly recommendable you to have a look at some samples already developed:

Contributors

0.0.2-rc.2

07 Sep 05:32
Compare
Choose a tag to compare
0.0.2-rc.2 Pre-release
Pre-release

Bug Fixes

There was not bug detected for previous version.

Code Refactoring

None

Features

  • Providing a Exkopion site on Exkorpion site, still in draft
  • Full integration with ExUnit
  • Add table resume after tests are executed

TODO

  • Re-factor code (Very mandatory for next release), Specially function print_resume in task exkorpion.

0.0.2-rc.1

02 Sep 12:10
Compare
Choose a tag to compare
0.0.2-rc.1 Pre-release
Pre-release

Exkorpion

Exkorpion is a framework that will help developers to write tests in a BDD form.

Installation

Library is available in Hex, the package can be installed as:

  1. Add exkorpion to your list of dependencies in mix.exs:

    def deps do
      [{:exkorpion, "~> 0.0.2-rc.1"}]
    end
  2. Ensure exkorpion is started before your application:

    def application do
      [applications: [:exkorpion]]
    end

Getting started with Exkorpion

Wrapping ExUnit to achieve a BDD syntax for our tests.

Below you can find some very basic examples of how to use Exkorpion

  defmodule Exkorpion.MathExamplesTest do
  use Exkorpion

  def sum a, b do
    a + b
  end

  def subs a, b do
    a - b
  end



  scenario "testing sum operation works as expected" do

    beforeEach do
      %{a: 12}
    end


    it "does multiple operations depending on vairable input" do

      %{
        with: fn ctx ->
        [
          %{param1: ctx.a, param2: 3, result: 15, op: fn a,b -> sum(a,b) end},
          %{param1: 3, param2: -2, result: 5, op: fn a,b -> subs(a,b) end}
        ]
        end,
        given: fn ctx ->
          %{a: ctx.param1, b: ctx.param2}
        end,
        when: &(%{c: &1.op.(&1.a ,&1.b)}),
        then: fn ctx ->
          assert ctx.c === ctx.result
        end
      }
    end
  end  

  scenario "testing sum operation works as expected 2" do

    beforeEach do
      %{a: 10}
    end

    it "sum positive numbers works as expected" do
      %{
        given: &(%{a: &1.a, b: 3}),
        when: &(%{c: &1.a + &1.b}),
        then: fn ctx ->
          assert ctx.c === 13
        end
      }
    end

    it "sum negative numbers and it should work as expected" do
      %{
        given: &(%{a: &1.a, b: -2}),
        when: &(%{c: sum(&1.a ,&1.b)}),
        then: fn ctx ->
          assert ctx.c === 8
        end
      }
    end

  end

end

How to run

  • Make a *scenarios directory in your project
  • Add files with sufix _scenario.ex or _scenario.exs
  • Implementing some test as example above.
  • Run command MIX_ENV=test mix exkorpion

Project status

  • Improving coding style
  • Implementing new functionalities.
  • Detecting bugs and fixing them.
  • Waitign for feddback.

Contributors

Stable version

0.0.1 is the stable version

CHANGELOG.md

0.0.2-rc.1 (2016-09-02)

Bug Fixes

There was not bug detected for previous version.

Code Refactoring

  • Applying best coding practice (trying at least XD)
  • Adding credo to run static code analysis.

Features

  • Adding beforeEach functionality
  • Raising Assertion Errors, better understanding of assertion errors
  • Adding exkorpion examples as part of this project
  • Creating a task that will allow us to run the tests by command mix exkorpion

Initial release

29 Aug 05:40
Compare
Choose a tag to compare

Exkorpion

Exkorpion is a framework that will help developers to write tests in a BDD form.

Installation

Library is available in Hex, the package can be installed as:

  1. Add exkorpion to your list of dependencies in mix.exs:

    def deps do
      [{:exkorpion, "~> 0.0.1"}]
    end
  2. Ensure exkorpion is started before your application:

    def application do
      [applications: [:exkorpion]]
    end

Getting started with Exkorpion

As was mentioned above Exkorpion is a test framework focused on helping developers to work under BDD. Then, as you could guess the syntax
will look like Given-When-Then.

Below you can find some very basic examples of how to use Exkorpion

        defmodule ExkorpionDemo.MathOperationsTest do
            use Exkorpion

            def sum(a,b) do
                a + b
            end

            def subs a, b do
              a - b
            end

            scenario "testing sum operation works as expected" do

                    it "sum positive numbers works as expected" do
                        %{
                            given: fn -> %{a: 1, b: 2} end,

                            when: fn ctx ->
                                %{c: ctx.a + ctx.b}
                            end,
                            then: fn ctx ->
                                assert ctx.c === 3
                            end
                        }
                    end

                    it "sum negative numbers and it should work as expected" do
                      %{
                        given: fn  ->
                            %{a: -1, b: -2}
                        end,
                        when: fn ctx ->
                            %{c: sum(ctx.a, ctx.b)}
                        end,
                        then: fn ctx ->
                            assert ctx.c === -3
                        end
                      }
                    end

                    it "does multiple operations depending on vairable input" do

                      %{
                          with: fn ->
                            [
                                %{param1: 2, param2: 3, result: 5},
                                %{param1: 3, param2: -2, result: 1}
                            ]
                          end,
                          given: fn ctx ->
                            %{a: ctx.param1, b: ctx.param2}
                          end,
                          when: fn ctx ->
                            %{c: sum(ctx.a, ctx.b)}
                          end,
                          then: fn ctx ->
                            assert ctx.c === ctx.result
                          end
                      }
                    end
           end
        end

In order to write new tests with Exkorpion, we need to consider the below:

  1. Add use Exkorpion after module declaration.
  2. A scenario will be compounds by one of multiple cases, which are represented by *it
  3. So far, we can write two types of tests:
    • We can write basic tests with the required 3 steps: Given, When and Then and the tests will be performed in this order. An example of this
      type of tests can be found in the above example: it sum positive numbers works as expected and it does multiple operations depending on vairable input
    • We could extend the test by defining different inputs for the same tests. We can achieve by adding with to our map declaration, as we can see in
      it does multiple operations depending on vairable input

Contributors