GithubHelp home page GithubHelp logo

lincolnf / pact_elixir Goto Github PK

View Code? Open in Web Editor NEW

This project forked from elitau/pact_elixir

0.0 1.0 0.0 6.78 MB

Elixir version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.

License: MIT License

Elixir 94.88% C 5.12%

pact_elixir's Introduction

Pact FFI

Pact provides a c library that can be used to talk to pact

PactElixir

This library is an Elixir wrapper for the pact-reference implementation

And it is in PRE alpha shape without any semantic versioning or documentation.

Build Status Coverage Status SourceLevel Inline docs

It is not yet usable as many needed parts like publishing a pact file to a broker or pact verification on the provider side are still missing. Also there is no documentation available, yet.

Development

Discussion about the development of this library takes places in the #pact-elixir Channel at https://pact-foundation.slack.com/.

Installation

You need Rust in order to build and install the package.

If available in Hex, the package can be installed by adding pact_elixir to your list of dependencies in mix.exs:

def deps do
  [
    {:pact_elixir, "~> 0.5.2"}
  ]
end

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/pact_elixir.

Examples

This is an example test case:

defmodule PactElixir.PactMockServerTest do
  use ExUnit.Case
  alias PactElixir.{PactMockServer, ServiceProvider}
  import PactElixir.Dsl

  setup do
    options = %{provider: "SomeProvider", consumer: "SomeConsumer"}
    provider = new_service_provider(options)

    {:ok, mock_server_pid} = start_supervised({PactMockServer, provider})
    {:ok, mock_server_pid: mock_server_pid, provider: provider}
  end

  describe "SomeProvider talks to SomeConsumer" do
    test "some basic test", %{mock_server_pid: mock_server_pid} do
      expected = "{groups: ['Editors'], id: 123, username: 'UserA'}"

      user(mock_server_pid)

      assert expected == user(mock_server_pid).body
      assert {:ok} == PactMockServer.write_pact_file(mock_server_pid)
    end
  end

  defp get_request(path, mock_server_pid) when is_pid(mock_server_pid) do
    get_request(path, PactMockServer.port(mock_server_pid))
  end

  defp get_request(path, port) when is_number(port) do
    %HTTPoison.Response{} = HTTPoison.get!("http://localhost:#{port}#{path}")
  end

  def user(mock_server_pid) do
    get_request("/users/UserA", mock_server_pid)
  end

  defp new_service_provider(options \\ %{}) do
    options
    |> PactElixir.Dsl.service_provider()
    |> add_interaction(
      "give me foo",
      given("UserA exists and is not an administrator"),
      with_request(method: :get, path: "/users/UserA"),
      will_respond_with(status: 200, body: "{groups: ['Editors'], id: 123, username: 'UserA'}")
    )
  end
end

You should be able to run it with mix test <path_to_test_case>.

Publishing If the test passes, a json file will be created and saved in a new directory - ./pacts.

Currently, pact publishing is not yet implemented in this library. You can run the following bash script for your basic publishing needs:

#!/bin/bash
# This script:
# 1) extracts the name of provider and consumer from the name of a JSON pact file
# e.g.: Consumer1-Provider.json gives you consumer Consumer1 and provider Provider
# 2) reads the JSON pact file from /pacts directory (pacts are stored there by specification)
# 3) publishes pact to Pact Broker

for pact in ./pacts/*.json; do
    pact_name=$(basename $pact)

    consumer=${pact_name%-*}
    provider=${pact_name#*-}
    provider=${provider%.*}

    curl -v -XPUT \-H "Content-Type: application/json" \
    -d@${pact} \
    https://<your-pact-broker-url>/pacts/provider/$provider/consumer/$consumer/version/<some-version-number>
done

Troubleshooting

Compiling NIF crate :pactmockserver (native/pactmockserver)...
could not compile dependency :pact_elixir, "mix compile"
failed. You can recompile this dependency with "mix deps.compile pact_elixir", update it with "mix deps.update pact_elixir" or clean it with "mix deps.clean pact_elixir"

This can be solved by ensuring proper structure of mix.exs.

  1. Ensure you have rustler listed in compilers
  2. Ensure pactmockserver is listed in rustler_crates
def project do
    [
      #...
      compilers: [:phoenix, :rustler] ++ Mix.compilers(),
      rustler_crates: rustler_crates(Mix.env()),
      #...
    ]
  end

(This is an example setting, where you don't want to ship any rustler crates to production. Bottom line is, there has to be a function that returns the crates list, including pactmockserver).

defp rustler_crates(mix_env) when mix_env in [:test, :dev] do
    [
      pactmockserver: [
        path: "deps/pact_elixir/native/pactmockserver",
        mode: (:debug),
      ]
    ]
  end

  defp rustler_crates(_prod) do
    []
  end

Docker

Properly installing Rust should solve a majority of the problems. Just add the following code (this is for a Debian distro, it assumes you have curl installed):

# Rust is required by pact-elixir
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
ENV PATH=$HOME/.cargo/bin:$PATH

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.