gurke 2.1.0 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/README.md +2 -0
- data/features/gurke/other_reporter.feature +35 -0
- data/features/gurke/run_specific_directories.feature +62 -0
- data/lib/gurke.rb +1 -0
- data/lib/gurke/cli.rb +19 -2
- data/lib/gurke/feature.rb +1 -1
- data/lib/gurke/reporter.rb +27 -0
- data/lib/gurke/reporters/default_reporter.rb +0 -23
- data/lib/gurke/reporters/team_city_reporter.rb +128 -0
- data/lib/gurke/runner.rb +4 -1
- data/lib/gurke/step_definition.rb +2 -1
- data/lib/gurke/version.rb +2 -2
- data/spec/gurke/step_definition_spec.rb +27 -0
- metadata +9 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8c96ab204add1ca62ac31c38b6c375324ee89e3
|
4
|
+
data.tar.gz: 42ba448e6eaf2bdf6352df493d31036c0ab789cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 350ced1ca8fac0b2279ceab141bccd3c16eb358a129de1aa7ed06c960c94a11e61706e4730cc53af2846e2c9e73493e1e29544a8c659b610d2ce7448c183cf36
|
7
|
+
data.tar.gz: 2b2831a82dea72c9c8c552e88187ac17574d9bcbce2e69deae41a94efe4e144ea3c5c13ae07052826244ca1a7f962d3e56ec27585e38689be58d1e84370fc713
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## 2.2.1
|
4
|
+
|
5
|
+
* BugFix (missing argument in cli.rb)
|
6
|
+
* BugFix in after_feature hook call (missing feature argument)
|
7
|
+
|
8
|
+
## 2.2.0
|
9
|
+
|
10
|
+
+ Support executing all features inside one directory
|
11
|
+
+ Support reporter selection via cli
|
12
|
+
+ Add TeamCityReporter (`gurke --formatter team_city`)
|
13
|
+
* Support string as step definitions correctly
|
14
|
+
* Smaller bugfix in improved exception formatting
|
15
|
+
|
16
|
+
|
17
|
+
## 2.1.0
|
18
|
+
|
19
|
+
* Improve exception formating
|
20
|
+
|
21
|
+
## 2.0.0
|
22
|
+
|
23
|
+
* Project start
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Gurke
|
2
2
|
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/gurke.svg)](http://badge.fury.io/rb/gurke) [![Build Status](http://img.shields.io/travis/jgraichen/gurke/master.svg)](https://travis-ci.org/jgraichen/gurke) [![Code Climate](http://img.shields.io/codeclimate/github/jgraichen/gurke.svg)](https://codeclimate.com/github/jgraichen/gurke) [![Dependency Status](http://img.shields.io/gemnasium/jgraichen/gurke.svg)](https://gemnasium.com/jgraichen/gurke) [![RubyDoc Documentation](http://img.shields.io/badge/rubydoc-here-blue.svg)](http://rubydoc.info/github/jgraichen/gurke/master/frames)
|
4
|
+
|
3
5
|
**Gurke** is an experimental, alternative cucumber runner. It ~~steals~~ borrows ideas and concepts from [turnip](https://github.com/jnicklas/turnip), [rspec](http://rspec.info) and tries to avoid [cucumber](https://github.com/cucumber/cucumber/).
|
4
6
|
|
5
7
|
That includes * Step definitions in modules * Before, After and Around hooks * Formatters * Partial step inclusion (via modules) * etc. Also new ideas like keyword depended step definitions are planned.
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Feature: Other Reporter
|
2
|
+
As a developer
|
3
|
+
In order to adjust the output to my requirements (e.g. inside a CI)
|
4
|
+
I want to pass a command line argument to change the reporter
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given I am in a project using gurke
|
8
|
+
And a file "features/test.feature" with the following content exists
|
9
|
+
"""
|
10
|
+
Feature: F
|
11
|
+
Scenario: Scenario A
|
12
|
+
Given this is a success
|
13
|
+
|
14
|
+
"""
|
15
|
+
And a file "features/support/steps/test_steps.rb" with the following content exists
|
16
|
+
"""
|
17
|
+
module TestSteps
|
18
|
+
step("This is a success") { }
|
19
|
+
end
|
20
|
+
Gurke.configure{|c| c.include TestSteps }
|
21
|
+
"""
|
22
|
+
|
23
|
+
Scenario: Use the default reporter without addition arguments
|
24
|
+
When I execute "bundle exec gurke"
|
25
|
+
Then the program output should not include "##teamcity"
|
26
|
+
|
27
|
+
Scenario: Use specified reporter when run with --formatter
|
28
|
+
When I execute "bundle exec gurke --formatter team_city"
|
29
|
+
Then the program output should include "##teamcity[testStarted name='Scenario A']"
|
30
|
+
Then the program output should include "##teamcity[testFinished name='Scenario A']"
|
31
|
+
|
32
|
+
Scenario: Use specified reporter when run with -f
|
33
|
+
When I execute "bundle exec gurke -f team_city"
|
34
|
+
Then the program output should include "##teamcity[testStarted name='Scenario A']"
|
35
|
+
Then the program output should include "##teamcity[testFinished name='Scenario A']"
|
@@ -0,0 +1,62 @@
|
|
1
|
+
Feature: Run specific features or scenarios
|
2
|
+
In order to get faster test results
|
3
|
+
As a user
|
4
|
+
I want run only feature files from one directory
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given I am in a project using gurke
|
8
|
+
Given a file "features/odd/a.feature" with the following content exists
|
9
|
+
"""
|
10
|
+
Feature: F
|
11
|
+
Bla blub, a longer description.
|
12
|
+
|
13
|
+
Scenario: Scenario A
|
14
|
+
Given I am successful
|
15
|
+
"""
|
16
|
+
Given a file "features/odd/c.feature" with the following content exists
|
17
|
+
"""
|
18
|
+
Feature: F
|
19
|
+
Bla blub, a longer description.
|
20
|
+
|
21
|
+
Scenario: Scenario C
|
22
|
+
Given I am successful
|
23
|
+
"""
|
24
|
+
Given a file "features/even/b.feature" with the following content exists
|
25
|
+
"""
|
26
|
+
Feature: F
|
27
|
+
Bla blub, a longer description.
|
28
|
+
|
29
|
+
Scenario: Scenario B
|
30
|
+
Given I am successful
|
31
|
+
"""
|
32
|
+
Given a file "trash/b.f" with the following content exists
|
33
|
+
"""
|
34
|
+
Feature: F
|
35
|
+
Bla blub, a longer description.
|
36
|
+
|
37
|
+
Scenario: Scenario B
|
38
|
+
Given I am successful
|
39
|
+
"""
|
40
|
+
And a file "features/support/steps/test_steps.rb" with the following content exists
|
41
|
+
"""
|
42
|
+
module TestSteps
|
43
|
+
Given("I am successful") { true }
|
44
|
+
end
|
45
|
+
Gurke.configure{|c| c.include TestSteps }
|
46
|
+
"""
|
47
|
+
|
48
|
+
Scenario: Run all features from on directory
|
49
|
+
When I execute "bundle exec gurke features/odd"
|
50
|
+
And the program output should include "2 scenarios: 0 failing, 0 pending"
|
51
|
+
|
52
|
+
Scenario: Run all features from on directory (II)
|
53
|
+
When I execute "bundle exec gurke features/even"
|
54
|
+
And the program output should include "1 scenarios: 0 failing, 0 pending"
|
55
|
+
|
56
|
+
Scenario: Run all features from on directory (with subdirectories)
|
57
|
+
When I execute "bundle exec gurke features"
|
58
|
+
And the program output should include "3 scenarios: 0 failing, 0 pending"
|
59
|
+
|
60
|
+
Scenario: Run all features from on directory (based on feature pattern)
|
61
|
+
When I execute "bundle exec gurke trash"
|
62
|
+
And the program output should include "0 scenarios: 0 failing, 0 pending"
|
data/lib/gurke.rb
CHANGED
data/lib/gurke/cli.rb
CHANGED
@@ -28,8 +28,7 @@ module Gurke
|
|
28
28
|
Dir[r].each{|f| require File.expand_path(f) }
|
29
29
|
end if options[:require].any?
|
30
30
|
|
31
|
-
files
|
32
|
-
files.map!{|f| File.expand_path(f) }
|
31
|
+
files = expand_files files, options
|
33
32
|
|
34
33
|
runner = if options[:drb_server]
|
35
34
|
Runner::DRbServer
|
@@ -58,6 +57,8 @@ module Gurke
|
|
58
57
|
opt :help, 'Print this help.'
|
59
58
|
opt :version, 'Show program version information.'
|
60
59
|
opt :backtrace, 'Show full error backtraces.'
|
60
|
+
opt :formatter, 'Select a special formatter as reporter', \
|
61
|
+
default: 'default'
|
61
62
|
opt :pattern, 'File pattern matching feature files to be run.',
|
62
63
|
default: 'features/**/*.feature'
|
63
64
|
opt :require, 'Files matching this pattern will be required after'\
|
@@ -73,5 +74,21 @@ module Gurke
|
|
73
74
|
opt :drb, 'Run features on already started DRb server. (experimental)', short: :none
|
74
75
|
end
|
75
76
|
end
|
77
|
+
|
78
|
+
private
|
79
|
+
def expand_files(files, options)
|
80
|
+
files = Dir[options[:pattern].to_s] if files.empty? && options[:pattern]
|
81
|
+
files.inject([]) do |memo, input|
|
82
|
+
if File.directory? input
|
83
|
+
Dir[input + '/**/*'].each do |file_in_dir|
|
84
|
+
next if options[:pattern] && !File.fnmatch?(options[:pattern], file_in_dir)
|
85
|
+
memo << File.expand_path(file_in_dir)
|
86
|
+
end
|
87
|
+
else
|
88
|
+
memo << File.expand_path(input)
|
89
|
+
end
|
90
|
+
memo
|
91
|
+
end
|
92
|
+
end
|
76
93
|
end
|
77
94
|
end
|
data/lib/gurke/feature.rb
CHANGED
data/lib/gurke/reporter.rb
CHANGED
@@ -255,5 +255,32 @@ module Gurke
|
|
255
255
|
rescue => e
|
256
256
|
warn "Rescued in reporter: #{e}\n" + e.backtrace.join("\n")
|
257
257
|
end
|
258
|
+
|
259
|
+
|
260
|
+
# @api private
|
261
|
+
#
|
262
|
+
protected
|
263
|
+
def format_exception(ex)
|
264
|
+
s = [ex.class.to_s + ': ' + ex.message.strip]
|
265
|
+
if ex.backtrace.nil?
|
266
|
+
s << ' <no backtrace available>'
|
267
|
+
elsif ex.backtrace.empty?
|
268
|
+
s << ' <backtrace empty>'
|
269
|
+
else
|
270
|
+
ex.backtrace.each do |bt|
|
271
|
+
s << ' ' + bt.strip
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
if ex.respond_to?(:cause) && ex.cause &&
|
276
|
+
ex.cause.respond_to?(:message) && ex.cause.respond_to?(:backtrace)
|
277
|
+
|
278
|
+
cause = format_exception(ex.cause)
|
279
|
+
s << 'caused by: ' + cause.shift
|
280
|
+
s += cause
|
281
|
+
end
|
282
|
+
|
283
|
+
s
|
284
|
+
end
|
258
285
|
end
|
259
286
|
end
|
@@ -90,29 +90,6 @@ module Gurke::Reporters
|
|
90
90
|
io.puts exout.map{|s| red(" #{s}\n") }.join
|
91
91
|
end
|
92
92
|
|
93
|
-
def format_exception(ex)
|
94
|
-
s = [ex.message.strip]
|
95
|
-
if ex.backtrace.nil?
|
96
|
-
s << ' <no backtrace available>'
|
97
|
-
elsif ex.backtrace.empty?
|
98
|
-
s << ' <backtrace empty>'
|
99
|
-
else
|
100
|
-
ex.backtrace.each do |bt|
|
101
|
-
s << ' ' + bt.strip
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
if ex.respond_to?(:cause) && ex.cause &&
|
106
|
-
ex.cause.respond_to?(:message) && ex.cause.respond_to?(:backtrace)
|
107
|
-
|
108
|
-
cause = format_exception(ex.cause)
|
109
|
-
s << 'caused by: ' + cause.shift
|
110
|
-
s += cause
|
111
|
-
end
|
112
|
-
|
113
|
-
s
|
114
|
-
end
|
115
|
-
|
116
93
|
[:black, :red, :green, :yellow, :blue,
|
117
94
|
:magenta, :cyan, :white, :default, :light_black,
|
118
95
|
:light_red, :light_green, :light_yellow, :light_blue,
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module Gurke::Reporters
|
2
|
+
#
|
3
|
+
# The {TeamCityReporter} prints features, scenarios and
|
4
|
+
# steps in a format parseable by TeamCity CI.
|
5
|
+
#
|
6
|
+
class TeamCityReporter < NullReporter
|
7
|
+
attr_reader :io
|
8
|
+
def initialize(io = $stdout)
|
9
|
+
@io = io
|
10
|
+
end
|
11
|
+
|
12
|
+
def before_feature(feature)
|
13
|
+
publish :testSuiteStarted, name: feature.name
|
14
|
+
io.puts " #{feature.description.split("\n").join("\n ")}"
|
15
|
+
io.puts
|
16
|
+
end
|
17
|
+
|
18
|
+
def before_scenario(scenario)
|
19
|
+
@scenario = scenario
|
20
|
+
publish :testStarted, name: scenario.name
|
21
|
+
end
|
22
|
+
|
23
|
+
def start_background(*)
|
24
|
+
unless @background
|
25
|
+
io.puts ' Background:'
|
26
|
+
end
|
27
|
+
|
28
|
+
@background = true
|
29
|
+
end
|
30
|
+
|
31
|
+
def end_background(*)
|
32
|
+
@background = false
|
33
|
+
end
|
34
|
+
|
35
|
+
def before_step(step, *)
|
36
|
+
io.print ' ' if @background
|
37
|
+
io.print ' '
|
38
|
+
io.print step.keyword
|
39
|
+
io.print step.name
|
40
|
+
end
|
41
|
+
|
42
|
+
def after_step(step, *)
|
43
|
+
case step.state
|
44
|
+
when :pending then print_pending step
|
45
|
+
when :failed then print_failed step
|
46
|
+
when :success then print_braces 'success'
|
47
|
+
else print_braces 'skipped'
|
48
|
+
end
|
49
|
+
io.puts
|
50
|
+
io.flush
|
51
|
+
end
|
52
|
+
|
53
|
+
def after_scenario(scenario)
|
54
|
+
publish :testFinished, name: scenario.name
|
55
|
+
end
|
56
|
+
|
57
|
+
def after_feature(feature)
|
58
|
+
publish :testSuiteFinished, name: feature.name
|
59
|
+
end
|
60
|
+
|
61
|
+
def after_features(features)
|
62
|
+
scenarios = features.map(&:scenarios).flatten
|
63
|
+
|
64
|
+
example_count = scenarios.size
|
65
|
+
failure_count = scenarios.select(&:failed?).size
|
66
|
+
pending_count = scenarios.select(&:pending?).size
|
67
|
+
|
68
|
+
io.puts " #{example_count} scenarios: " \
|
69
|
+
"#{failure_count} failing, " \
|
70
|
+
"#{pending_count} pending"
|
71
|
+
io.puts
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def print_braces(str)
|
77
|
+
io.print " (#{str})"
|
78
|
+
end
|
79
|
+
|
80
|
+
def print_pending(step)
|
81
|
+
return if @pending == @scenario # only once per scenario
|
82
|
+
publish :testPending,
|
83
|
+
name: @scenario.name,
|
84
|
+
message: 'Step definition missing'
|
85
|
+
@pending = @scenario
|
86
|
+
end
|
87
|
+
|
88
|
+
def print_failed(step)
|
89
|
+
publish :testFailed,
|
90
|
+
name: @scenario.name,
|
91
|
+
message: step.exception.inspect,
|
92
|
+
backtrace: step.exception.backtrace.join('\n')
|
93
|
+
|
94
|
+
print_braces 'failure'
|
95
|
+
io.puts
|
96
|
+
|
97
|
+
exout = format_exception(step.exception)
|
98
|
+
io.puts exout.map{|s| " #{s}\n" }.join
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
private
|
103
|
+
def publish(message_name, args)
|
104
|
+
args = [] << message_name.to_s << escaped_array_of(args)
|
105
|
+
args = args.flatten.reject(&:nil?)
|
106
|
+
|
107
|
+
io.puts "##teamcity[#{args.join(' ')}]"
|
108
|
+
end
|
109
|
+
|
110
|
+
def escape(string)
|
111
|
+
string.gsub(/(\||'|\r|\n|\u0085|\u2028|\u2029|\[|\])/, '|$1')
|
112
|
+
end
|
113
|
+
|
114
|
+
def escaped_array_of(args)
|
115
|
+
return [] if args.nil?
|
116
|
+
|
117
|
+
if args.is_a? Hash
|
118
|
+
args.map { |key, value| "#{key.to_s}='#{escape value.to_s}'" }
|
119
|
+
else
|
120
|
+
"'#{escape args}'"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def step_name(step)
|
125
|
+
step.keyword + step.name.gsub(/"(.*?)"/, '\0')
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
data/lib/gurke/runner.rb
CHANGED
@@ -16,10 +16,11 @@ module Gurke
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def match(name, type = :any)
|
19
|
+
return if self.type != :any && self.type != type
|
20
|
+
return if pattern.is_a?(String) && name != pattern
|
19
21
|
match = pattern.match(name)
|
20
22
|
|
21
23
|
return unless match
|
22
|
-
return if self.type != :any && self.type != type
|
23
24
|
|
24
25
|
Match.new(method_name, match.to_a[1..-1])
|
25
26
|
end
|
data/lib/gurke/version.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Gurke::StepDefinition do
|
6
|
+
let(:pattern) { nil }
|
7
|
+
let(:step_definition) { described_class.new pattern }
|
8
|
+
subject { step_definition }
|
9
|
+
|
10
|
+
context '#match' do
|
11
|
+
context 'with regex' do
|
12
|
+
let(:pattern) { /dies ist (ein|zwei) regex/ }
|
13
|
+
|
14
|
+
it { expect(subject.match('dies ist ein regex')).to be_a(Gurke::StepDefinition::Match) }
|
15
|
+
it { expect(subject.match('dies ist zwei regex')).to be_a(Gurke::StepDefinition::Match) }
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'with string' do
|
19
|
+
let(:pattern) { 'a string' }
|
20
|
+
|
21
|
+
it { expect(subject.match('a string')).to be_a(Gurke::StepDefinition::Match) }
|
22
|
+
it { expect(subject.match(' a string')).to be_nil }
|
23
|
+
it { expect(subject.match('a string ')).to be_nil }
|
24
|
+
it { expect(subject.match(' a string ')).to be_nil }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gurke
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1
|
4
|
+
version: 2.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Graichen
|
@@ -74,6 +74,7 @@ executables:
|
|
74
74
|
extensions: []
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
|
+
- CHANGELOG.md
|
77
78
|
- LICENSE.txt
|
78
79
|
- README.md
|
79
80
|
- bin/gurke
|
@@ -81,7 +82,9 @@ files:
|
|
81
82
|
- features/gurke.rb
|
82
83
|
- features/gurke/backtrace_filtering.feature
|
83
84
|
- features/gurke/filter_by_tags.feature
|
85
|
+
- features/gurke/other_reporter.feature
|
84
86
|
- features/gurke/pending_steps.feature
|
87
|
+
- features/gurke/run_specific_directories.feature
|
85
88
|
- features/gurke/run_specific_scenarios.feature
|
86
89
|
- features/gurke/step_specific_definitions.feature
|
87
90
|
- features/support/steps/cli_steps.rb
|
@@ -99,6 +102,7 @@ files:
|
|
99
102
|
- lib/gurke/reporter.rb
|
100
103
|
- lib/gurke/reporters/default_reporter.rb
|
101
104
|
- lib/gurke/reporters/null_reporter.rb
|
105
|
+
- lib/gurke/reporters/team_city_reporter.rb
|
102
106
|
- lib/gurke/rspec.rb
|
103
107
|
- lib/gurke/run_list.rb
|
104
108
|
- lib/gurke/runner.rb
|
@@ -111,6 +115,7 @@ files:
|
|
111
115
|
- spec/gurke/feature_list_spec.rb
|
112
116
|
- spec/gurke/run_list_spec.rb
|
113
117
|
- spec/gurke/scenario_spec.rb
|
118
|
+
- spec/gurke/step_definition_spec.rb
|
114
119
|
- spec/spec_helper.rb
|
115
120
|
homepage: https://github.com/jgraichen/gurke
|
116
121
|
licenses:
|
@@ -141,7 +146,9 @@ test_files:
|
|
141
146
|
- features/gurke.rb
|
142
147
|
- features/gurke/backtrace_filtering.feature
|
143
148
|
- features/gurke/filter_by_tags.feature
|
149
|
+
- features/gurke/other_reporter.feature
|
144
150
|
- features/gurke/pending_steps.feature
|
151
|
+
- features/gurke/run_specific_directories.feature
|
145
152
|
- features/gurke/run_specific_scenarios.feature
|
146
153
|
- features/gurke/step_specific_definitions.feature
|
147
154
|
- features/support/steps/cli_steps.rb
|
@@ -149,5 +156,6 @@ test_files:
|
|
149
156
|
- spec/gurke/feature_list_spec.rb
|
150
157
|
- spec/gurke/run_list_spec.rb
|
151
158
|
- spec/gurke/scenario_spec.rb
|
159
|
+
- spec/gurke/step_definition_spec.rb
|
152
160
|
- spec/spec_helper.rb
|
153
161
|
has_rdoc:
|