rspec_log_formatter 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +20 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/rspec_log_formatter/analysis/analyzer.rb +38 -0
- data/lib/rspec_log_formatter/analysis/pretty_printer.rb +19 -0
- data/lib/rspec_log_formatter/analysis/result.rb +25 -0
- data/lib/rspec_log_formatter/analysis/score.rb +29 -0
- data/lib/rspec_log_formatter/formatter.rb +69 -0
- data/lib/rspec_log_formatter/version.rb +3 -0
- data/lib/rspec_log_formatter.rb +4 -0
- data/rspec_log_formatter.gemspec +25 -0
- data/spec/fixtures/fail_history_analyzer.rspec.history +70 -0
- data/spec/fixtures/test_was_flaky_then_fixed.history +10 -0
- data/spec/fixtures/varying_flakiness.history +9 -0
- data/spec/lib/rspec_log_analyzer/analysis/analyzer_spec.rb +41 -0
- data/spec/lib/rspec_log_analyzer/analysis/pretty_printer_spec.rb +56 -0
- data/spec/lib/rspec_log_analyzer/formatter_spec.rb +36 -0
- data/spec/spec_helper.rb +10 -0
- metadata +129 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MGJmODJlZTJkMzNjOGY5OWRjNDRjNmIxYzUyMTM0ZWEyY2MxN2U0Ng==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YzQ3MDllYzM1MmQ5NmJjNzJkYmVlMjE0ZjkxY2U1ZmFiZjg1ZDYxMw==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MzBjMWQ3NGZjMzZmODM1M2VhY2ZmYjA3MGE0NjQzYTg5Zjg1YjEwNTA3YjIy
|
10
|
+
ZDhmMDZlNDBmYTc5Y2ZjZjc1Njg3MjMwYzQ1ZjRlNmJhOTFmZTI5NzQwZDlj
|
11
|
+
MDA0OGQ5ODJjNmQxZWU1NDZlOTJkM2Q4NTU2YzFlNGJiMmQ0ZGQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
Mzc5NWQ5MzEyZmFiMDE0ODZjODEyZTkxYWQ4MWQ3ZDRjYmUzNDI5ODY3YjVm
|
14
|
+
NTY2ZTg1ZjJkZWY1YjczMGQyMWE3OTE4M2Q4YjJjMDA4YTdjNTM0Nzg3YjRk
|
15
|
+
MjdhMjgzZjM4Y2JkY2MwNjE2OWFiYzQwNWIwM2M2YzAyNjE4MTQ=
|
data/.gitignore
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rspec_log_formatter
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Serguei Filimonov
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# RspecLogFormatter
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'rspec_log_formatter'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install rspec_log_formatter
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it ( http://github.com/<my-github-username>/rspec_log_formatter/fork )
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module RspecLogFormatter
|
4
|
+
module Analysis
|
5
|
+
class Analyzer
|
6
|
+
def analyze(filepath, options = {})
|
7
|
+
window = options[:last_builds]
|
8
|
+
|
9
|
+
build_numbers = []
|
10
|
+
results = File.open(filepath).each_line.map do |line|
|
11
|
+
result = Result.new(*CSV.parse_line(line, col_sep: "\t").first(7))
|
12
|
+
build_numbers << result.build_number
|
13
|
+
result
|
14
|
+
end
|
15
|
+
build_numbers.uniq!.sort!
|
16
|
+
|
17
|
+
|
18
|
+
scores = []
|
19
|
+
results.group_by(&:description).each do |description, results|
|
20
|
+
score = Score.new(description)
|
21
|
+
|
22
|
+
results.group_by(&:build_number).each do |build_number, results|
|
23
|
+
next if (window && !build_numbers.last(window).include?(build_number))
|
24
|
+
next if results.all?(&:failure?) #not flaky
|
25
|
+
|
26
|
+
|
27
|
+
score.runs += results.count
|
28
|
+
score.failures += results.count(&:failure?)
|
29
|
+
score.failure_messages += results.select(&:failure?).map { |r| "#{r.klass}\n #{r.message}" }
|
30
|
+
end
|
31
|
+
scores << score if score.runs > 0
|
32
|
+
end
|
33
|
+
|
34
|
+
scores.sort.map(&:as_hash)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RspecLogFormatter
|
2
|
+
module Analysis
|
3
|
+
class PrettyPrinter
|
4
|
+
def initialize(results)
|
5
|
+
@results = results
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
results = @results.first(10)
|
10
|
+
header = "Top #{results.count} flakiest examples\n"
|
11
|
+
header + results.each_with_index.map do |result, i|
|
12
|
+
title = " #{i+1}) #{result[:description]} -- #{result[:percent]}%"
|
13
|
+
failure_messages = result[:failure_messages].map { |fm| " * #{fm}" }.join("\n")
|
14
|
+
title + "\n" + failure_messages
|
15
|
+
end.join("\n")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RspecLogFormatter
|
2
|
+
module Analysis
|
3
|
+
class Result
|
4
|
+
def initialize(build_number, time, outcome, description, spec_path, message=nil, klass=nil)
|
5
|
+
@build_number = build_number
|
6
|
+
@description = description
|
7
|
+
@outcome = outcome
|
8
|
+
@spec_path = spec_path
|
9
|
+
@message = message
|
10
|
+
@klass = klass
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :build_number, :description
|
14
|
+
attr_reader :message, :klass
|
15
|
+
|
16
|
+
def failure?
|
17
|
+
@outcome == "failed"
|
18
|
+
end
|
19
|
+
|
20
|
+
def success?
|
21
|
+
@outcome == "passed"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module RspecLogFormatter
|
2
|
+
module Analysis
|
3
|
+
class Score
|
4
|
+
def initialize(desc)
|
5
|
+
@description = desc
|
6
|
+
@runs = 0
|
7
|
+
@failures = 0
|
8
|
+
@failure_messages = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def percent
|
12
|
+
100 * @failures.to_f/@runs
|
13
|
+
end
|
14
|
+
|
15
|
+
def <=>(other)
|
16
|
+
other.percent <=> percent
|
17
|
+
end
|
18
|
+
|
19
|
+
def as_hash
|
20
|
+
{
|
21
|
+
description: @description,
|
22
|
+
percent: percent,
|
23
|
+
failure_messages: failure_messages,
|
24
|
+
}
|
25
|
+
end
|
26
|
+
attr_accessor :runs, :failures, :failure_messages
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "csv"
|
2
|
+
require "rspec/core/formatters/base_formatter"
|
3
|
+
|
4
|
+
module RspecLogFormatter
|
5
|
+
class Formatter < RSpec::Core::Formatters::BaseFormatter
|
6
|
+
FILENAME = "rspec.history"
|
7
|
+
|
8
|
+
class Config
|
9
|
+
def clock=(clock)
|
10
|
+
@clock = clock
|
11
|
+
end
|
12
|
+
def clock
|
13
|
+
@clock ||= Time
|
14
|
+
@clock
|
15
|
+
end
|
16
|
+
end
|
17
|
+
CONFIG = Config.new
|
18
|
+
|
19
|
+
def initialize(*args)
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.analyze(filepath)
|
24
|
+
Analysis::Analyzer.new.analyze(filepath)
|
25
|
+
end
|
26
|
+
|
27
|
+
def example_started(example)
|
28
|
+
@clock_start = clock.now
|
29
|
+
end
|
30
|
+
|
31
|
+
def example_passed(example)
|
32
|
+
record("passed", example, clock.now, clock.now - @clock_start)
|
33
|
+
end
|
34
|
+
|
35
|
+
def example_failed(example)
|
36
|
+
record("failed", example, clock.now, clock.now - @clock_start, example.exception)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def clock
|
42
|
+
CONFIG.clock
|
43
|
+
end
|
44
|
+
|
45
|
+
def record(outcome, example, time, duration, exception=nil)
|
46
|
+
if exception
|
47
|
+
exception_data = [
|
48
|
+
exception.message.gsub(/\r|\n|\t/, " "),
|
49
|
+
exception.class,
|
50
|
+
]
|
51
|
+
else
|
52
|
+
exception_data = [nil,nil]
|
53
|
+
end
|
54
|
+
|
55
|
+
example_data = [
|
56
|
+
ENV["BUILD_NUMBER"],
|
57
|
+
time,
|
58
|
+
outcome,
|
59
|
+
example.full_description.to_s.gsub(/\r|\n|\t/, " "),
|
60
|
+
example.file_path,
|
61
|
+
] + exception_data + [duration]
|
62
|
+
|
63
|
+
File.open(FILENAME, "a") do |f|
|
64
|
+
f.puts example_data.to_csv(col_sep: "\t")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rspec_log_formatter/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rspec_log_formatter"
|
8
|
+
spec.version = RspecLogFormatter::VERSION
|
9
|
+
spec.authors = ["Serguei Filimonov"]
|
10
|
+
spec.email = ["sfilimonov@pivotallabs.com"]
|
11
|
+
spec.summary = "Logs the outcomes of the tests to a file"
|
12
|
+
spec.description = "Logs the outcomes of the tests to a file"
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "pry"
|
25
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
2014-01-21 16:08:25 -0800 passed description0 ./spec/m1k1_spec.rb
|
2
|
+
2014-01-21 16:08:25 -0800 passed description1 ./spec/m1k1_spec.rb
|
3
|
+
2014-01-21 16:08:25 -0800 passed description2 ./spec/m1k1_spec.rb
|
4
|
+
2014-01-21 16:08:25 -0800 passed description3 ./spec/m1k1_spec.rb
|
5
|
+
2014-01-21 16:08:25 -0800 passed description4 ./spec/m1k1_spec.rb
|
6
|
+
2014-01-21 16:08:25 -0800 passed description5 ./spec/m1k1_spec.rb
|
7
|
+
2014-01-21 16:08:25 -0800 passed description6 ./spec/m1k1_spec.rb
|
8
|
+
2014-01-21 16:08:25 -0800 passed description7 ./spec/m1k1_spec.rb
|
9
|
+
2014-01-21 16:08:25 -0800 passed description8 ./spec/m1k1_spec.rb
|
10
|
+
2014-01-21 16:08:25 -0800 passed description9 ./spec/m1k1_spec.rb
|
11
|
+
2014-01-22 16:08:25 -0800 failed description0 ./spec/m1k1_spec.rb msg10 ec10
|
12
|
+
2014-01-22 16:08:25 -0800 passed description1 ./spec/m1k1_spec.rb
|
13
|
+
2014-01-22 16:08:25 -0800 passed description2 ./spec/m1k1_spec.rb
|
14
|
+
2014-01-22 16:08:25 -0800 passed description3 ./spec/m1k1_spec.rb
|
15
|
+
2014-01-22 16:08:25 -0800 passed description4 ./spec/m1k1_spec.rb
|
16
|
+
2014-01-22 16:08:25 -0800 passed description5 ./spec/m1k1_spec.rb
|
17
|
+
2014-01-22 16:08:25 -0800 passed description6 ./spec/m1k1_spec.rb
|
18
|
+
2014-01-22 16:08:25 -0800 passed description7 ./spec/m1k1_spec.rb
|
19
|
+
2014-01-22 16:08:25 -0800 passed description8 ./spec/m1k1_spec.rb
|
20
|
+
2014-01-22 16:08:25 -0800 passed description9 ./spec/m1k1_spec.rb
|
21
|
+
2014-01-23 16:08:25 -0800 failed description0 ./spec/m1k1_spec.rb msg20 ec20
|
22
|
+
2014-01-23 16:08:25 -0800 failed description1 ./spec/m1k1_spec.rb msg21 ec21
|
23
|
+
2014-01-23 16:08:25 -0800 passed description2 ./spec/m1k1_spec.rb
|
24
|
+
2014-01-23 16:08:25 -0800 passed description3 ./spec/m1k1_spec.rb
|
25
|
+
2014-01-23 16:08:25 -0800 passed description4 ./spec/m1k1_spec.rb
|
26
|
+
2014-01-23 16:08:25 -0800 passed description5 ./spec/m1k1_spec.rb
|
27
|
+
2014-01-23 16:08:25 -0800 passed description6 ./spec/m1k1_spec.rb
|
28
|
+
2014-01-23 16:08:25 -0800 passed description7 ./spec/m1k1_spec.rb
|
29
|
+
2014-01-23 16:08:25 -0800 passed description8 ./spec/m1k1_spec.rb
|
30
|
+
2014-01-23 16:08:25 -0800 passed description9 ./spec/m1k1_spec.rb
|
31
|
+
2014-01-24 16:08:25 -0800 failed description0 ./spec/m1k1_spec.rb msg30 ec30
|
32
|
+
2014-01-24 16:08:25 -0800 failed description1 ./spec/m1k1_spec.rb msg31 ec31
|
33
|
+
2014-01-24 16:08:25 -0800 failed description2 ./spec/m1k1_spec.rb msg32 ec32
|
34
|
+
2014-01-24 16:08:25 -0800 passed description3 ./spec/m1k1_spec.rb
|
35
|
+
2014-01-24 16:08:25 -0800 passed description4 ./spec/m1k1_spec.rb
|
36
|
+
2014-01-24 16:08:25 -0800 passed description5 ./spec/m1k1_spec.rb
|
37
|
+
2014-01-24 16:08:25 -0800 passed description6 ./spec/m1k1_spec.rb
|
38
|
+
2014-01-24 16:08:25 -0800 passed description7 ./spec/m1k1_spec.rb
|
39
|
+
2014-01-24 16:08:25 -0800 passed description8 ./spec/m1k1_spec.rb
|
40
|
+
2014-01-24 16:08:25 -0800 passed description9 ./spec/m1k1_spec.rb
|
41
|
+
2014-01-25 16:08:25 -0800 failed description0 ./spec/m1k1_spec.rb msg40 ec40
|
42
|
+
2014-01-25 16:08:25 -0800 failed description1 ./spec/m1k1_spec.rb msg41 ec41
|
43
|
+
2014-01-25 16:08:25 -0800 failed description2 ./spec/m1k1_spec.rb msg42 ec42
|
44
|
+
2014-01-25 16:08:25 -0800 failed description3 ./spec/m1k1_spec.rb msg43 ec43
|
45
|
+
2014-01-25 16:08:25 -0800 passed description4 ./spec/m1k1_spec.rb
|
46
|
+
2014-01-25 16:08:25 -0800 passed description5 ./spec/m1k1_spec.rb
|
47
|
+
2014-01-25 16:08:25 -0800 passed description6 ./spec/m1k1_spec.rb
|
48
|
+
2014-01-25 16:08:25 -0800 passed description7 ./spec/m1k1_spec.rb
|
49
|
+
2014-01-25 16:08:25 -0800 passed description8 ./spec/m1k1_spec.rb
|
50
|
+
2014-01-25 16:08:25 -0800 passed description9 ./spec/m1k1_spec.rb
|
51
|
+
2014-01-26 16:08:25 -0800 failed description0 ./spec/m1k1_spec.rb msg50 ec50
|
52
|
+
2014-01-26 16:08:25 -0800 failed description1 ./spec/m1k1_spec.rb msg51 ec51
|
53
|
+
2014-01-26 16:08:25 -0800 failed description2 ./spec/m1k1_spec.rb msg52 ec52
|
54
|
+
2014-01-26 16:08:25 -0800 failed description3 ./spec/m1k1_spec.rb msg53 ec53
|
55
|
+
2014-01-26 16:08:25 -0800 failed description4 ./spec/m1k1_spec.rb msg54 ec54
|
56
|
+
2014-01-26 16:08:25 -0800 passed description5 ./spec/m1k1_spec.rb
|
57
|
+
2014-01-26 16:08:25 -0800 passed description6 ./spec/m1k1_spec.rb
|
58
|
+
2014-01-26 16:08:25 -0800 passed description7 ./spec/m1k1_spec.rb
|
59
|
+
2014-01-26 16:08:25 -0800 passed description8 ./spec/m1k1_spec.rb
|
60
|
+
2014-01-26 16:08:25 -0800 passed description9 ./spec/m1k1_spec.rb
|
61
|
+
2014-01-27 16:08:25 -0800 failed description0 ./spec/m1k1_spec.rb msg60 ec60
|
62
|
+
2014-01-27 16:08:25 -0800 failed description1 ./spec/m1k1_spec.rb msg61 ec61
|
63
|
+
2014-01-27 16:08:25 -0800 failed description2 ./spec/m1k1_spec.rb msg62 ec62
|
64
|
+
2014-01-27 16:08:25 -0800 failed description3 ./spec/m1k1_spec.rb msg63 ec63
|
65
|
+
2014-01-27 16:08:25 -0800 failed description4 ./spec/m1k1_spec.rb msg64 ec64
|
66
|
+
2014-01-27 16:08:25 -0800 failed description5 ./spec/m1k1_spec.rb msg65 ec65
|
67
|
+
2014-01-27 16:08:25 -0800 failed description6 ./spec/m1k1_spec.rb msg66 ec66
|
68
|
+
2014-01-27 16:08:25 -0800 failed description7 ./spec/m1k1_spec.rb msg67 ec67
|
69
|
+
2014-01-27 16:08:25 -0800 failed description8 ./spec/m1k1_spec.rb msg68 ec68
|
70
|
+
2014-01-27 16:08:25 -0800 failed description9 ./spec/m1k1_spec.rb msg69 ec69
|
@@ -0,0 +1,10 @@
|
|
1
|
+
1 2014-01-21 16:08:25 -0800 failed desc ./spec/m1k1_spec.rb msg10 ec10
|
2
|
+
1 2014-01-21 16:08:25 -0800 passed desc ./spec/m1k1_spec.rb
|
3
|
+
2 2014-01-21 16:08:25 -0800 failed desc ./spec/m1k1_spec.rb msg10 ec10
|
4
|
+
2 2014-01-21 16:08:25 -0800 passed desc ./spec/m1k1_spec.rb
|
5
|
+
3 2014-01-21 16:08:25 -0800 failed desc ./spec/m1k1_spec.rb msg10 ec10
|
6
|
+
3 2014-01-21 16:08:25 -0800 passed desc ./spec/m1k1_spec.rb
|
7
|
+
4 2014-01-21 16:08:25 -0800 passed desc ./spec/m1k1_spec.rb
|
8
|
+
5 2014-01-21 16:08:25 -0800 passed desc ./spec/m1k1_spec.rb
|
9
|
+
6 2014-01-21 16:08:25 -0800 passed desc ./spec/m1k1_spec.rb
|
10
|
+
7 2014-01-21 16:08:25 -0800 passed desc ./spec/m1k1_spec.rb
|
@@ -0,0 +1,9 @@
|
|
1
|
+
1 2014-01-21 16:08:25 -0800 failed desc1 ./spec/m1k1_spec.rb msg10 ec10
|
2
|
+
1 2014-01-21 16:08:25 -0800 passed desc1 ./spec/m1k1_spec.rb
|
3
|
+
1 2014-01-21 16:08:25 -0800 failed desc3 ./spec/m1k1_spec.rb msg10 ec10
|
4
|
+
1 2014-01-21 16:08:25 -0800 failed desc3 ./spec/m1k1_spec.rb msg10 ec10
|
5
|
+
1 2014-01-21 16:08:25 -0800 failed desc3 ./spec/m1k1_spec.rb msg10 ec10
|
6
|
+
1 2014-01-21 16:08:25 -0800 passed desc3 ./spec/m1k1_spec.rb
|
7
|
+
1 2014-01-21 16:08:25 -0800 failed desc2 ./spec/m1k1_spec.rb msg10 ec10
|
8
|
+
1 2014-01-21 16:08:25 -0800 failed desc2 ./spec/m1k1_spec.rb msg10 ec10
|
9
|
+
1 2014-01-21 16:08:25 -0800 passed desc2 ./spec/m1k1_spec.rb
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe RspecLogFormatter::Analysis::Analyzer do
|
4
|
+
it "sorts the parsed results by failure percentage" do
|
5
|
+
filepath = File.expand_path("../../../../fixtures/varying_flakiness.history", __FILE__)
|
6
|
+
described_class.new.analyze(filepath).map{|r| r[:percent] }.should == [
|
7
|
+
75.0, 100*2.0/3.0, 50.0
|
8
|
+
]
|
9
|
+
end
|
10
|
+
|
11
|
+
it "works" do
|
12
|
+
filepath = File.expand_path("../../../../fixtures/fail_history_analyzer.rspec.history", __FILE__)
|
13
|
+
described_class.new.analyze(filepath).first.should == {
|
14
|
+
description: "description0",
|
15
|
+
percent: 85.71428571428571,
|
16
|
+
failure_messages: [
|
17
|
+
"ec10\n msg10",
|
18
|
+
"ec20\n msg20",
|
19
|
+
"ec30\n msg30",
|
20
|
+
"ec40\n msg40",
|
21
|
+
"ec50\n msg50",
|
22
|
+
"ec60\n msg60",
|
23
|
+
]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
it "can analyze only a window of builds" do
|
28
|
+
filepath = File.expand_path("../../../../fixtures/test_was_flaky_then_fixed.history", __FILE__)
|
29
|
+
subject.analyze(filepath, last_builds: 7).first.should == {
|
30
|
+
description: "desc",
|
31
|
+
percent: 30.0,
|
32
|
+
failure_messages: ["ec10\n msg10", "ec10\n msg10", "ec10\n msg10"]
|
33
|
+
}
|
34
|
+
subject.analyze(filepath, last_builds: 4).first.should == {
|
35
|
+
description: "desc",
|
36
|
+
percent: 0.0,
|
37
|
+
failure_messages: []
|
38
|
+
}
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RspecLogFormatter::Analysis::PrettyPrinter do
|
4
|
+
it "pretty prints the results of an analysis" do
|
5
|
+
results = [{
|
6
|
+
description: "I fail a lot.",
|
7
|
+
percent: 99,
|
8
|
+
failure_messages: ["I'm a total failure."]
|
9
|
+
},{
|
10
|
+
description: "I fail often.",
|
11
|
+
percent: 70,
|
12
|
+
failure_messages: ["I am a failure message.", "I'm another failure message."]
|
13
|
+
}]
|
14
|
+
|
15
|
+
described_class.new(results).to_s.should == <<-TEXT.strip
|
16
|
+
Top 2 flakiest examples
|
17
|
+
1) I fail a lot. -- 99%
|
18
|
+
* I'm a total failure.
|
19
|
+
2) I fail often. -- 70%
|
20
|
+
* I am a failure message.
|
21
|
+
* I'm another failure message.
|
22
|
+
TEXT
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when there are more than 10 results" do
|
26
|
+
it "only prints the top 10" do
|
27
|
+
results = (1..20).map do |i|
|
28
|
+
{description: "hi#{i}", percent: 1, failure_messages: ["bye#{i}"]}
|
29
|
+
end
|
30
|
+
|
31
|
+
described_class.new(results).to_s.should == <<-TEXT.strip
|
32
|
+
Top 10 flakiest examples
|
33
|
+
1) hi1 -- 1%
|
34
|
+
* bye1
|
35
|
+
2) hi2 -- 1%
|
36
|
+
* bye2
|
37
|
+
3) hi3 -- 1%
|
38
|
+
* bye3
|
39
|
+
4) hi4 -- 1%
|
40
|
+
* bye4
|
41
|
+
5) hi5 -- 1%
|
42
|
+
* bye5
|
43
|
+
6) hi6 -- 1%
|
44
|
+
* bye6
|
45
|
+
7) hi7 -- 1%
|
46
|
+
* bye7
|
47
|
+
8) hi8 -- 1%
|
48
|
+
* bye8
|
49
|
+
9) hi9 -- 1%
|
50
|
+
* bye9
|
51
|
+
10) hi10 -- 1%
|
52
|
+
* bye10
|
53
|
+
TEXT
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RspecLogFormatter::Formatter do
|
4
|
+
|
5
|
+
def make_example(opts={})
|
6
|
+
@count ||= 0; @count += 1
|
7
|
+
double({
|
8
|
+
full_description: "description_#{@count}",
|
9
|
+
file_path: "path_#{@count}"
|
10
|
+
}.merge(opts))
|
11
|
+
end
|
12
|
+
|
13
|
+
it "works" do
|
14
|
+
failed_example = make_example(exception: Exception.new("Error"))
|
15
|
+
passed_example = make_example(exception: nil)
|
16
|
+
time = Time.parse("2014-02-06 16:01:10")
|
17
|
+
clock = double(now: time)
|
18
|
+
RspecLogFormatter::Formatter::CONFIG.clock = clock
|
19
|
+
|
20
|
+
formatter = RspecLogFormatter::Formatter.new(StringIO.new)
|
21
|
+
formatter.example_started(failed_example)
|
22
|
+
#clock.stub(now: time + 5)
|
23
|
+
RspecLogFormatter::Formatter::CONFIG.clock = double(now: time + 5)
|
24
|
+
formatter.example_failed(failed_example)
|
25
|
+
|
26
|
+
formatter.example_started(passed_example)
|
27
|
+
#clock.stub(:now, time + 8)
|
28
|
+
RspecLogFormatter::Formatter::CONFIG.clock = double(now: time + 8)
|
29
|
+
formatter.example_passed(passed_example)
|
30
|
+
formatter.dump_summary(1,2,3,4)
|
31
|
+
File.open('rspec.history').readlines.should == [
|
32
|
+
"\t2014-02-06 16:01:15 -0800\tfailed\tdescription_1\tpath_1\tError\tException\t5.0\n",
|
33
|
+
"\t2014-02-06 16:01:18 -0800\tpassed\tdescription_2\tpath_2\t\t\t3.0\n",
|
34
|
+
]
|
35
|
+
end
|
36
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec_log_formatter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Serguei Filimonov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Logs the outcomes of the tests to a file
|
70
|
+
email:
|
71
|
+
- sfilimonov@pivotallabs.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- .ruby-gemset
|
78
|
+
- .ruby-version
|
79
|
+
- Gemfile
|
80
|
+
- LICENSE.txt
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- lib/rspec_log_formatter.rb
|
84
|
+
- lib/rspec_log_formatter/analysis/analyzer.rb
|
85
|
+
- lib/rspec_log_formatter/analysis/pretty_printer.rb
|
86
|
+
- lib/rspec_log_formatter/analysis/result.rb
|
87
|
+
- lib/rspec_log_formatter/analysis/score.rb
|
88
|
+
- lib/rspec_log_formatter/formatter.rb
|
89
|
+
- lib/rspec_log_formatter/version.rb
|
90
|
+
- rspec_log_formatter.gemspec
|
91
|
+
- spec/fixtures/fail_history_analyzer.rspec.history
|
92
|
+
- spec/fixtures/test_was_flaky_then_fixed.history
|
93
|
+
- spec/fixtures/varying_flakiness.history
|
94
|
+
- spec/lib/rspec_log_analyzer/analysis/analyzer_spec.rb
|
95
|
+
- spec/lib/rspec_log_analyzer/analysis/pretty_printer_spec.rb
|
96
|
+
- spec/lib/rspec_log_analyzer/formatter_spec.rb
|
97
|
+
- spec/spec_helper.rb
|
98
|
+
homepage: ''
|
99
|
+
licenses:
|
100
|
+
- MIT
|
101
|
+
metadata: {}
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ! '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 2.2.2
|
119
|
+
signing_key:
|
120
|
+
specification_version: 4
|
121
|
+
summary: Logs the outcomes of the tests to a file
|
122
|
+
test_files:
|
123
|
+
- spec/fixtures/fail_history_analyzer.rspec.history
|
124
|
+
- spec/fixtures/test_was_flaky_then_fixed.history
|
125
|
+
- spec/fixtures/varying_flakiness.history
|
126
|
+
- spec/lib/rspec_log_analyzer/analysis/analyzer_spec.rb
|
127
|
+
- spec/lib/rspec_log_analyzer/analysis/pretty_printer_spec.rb
|
128
|
+
- spec/lib/rspec_log_analyzer/formatter_spec.rb
|
129
|
+
- spec/spec_helper.rb
|