Giter VIP home page Giter VIP logo

dredd-hooks-template's Introduction

Cross-Language Test Suite for Dredd Hooks Handlers

Build Status

Dredd is a tool for testing web APIs. It supports hooks written in many languages. To support a particular language, it needs an adapter, so-called hooks handler. This BDD test suite ensures that the public interface of each hooks handler works as Dredd expects. The test suite is written in Gherkin and uses Cucumber as a test runner.

To use the test suite, first read the docs about how to create a new hooks handler for Dredd. Implement your hooks handler and then continue with the following guide.

Installation

  1. Make sure you have Node.js (ideally version 10 or higher) and npm available.

  2. Create a package.json file in the root of your project. This is where your JavaScript dependencies are going to be specified:

    {
      "scripts": { "test": "dredd-hooks-template test" },
      "private": true
    }
  3. Run npm install dredd-hooks-template --save-dev --save-exact to install and declare this test suite as your development dependency.

  4. Run npx dredd-hooks-template init to get a copy of the test suite in the ./features directory.

  5. Open the feature files in ./features/*.feature and in all of them

    • replace {{my-executable-path}} with a path to your hooks handler executable which you want to get tested (e.g. ./bin/dredd_hooks)
    • replace {{my-extension}} by the extension of the hooks handler language (e.g. .py),
    • uncomment the code blocks and rewrite them to the hooks handler language.

Now you have the test suite ready.

Usage

Every time you run npx dredd-hooks-template test (or npm test), you should see the test suite running. The end goal is that all the tests pass:

test suite passing

You should add the package.json file to Git. When starting from scratch, you can run npm install to install the JavaScript dependencies.

Upgrading

Watch for newer versions of the dredd-hooks-template package and upgrade regularly to keep up with development of Dredd and the test suite itself. To upgrade, run:

$ npx dredd-hooks-template upgrade

It upgrades the package to the latest version and copies the latest feature files to the project's ./features/ directory. It won't overwrite the existing files as the names of the new files get suffixed with version. Then it's up to you to compare the old and new files, spot changes, and update the project's test suite.

Reference Implementations

The Python hooks and the Ruby hooks can be used as examples of how to use this cross-language test suite.

Keep Tests Running with CI

To make sure the hooks handler will always work correctly with Dredd and the expectations won't get accidentally broken, put the tests into Travis CI, which runs the tests for each change on your repository. See existing configuration files for inspiration:

dredd-hooks-template's People

Contributors

dependabot-preview[bot] avatar gonzalo-bulnes avatar greenkeeper[bot] avatar honzajavorek avatar miiila avatar w-vi avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

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

dredd-hooks-template's Issues

CLI

Just a crazy idea. It could be nice to have a simple CLI in this package, which would be able to:

  • dredd-template init - Initialize a new hooks project (interactively prompting for information)
  • dredd-template update - Update existing hooks project from the upstream contents of dredd-hooks-template repository
  • dredd-template test - Optional, convenience command wrapping executing of the tests

Obviously, the biggest challenge would be the update command. However, the update command would be the reason for existence of this tool in the first place. Currently, getting updates from upstream is quite painful and manual process. If we have more hook repositories, it can be a real bottle neck.

The update command would probably try to use git under the hood to evaluate the changes. It would take care of language placeholders and would be able to keep language-specific code snippets in place. It would be up to the maintainer to fix them (or add new ones) if the tests do not pass after update. The tool wouldn't try to be super-intelligent, but it would rather try to automate as much of the manual, clearly automatable work as possible.

Don't use `@debug` in test

Use @announce instead of @debug as @debug is possibly buffering or otherwise tempering with the output and tests even though valid may fail.

Be explicit about Dredd path?

In #42 there's a new approach to how the template should be used. The helper CLI takes care of copying the feature files and replaces Dredd path in the feature files to its actual path in local node_modules.

This could be either made completely explicit by putting ./node_modules/.bin/dredd into the feature files directly, or perhaps the steps.js could take care of it somehow. In such case the CLI wouldn't need to modify the files during copy in any way.

Related to #3

Tests do not validate hooks can listen on different ports

I fixed this bug a while back with the php hooks (Go is probably an offender at the moment). Nothing in the test suite validates that a hook server's implementation will work with dredd's --hooks-worker-handler-port. Making this as a reminder to myself to make a future PR to add this test. Do we have any idea if other hook servers respect this? I am assuming ruby and python are good since you guys developed them. That would leave the Go and Perl ones potentially if thats the case.

Test the 'upgrade' CLI command

The #42 introduces an 'upgrade' command. We should somehow verify it works in the smoke test. It is necessary to publish the package for the first time for the 'upgrade' command to work, and perhaps also Semantic Release should be employed here as well before we dig into this.

The test suite kills any process (including itself) if its path contains string 'dredd-hooks' (e.g. in dir name)

Running bundle exec cucumber outputs

$ bundle exec cucumber
Feature: Execution order

Killed: 9

on my computer (Mac). I debugged that it's caused by following lines in features/support/env.rb:

...
Before do
  puts "Killing server..."
  system "for i in `ps axu | grep 'server.rb' | grep ruby | awk '{print $2}'`; do kill -9 $i; done > /dev/null 2>&1"
  puts "Killing handler..."
  system "for i in `ps axu | grep 'dredd-hooks' | grep ruby | awk '{print $2}'`; do kill -9 $i; done > /dev/null 2>&1"
  ...

If I comment out the two "killing" lines, I can run Cucumber without problems, but then it seems to hang in the Feature: TCP server and messages / Scenario: Message exchange for event beforeEach / And I send a newline character as a message delimiter to the socket part:

Feature: TCP server and messages

  Scenario: TCP server                                       # features/tcp_server.feature:3
      Killing server...
      Killing handler...
    When I run `dredd-hooks-ruby` interactively              # vendor/bundle/ruby/2.0.0/gems/aruba-0.6.2/lib/aruba/cucumber.rb:113
    And I wait for output to contain "Starting"              # vendor/bundle/ruby/2.0.0/gems/aruba-0.6.2/lib/aruba/cucumber.rb:131
    Then It should start listening on localhost port "61321" # features/step_definitions/dredd_steps.rb:13

  Scenario: Message exchange for event beforeEach                       # features/tcp_server.feature:8
      Killing server...
      Killing handler...
    Given I run `dredd-hooks-ruby` interactively                        # vendor/bundle/ruby/2.0.0/gems/aruba-0.6.2/lib/aruba/cucumber.rb:113
    When I wait for output to contain "Starting"                        # vendor/bundle/ruby/2.0.0/gems/aruba-0.6.2/lib/aruba/cucumber.rb:131
    And I connect to the server                                         # features/step_definitions/dredd_steps.rb:18
    And I send a JSON message to the socket:                            # features/step_definitions/dredd_steps.rb:22
      """
      {"event": "beforeEach", "uuid": "1234-abcd", "data": {"key":"value"}}
      """
    And I send a newline character as a message delimiter to the socket # features/step_definitions/dredd_steps.rb:27

Nothing gets printed since that moment for very long time and I have to eventually interrupt Cucumber with Ctrl+C.

Add a feature which requires hooks handler to react to SIGTERM

Taking this out of https://github.com/apiaryio/dredd-hooks-template/pull/65/files#r290878471 where @kylef proposes:

Maybe in this case if a process doesn't gracefully exit from SIGTERM that should be a test failure too (instead of having to SIGKILL it).

This is a proposal to add a feature, which ensures the hooks handlers can react to SIGTERM correctly (SIGINT could be tested too).

Downsides of introducing this is that it would be slightly harder to write a hooks handler (the author already needs to know TCP, now they'd need to know what signals are and how they work) and that SIGTERM (or any alternative to it) doesn't exist on Windows, which would make it complicated for those either aiming for Windows support (#21) or developing the hooks handler on Windows (no way to test locally that it works).

Rewrite the template to Node.js

The whole hooks template and especially the Ruby hooks are in a somewhat hard-to-resolve state: apiaryio/dredd#917 I've written 5 lines of Ruby in my whole life and putting the template and the Ruby hooks into shape feels overwhelming to me. I'd like to port dredd-hooks-template to Node.js instead of using Ruby.

Why?

  • Because I'm able to maintain it in that case and to give it a full support, as well as anyone else in the company or new hires or Dredd contributors, as Dredd itself is in JavaScript.

  • Second, if the test suite itself is in Ruby, it brings Ruby dependencies to all of the other projects. That's an issue for Ruby hooks, where it constraints Ruby hooks' own dependencies, and it also feels strange (read as "makes CI setup complicated") in projects like Go, Rust, Python, etc. Unlike Ruby, thanks to web development, today Node.js is a common "buddy" of other languages, living alongside other-language projects, and people are used to work with it. Even hardcore backend Python people know how to npm install things.

    If you don't know what I mean by the "buddy" thing, see e.g. this:

    image
  • The Node.js hooks are a native part of Dredd, so there can never be a collision like Ruby hooks / Ruby hooks template dependencies. Node.js is mutually exclusive to additional languages supported by Dredd.

Change the placeholder for the hooks handler executable

Currently there's dredd-hooks-{{mylanguage}} in the feature files. It could be changed to something better conveying the fact that the whole string is a placeholder (not just a part of it) and that it represents a path to the hooks handler executable under test. Related to #4

Simplify server steps

image

Perhaps it's unnecessary to be so explicit? What about something like

And a file "server.js" with a server responding on "/message" with "Hello World!" 

The steps can implement it as a black box then.

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.