Cucumber

cucumber

configuration

config/cucumber.yml:

<% common_options = '--format pretty' %>

# it's not necessary to specify features directory as argument
default: <%= common_options %>
focus: <%= common_options %> --tags @focus

rake task

Rakefile:

require 'cucumber/rake/task'

Cucumber::Rake::Task.new(:features) do |task|
  # default options are set in cucumber.yml
  task.fork = false
end

it’s not necessary to specify description with desc 'bla bla bla' because Cucumber::Rake::Task already provides description.

syntax highlighting in vim

to enable syntax highlighting for feature files in vim it’s not required to install tpope/vim-cucumber plugin.

step definitions

it doesn’t matter what the name of directory for step definitions is: all files in features/ directory are recursively required.

I prefer to name it steps for the sake of brevity.

wip

https://github.com/cucumber/cucumber/wiki/Tags

it’s like using pending in RSpec.

default profile already includes --tags ~@wip filter - scenarios marked with @wip tag will not be run.

focus

https://github.com/cucumber/cucumber/wiki/Tags

debugging

to show all log messages on screen when running tests temporarily assign $stdout and $stderr to STDOUT and STDERR accordingly in Runner class.

if debugging error in bitbucket pipeline temporarily add lines to log errors to STDERR as well (along with logging to $stderr) in top level class which catches all errors (say, CLI) - this should be done in order not to break tests that check expected output of executed commands.

aruba

AWD - aruba working directory

configuration

features/support/aruba.rb:

require 'aruba/cucumber'

that’s all that is required to use aruba steps in your features.

AWD

by default AWD is tmp/aruba/ (this is where all temporary files are created).

set home directory to AWD

mock home directory (set HOME environment variable to AWD): https://relishapp.com/philoserf/aruba/docs/environment/mock-the-home-variable.

environment variables and dotenv

it’s safe to set environment variables in tests - dotenv will not overwrite existing environments (unless instructed to do so with Dotenv.overload).

checking exit status

don’t check exit status when using ‘I successfully run cmd’ step - test will always either fail or return exit status 0.

fixtures

when using a fixture its directory is copied to AWD (tmp/aruba/) and fixture directory becomes new AWD.

mock home directory after using fixture so that home is set to new AWD (which is fixture directory then) - using @mocked-home-directory tag doesn’t work because in that case home directory is set before running scenario (and changing AWD by fixture accordingly):

  Scenario: New library contains more items than in store
    Given I use the fixture "with_items_12_in_store"
    And a mocked home directory
    ...

troubleshooting

syntastic doesn’t find aruba step definitions

description

it’s necessary to require aruba/cucumber so that syntastic could find aruba step definitions. this file is required in features/support/env.rb as recommended in aruba documentation. but syntastic kept on showing Cucumber::Undefined errors for all aruba steps.

solution

I edited ~/.vim/vimrc to run cucumber with syntastic profile:

let g:syntastic_cucumber_cucumber_args='--profile syntastic'

and required features/support directory explicitly for syntastic profile in config/cucumber.yml:

<% common_options = '--format pretty' %>

default: <%= common_options %>
syntastic: -r features/support <%= common_options %>

but that didn’t help.

in the end it turned out the problem was with the name of support file - syntastic refused to find exactly features/support/env.rb.

btw aruba init --test-framework cucumber generates features/support/aruba.rb so I renamed env.rb to aruba.rb too. after that syntastic no longer showed errors for aruba steps - only for not implemented ones. moreover filename doesn’t even matter - it can be anything but env.rb.

long story short:

syntastic doesn’t require features/support/env.rb for some reason - just rename it to something else (say, aruba.rb). no modifications to config/cucumber.yml or ~/.vim/vimrc are necessary.

environment variables are not loaded with dotenv

description

https://github.com/bkeepers/dotenv:

By default, load will look for a file called .env in the current working directory.

but cucumber changes cwd so .env cannot be found in tests and environment variables are not loaded accordingly.

solution

get path of .env file relative to current file (say, bin/my_app.rb) and load it explicitly:

require 'dotenv'
Dotenv.load(File.expand_path('../../.env', __FILE__))

UPDATE: now I set all environment variables in feature itself.

false positive in the step the following files should exist

description

any string in the first line of data table provided as argument to the step the following files should exist is considered to be an existing file.

this step is defined in aruba gem so the problem must be with this gem.

solution

it has turned out that the latest release (v0.14.2) of aruba has bug in lib/aruba/cucumber/file.rb:82:

files = files.rows.flatten

here files.rows returns all rows in data table except header but according to docs data table argument to this step doesn’t have a header - thus the first line in data table (which is a file to be checked for presence) is treated as a header (which can be anything - it’s ignored anyway).

in the line above raw function should be used instead:

files = files.raw.flatten

here files.raw returns all rows including header. this is fixed in master branch of aruba.

long story short:

use master branch of aruba or provide fake header in data table when checking files for existence or not existence.

if using master branch don’t forget to run cucumber tests using bundle exec cucumber or bundle exec rake cucumber (not cucumber or \rake cucumber) - otherwise gem version (vs. Git version) of aruba is used:

$ which aruba
/Users/tap/.rbenv/shims/aruba
$ rbenv which aruba
/Users/tap/.rbenv/versions/2.4.1/bin/aruba
$ bundle exec which aruba
/Users/tap/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/bin/aruba