what_to_run 0.0.0
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 +7 -0
- data/README.md +67 -0
- data/bin/what_to_run +5 -0
- data/lib/what_to_run.rb +97 -0
- data/lib/what_to_run/minitest.rb +25 -0
- data/lib/what_to_run/rspec.rb +17 -0
- metadata +70 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8627bc44ac70f2e2911589b7a59e1c7bfac33bac
|
4
|
+
data.tar.gz: 26b2e777319a8d6ebcac6e7552aa95a23b8ce94d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: af570365e27f5a2c07e9debf012e7d2962e8c44849ae3fd10a8308de46b30aff32578d4c9fcef809aaf725d9da2aa36e195e0745aa172d3b875b336ebed3552e
|
7
|
+
data.tar.gz: f338f32e7886d66b61f2f816e4176287d2944ba4a7a107e57aad97705f9df3401307837790be6945c9979f82339f46fc4329902b9b4496c97bac3eb6770c8dcc
|
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Regression Test Selection
|
2
|
+
|
3
|
+
This is a demo repository for regression test selection. You will need Ruby 2.3 to use this (which is currently trunk Ruby).
|
4
|
+
|
5
|
+
## Make it go with Minitest
|
6
|
+
|
7
|
+
To try it with Minitest, do:
|
8
|
+
|
9
|
+
```
|
10
|
+
$ COLLECTION=1 ruby -I lib spec/whatever_test.rb
|
11
|
+
```
|
12
|
+
|
13
|
+
This will create the initial coverage information. Then modify `lib/my_thing.rb` so that the diff looks like this:
|
14
|
+
|
15
|
+
```patch
|
16
|
+
diff --git a/lib/my_thing.rb b/lib/my_thing.rb
|
17
|
+
index 806deff..eb057b9 100644
|
18
|
+
--- a/lib/my_thing.rb
|
19
|
+
+++ b/lib/my_thing.rb
|
20
|
+
@@ -4,7 +4,7 @@ class Whatever
|
21
|
+
end
|
22
|
+
|
23
|
+
def bar
|
24
|
+
- "bar #{@foo}"
|
25
|
+
+ raise
|
26
|
+
end
|
27
|
+
|
28
|
+
def baz
|
29
|
+
```
|
30
|
+
|
31
|
+
Now to predict which tests will fail, do this:
|
32
|
+
|
33
|
+
```
|
34
|
+
$ ruby what_to_run.rb
|
35
|
+
```
|
36
|
+
|
37
|
+
## Make it go with RSpec
|
38
|
+
|
39
|
+
To try it with RSpec, do:
|
40
|
+
|
41
|
+
```
|
42
|
+
$ COLLECTION=1 rspec spec/whatever_spec.rb
|
43
|
+
```
|
44
|
+
|
45
|
+
This will create the initial coverage information. Then modify `lib/my_thing.rb` so that the diff looks like this:
|
46
|
+
|
47
|
+
```patch
|
48
|
+
diff --git a/lib/my_thing.rb b/lib/my_thing.rb
|
49
|
+
index 806deff..eb057b9 100644
|
50
|
+
--- a/lib/my_thing.rb
|
51
|
+
+++ b/lib/my_thing.rb
|
52
|
+
@@ -4,7 +4,7 @@ class Whatever
|
53
|
+
end
|
54
|
+
|
55
|
+
def bar
|
56
|
+
- "bar #{@foo}"
|
57
|
+
+ raise
|
58
|
+
end
|
59
|
+
|
60
|
+
def baz
|
61
|
+
```
|
62
|
+
|
63
|
+
Now to predict which tests will fail, do this:
|
64
|
+
|
65
|
+
```
|
66
|
+
$ ruby what_to_run.rb
|
67
|
+
```
|
data/bin/what_to_run
ADDED
data/lib/what_to_run.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'shellwords'
|
3
|
+
require 'rugged'
|
4
|
+
require 'set'
|
5
|
+
|
6
|
+
module WhatToRun
|
7
|
+
extend self
|
8
|
+
|
9
|
+
def predict
|
10
|
+
lines_to_run.inject([]) do |tests, (file, line)|
|
11
|
+
cov_map[File.expand_path(file)][line].each do |desc|
|
12
|
+
tests += Array(desc)
|
13
|
+
end
|
14
|
+
tests
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def lines_to_run
|
19
|
+
repo = Rugged::Repository.new '.'
|
20
|
+
lines_to_run = Set.new
|
21
|
+
|
22
|
+
repo.index.diff.each_patch { |patch|
|
23
|
+
file = patch.delta.old_file[:path]
|
24
|
+
|
25
|
+
patch.each_hunk { |hunk|
|
26
|
+
hunk.each_line { |line|
|
27
|
+
case line.line_origin
|
28
|
+
when :addition
|
29
|
+
lines_to_run << [file, line.new_lineno]
|
30
|
+
when :deletion
|
31
|
+
lines_to_run << [file, line.old_lineno]
|
32
|
+
when :context
|
33
|
+
# do nothing
|
34
|
+
end
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
lines_to_run
|
40
|
+
end
|
41
|
+
|
42
|
+
def diff before, after
|
43
|
+
after.each_with_object({}) do |(file_name,line_cov), res|
|
44
|
+
before_line_cov = before[file_name]
|
45
|
+
|
46
|
+
# skip arrays that are exactly the same
|
47
|
+
next if before_line_cov == line_cov
|
48
|
+
|
49
|
+
# subtract the old coverage from the new coverage
|
50
|
+
cov = line_cov.zip(before_line_cov).map do |line_after, line_before|
|
51
|
+
if line_after
|
52
|
+
line_after - line_before
|
53
|
+
else
|
54
|
+
line_after
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# add the "diffed" coverage to the hash
|
59
|
+
res[file_name] = cov
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def cov_map
|
64
|
+
cov_map = Hash.new { |h, file| h[file] = Hash.new { |i, line| i[line] = [] } }
|
65
|
+
|
66
|
+
File.open('run_log.json') do |f|
|
67
|
+
# Read in the coverage info
|
68
|
+
JSON.parse(f.read).each do |args|
|
69
|
+
if args.length == 4 # for Minitest
|
70
|
+
desc = args.first(2).join('#')
|
71
|
+
else # for RSpec
|
72
|
+
desc = args.first
|
73
|
+
end
|
74
|
+
|
75
|
+
before, after = args.last(2)
|
76
|
+
|
77
|
+
# calculate the per test coverage
|
78
|
+
delta = diff before, after
|
79
|
+
|
80
|
+
delta.each_pair do |file, lines|
|
81
|
+
file_map = cov_map[file]
|
82
|
+
|
83
|
+
lines.each_with_index do |val, i|
|
84
|
+
# skip lines that weren't executed
|
85
|
+
next unless val && val > 0
|
86
|
+
|
87
|
+
# add the test name to the map. Multiple tests can execute the same
|
88
|
+
# line, so we need to use an array.
|
89
|
+
file_map[i + 1] << desc
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
cov_map
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'coverage'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
Coverage.start
|
5
|
+
|
6
|
+
require 'minitest'
|
7
|
+
|
8
|
+
class Minitest::Runnable
|
9
|
+
LOGS = []
|
10
|
+
|
11
|
+
Minitest.after_run {
|
12
|
+
File.open('run_log.json', 'w') { |f| f.write JSON.dump LOGS }
|
13
|
+
}
|
14
|
+
|
15
|
+
class << self
|
16
|
+
alias :old_run_one_method :run_one_method
|
17
|
+
|
18
|
+
def run_one_method klass, method_name, reporter
|
19
|
+
before = Coverage.peek_result
|
20
|
+
old_run_one_method klass, method_name, reporter
|
21
|
+
after = Coverage.peek_result
|
22
|
+
LOGS << [ klass.name, method_name.to_s, before, after ]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'coverage'
|
2
|
+
require 'json'
|
3
|
+
require 'rspec'
|
4
|
+
|
5
|
+
LOGS = []
|
6
|
+
Coverage.start
|
7
|
+
|
8
|
+
RSpec.configuration.after(:suite) {
|
9
|
+
File.open('run_log.json', 'w') { |f| f.write JSON.dump LOGS }
|
10
|
+
}
|
11
|
+
|
12
|
+
RSpec.configuration.around(:example) do |example|
|
13
|
+
before = Coverage.peek_result
|
14
|
+
example.call
|
15
|
+
after = Coverage.peek_result
|
16
|
+
LOGS << [ example.full_description, before, after ]
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: what_to_run
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aaron Patterson
|
8
|
+
- Dyego Costa
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-03-30 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rugged
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0.21'
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.21.0
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
requirements:
|
28
|
+
- - "~>"
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0.21'
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.21.0
|
34
|
+
description: Predict which tests are likely to fail after you’ve changed the code
|
35
|
+
email: dyego@dyegocosta.com
|
36
|
+
executables:
|
37
|
+
- what_to_run
|
38
|
+
extensions: []
|
39
|
+
extra_rdoc_files: []
|
40
|
+
files:
|
41
|
+
- README.md
|
42
|
+
- bin/what_to_run
|
43
|
+
- lib/what_to_run.rb
|
44
|
+
- lib/what_to_run/minitest.rb
|
45
|
+
- lib/what_to_run/rspec.rb
|
46
|
+
homepage: https://github.com/DyegoCosta/what_to_run
|
47
|
+
licenses:
|
48
|
+
- MIT
|
49
|
+
metadata: {}
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
requirements: []
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 2.4.6
|
67
|
+
signing_key:
|
68
|
+
specification_version: 4
|
69
|
+
summary: Regression test selection
|
70
|
+
test_files: []
|