minitest-heat 0.0.10 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +6 -6
- data/README.md +48 -13
- data/examples/exceptions.png +0 -0
- data/examples/failures.png +0 -0
- data/examples/map.png +0 -0
- data/examples/markers.png +0 -0
- data/examples/skips.png +0 -0
- data/examples/slows.png +0 -0
- data/lib/minitest/heat/backtrace/line_parser.rb +25 -0
- data/lib/minitest/heat/backtrace.rb +21 -59
- data/lib/minitest/heat/hit.rb +18 -6
- data/lib/minitest/heat/issue.rb +35 -17
- data/lib/minitest/heat/location.rb +113 -132
- data/lib/minitest/heat/locations.rb +105 -0
- data/lib/minitest/heat/map.rb +3 -4
- data/lib/minitest/heat/output/backtrace.rb +88 -70
- data/lib/minitest/heat/output/issue.rb +56 -83
- data/lib/minitest/heat/output/map.rb +116 -28
- data/lib/minitest/heat/output.rb +27 -13
- data/lib/minitest/heat/results.rb +11 -6
- data/lib/minitest/heat/source.rb +1 -1
- data/lib/minitest/heat/version.rb +1 -1
- data/lib/minitest/heat.rb +1 -0
- data/lib/minitest/heat_plugin.rb +1 -1
- data/lib/minitest/heat_reporter.rb +13 -6
- metadata +11 -4
- data/lib/minitest/heat/backtrace/line.rb +0 -118
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4009f20d5e5d4d92d8e0796e853df4da059e3ec7a6b49cae98a8ce71352316fd
|
4
|
+
data.tar.gz: adf5692ab8af5f08ec97607f43ac8f454ad91fb62d15d9f867ee354d920a7a45
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e0d422fbc88d79598464f1640ffb7b6ea3e8ab7324e85f9a059a61f1d14e6c8792f277525dadf6cf81ee493168708dd0eb1a3f9b836b7efd0af3e73b959f25b
|
7
|
+
data.tar.gz: dfa2aa6267e1c026da29b93e1e7ab73f4a1fc65d9d1132228efff315622b742ebe40074eec7a639e6246b7bad27f14a31feee647c9c1274b77d8a57b8d8ed22b
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
minitest-heat (0.0.
|
4
|
+
minitest-heat (0.0.14)
|
5
5
|
minitest
|
6
6
|
|
7
7
|
GEM
|
@@ -10,7 +10,7 @@ GEM
|
|
10
10
|
ast (2.4.2)
|
11
11
|
awesome_print (1.9.2)
|
12
12
|
coderay (1.1.3)
|
13
|
-
dead_end (
|
13
|
+
dead_end (3.0.2)
|
14
14
|
docile (1.4.0)
|
15
15
|
method_source (1.0.0)
|
16
16
|
minitest (5.14.4)
|
@@ -24,7 +24,7 @@ GEM
|
|
24
24
|
rake (12.3.3)
|
25
25
|
regexp_parser (2.1.1)
|
26
26
|
rexml (3.2.5)
|
27
|
-
rubocop (1.22.
|
27
|
+
rubocop (1.22.3)
|
28
28
|
parallel (~> 1.10)
|
29
29
|
parser (>= 3.0.0.0)
|
30
30
|
rainbow (>= 2.2.2, < 4.0)
|
@@ -33,9 +33,9 @@ GEM
|
|
33
33
|
rubocop-ast (>= 1.12.0, < 2.0)
|
34
34
|
ruby-progressbar (~> 1.7)
|
35
35
|
unicode-display_width (>= 1.4.0, < 3.0)
|
36
|
-
rubocop-ast (1.
|
36
|
+
rubocop-ast (1.13.0)
|
37
37
|
parser (>= 3.0.1.1)
|
38
|
-
rubocop-minitest (0.15.
|
38
|
+
rubocop-minitest (0.15.2)
|
39
39
|
rubocop (>= 0.90, < 2.0)
|
40
40
|
rubocop-rake (0.6.0)
|
41
41
|
rubocop (~> 1.0)
|
@@ -64,4 +64,4 @@ DEPENDENCIES
|
|
64
64
|
simplecov
|
65
65
|
|
66
66
|
BUNDLED WITH
|
67
|
-
2.
|
67
|
+
2.2.30
|
data/README.md
CHANGED
@@ -1,12 +1,41 @@
|
|
1
1
|
# Minitest::Heat
|
2
|
-
|
2
|
+
Minitest::Heat helps you identify problems faster so you can more efficiently resolve test failures. It does this through a few different methods.
|
3
3
|
|
4
|
-
|
4
|
+
It collects failures and inspects backtraces to identify patterns and provide a heat map summary of the files and line numbers that most frequently appear to be the causes of issues.
|
5
5
|
|
6
|
-
|
6
|
+
![Example Heat Map Displayed by Minitest Heat](https://raw.githubusercontent.com/garrettdimon/minitest-heat/main/examples/map.png)
|
7
7
|
|
8
|
-
|
8
|
+
It suppresses less critical issues like skips or slows when there are legitimate failures. It won't display information about slow tests unless all tests are passing (meaning no errors, failures, or skips)
|
9
|
+
|
10
|
+
It presents failures differently depending on the context of failure. For instance, it treats exceptions differently based on whether they arose directly from a test or from source code. It also treats extremely slow tests differently from moderately slow tests.
|
11
|
+
|
12
|
+
Markers get some nuance so that slow tests receive different markers than standard passing tests, and exception-triggered failures get different markers for source-code triggered exceptions (E) and test-triggered exceptions ('B' for 'Broken Test').
|
13
|
+
|
14
|
+
![Example Markers Displayed by Minitest Heat](https://raw.githubusercontent.com/garrettdimon/minitest-heat/main/examples/markers.png)
|
15
|
+
|
16
|
+
It also formats the failure details and backtraces to make them more scannable by emphasizing the project-relates lines from the backtrace.
|
17
|
+
|
18
|
+
It intelligently recognizes when an exception was raised from a test defintion vs. when an exception is genuinely triggered from the source code in order to help focus on fixing deeper exceptions first.
|
19
|
+
|
20
|
+
![Example Exceptions Displayed by Minitest Heat](https://raw.githubusercontent.com/garrettdimon/minitest-heat/main/examples/exceptions.png)
|
21
|
+
|
22
|
+
Failures are displayed ina fairly predictable manner but formatted to show the source code from the test so you can see the assertion that failed in addition to the summary of values that didn't satisfy the assertion.
|
23
|
+
|
24
|
+
![Example Failures Displayed by Minitest Heat](https://raw.githubusercontent.com/garrettdimon/minitest-heat/main/examples/failures.png)
|
25
|
+
|
26
|
+
Skipped tests are displayed in a simple manner as well so that it's easy to see the source of the skipped test as well as the reason it was skipped.
|
27
|
+
|
28
|
+
![Example Skips Displayed by Minitest Heat](https://raw.githubusercontent.com/garrettdimon/minitest-heat/main/examples/skips.png)
|
29
|
+
|
30
|
+
Slow tests get slightly more informative labels to indicate that they did pass, but they could use performance improvements. Tests that are particularly slow are called out with a little more emphasis so it's easier to focus on really slow tests first as they frequently represent the most potential for performance gains.
|
9
31
|
|
32
|
+
![Example Slows Displayed by Minitest Heat](https://raw.githubusercontent.com/garrettdimon/minitest-heat/main/examples/slows.png)
|
33
|
+
|
34
|
+
It also always displays the most significant issues at the bottom of the list in order to reduce the need to scroll up through the test failures. As you fix issues, the list becomes shorter, and the less significant issues will make there way to the bottom and be visible without scrolling.
|
35
|
+
|
36
|
+
For some additional insight about priorities and how it works, this [Twitter thread](https://twitter.com/garrettdimon/status/1432703746526560266) is currently the best place to start.
|
37
|
+
|
38
|
+
## Installation
|
10
39
|
Add this line to your application's Gemfile:
|
11
40
|
|
12
41
|
```ruby
|
@@ -27,27 +56,33 @@ And depending on your usage, you may need to require Minitest Heat in your test
|
|
27
56
|
require 'minitest/heat'
|
28
57
|
```
|
29
58
|
|
30
|
-
##
|
31
|
-
|
32
|
-
**Important:** In its current state, `Minitest::Heat` replaces any other reporter plugins you may have. Long-term, it should play nicer with other reporters, but during the initial heavy development cycle, it's been easier to have a high confidence that other reporters aren't the source of unexpected behavior.
|
33
|
-
|
34
|
-
Otherwise, once it's bundled and added to your `test_helper`, it shold "just work" whenever you run your test suite.
|
59
|
+
## Configuration
|
60
|
+
Minitest Heat doesn't currently offer a significant set of configuration options, but it will eventually support customizing the thresholds for "Slow" and "Painfully Slow". By default, it considers anything over 1.0s to be 'slow' and anything over 3.0s to be 'painfully slow'.
|
35
61
|
|
36
62
|
## Development
|
37
|
-
|
38
63
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
39
64
|
|
40
65
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
41
66
|
|
42
|
-
|
67
|
+
### Forcing Test Failures
|
68
|
+
In order to easily see how Minitest Heat handles different combinations of different types of failures, the following environment variables can be used to force failures.
|
69
|
+
|
70
|
+
```bash
|
71
|
+
IMPLODE=true # Every possible type of failure, skip, and slow is generated
|
72
|
+
FORCE_EXCEPTIONS=true # Only exception-triggered failures
|
73
|
+
FORCE_FAILURES=true # Only standard assertion failures
|
74
|
+
FORCE_SKIPS=true # No errors, just the skipped tests
|
75
|
+
FORCE_SLOWS=true # No errors or skipped tests, just slow tests
|
76
|
+
```
|
43
77
|
|
44
|
-
|
78
|
+
So to see the full context of a test suite, `IMPLODE=true bundle exec rake` will work its magic.
|
45
79
|
|
80
|
+
## Contributing
|
81
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/garrettdimon/minitest-heat. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/minitest-heat/blob/master/CODE_OF_CONDUCT.md).
|
46
82
|
|
47
83
|
## License
|
48
84
|
|
49
85
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
50
86
|
|
51
87
|
## Code of Conduct
|
52
|
-
|
53
88
|
Everyone interacting in the Minitest::Heat project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/minitest-heat/blob/master/CODE_OF_CONDUCT.md).
|
Binary file
|
Binary file
|
data/examples/map.png
ADDED
Binary file
|
Binary file
|
data/examples/skips.png
ADDED
Binary file
|
data/examples/slows.png
ADDED
Binary file
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module Minitest
|
6
|
+
module Heat
|
7
|
+
class Backtrace
|
8
|
+
# Represents a line from a backtrace to provide more convenient access to information about
|
9
|
+
# the relevant file and line number for displaying in test results
|
10
|
+
module LineParser
|
11
|
+
# Parses a line from a backtrace in order to convert it to usable components
|
12
|
+
def self.read(raw_text)
|
13
|
+
raw_pathname, raw_line_number, raw_container = raw_text.split(':')
|
14
|
+
raw_container = raw_container.delete_prefix('in `').delete_suffix("'")
|
15
|
+
|
16
|
+
::Minitest::Heat::Location.new(
|
17
|
+
pathname: raw_pathname,
|
18
|
+
line_number: raw_line_number,
|
19
|
+
container: raw_container
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'backtrace/
|
3
|
+
require_relative 'backtrace/line_parser'
|
4
4
|
|
5
5
|
module Minitest
|
6
6
|
module Heat
|
@@ -9,7 +9,7 @@ module Minitest
|
|
9
9
|
attr_reader :raw_backtrace
|
10
10
|
|
11
11
|
# Creates a more flexible backtrace data structure by parsing the lines of the backtrace to
|
12
|
-
# extract
|
12
|
+
# extract specific subsets of lines for investigating the offending files and line numbers
|
13
13
|
# @param raw_backtrace [Array] the array of lines from the backtrace
|
14
14
|
#
|
15
15
|
# @return [self]
|
@@ -24,80 +24,42 @@ module Minitest
|
|
24
24
|
raw_backtrace.empty?
|
25
25
|
end
|
26
26
|
|
27
|
-
#
|
28
|
-
# dependency or the Ruby core libraries
|
27
|
+
# All lines of the backtrace converted to Backtrace::LineParser's
|
29
28
|
#
|
30
|
-
# @return [
|
31
|
-
def
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
# The final location from within the project exposed in the backtrace. Could be test files or
|
36
|
-
# source code files
|
37
|
-
#
|
38
|
-
# @return [Line] the final project location from the backtrace parsed as a Backtrace::Line
|
39
|
-
def final_project_location
|
40
|
-
project_entries.first
|
41
|
-
end
|
42
|
-
|
43
|
-
# The most recently modified location from within the project
|
44
|
-
#
|
45
|
-
# @return [Line] the most recently modified project location from the backtrace parsed as a
|
46
|
-
# Backtrace::Line
|
47
|
-
def freshest_project_location
|
48
|
-
recently_modified_entries.first
|
49
|
-
end
|
29
|
+
# @return [Array<Location>] the full set of backtrace lines parsed as Location instances
|
30
|
+
def locations
|
31
|
+
return [] if raw_backtrace.nil?
|
50
32
|
|
51
|
-
|
52
|
-
#
|
53
|
-
# @return [Line] the final source code location from the backtrace parsed as a Backtrace::Line
|
54
|
-
def final_source_code_location
|
55
|
-
source_code_entries.first
|
33
|
+
@locations ||= raw_backtrace.map { |entry| Backtrace::LineParser.read(entry) }
|
56
34
|
end
|
57
35
|
|
58
|
-
#
|
36
|
+
# All entries from the backtrace within the project and sorted with the most recently modified
|
37
|
+
# files at the beginning
|
59
38
|
#
|
60
|
-
# @return [
|
61
|
-
def
|
62
|
-
|
39
|
+
# @return [Array<Location>] the sorted backtrace lines from the project
|
40
|
+
def recently_modified_locations
|
41
|
+
@recently_modified_locations ||= project_locations.sort_by(&:mtime).reverse
|
63
42
|
end
|
64
43
|
|
65
44
|
# All entries from the backtrace that are files within the project
|
66
45
|
#
|
67
|
-
# @return [
|
68
|
-
def
|
69
|
-
@
|
70
|
-
end
|
71
|
-
|
72
|
-
# All entries from the backtrace within the project and sorted with the most recently modified
|
73
|
-
# files at the beginning
|
74
|
-
#
|
75
|
-
# @return [Line] the sorted backtrace lines from the project parsed as Backtrace::Line's
|
76
|
-
def recently_modified_entries
|
77
|
-
@recently_modified_entries ||= project_entries.sort_by(&:mtime).reverse
|
46
|
+
# @return [Array<Location>] the backtrace lines from within the project
|
47
|
+
def project_locations
|
48
|
+
@project_locations ||= locations.select(&:project_file?)
|
78
49
|
end
|
79
50
|
|
80
51
|
# All entries from the backtrace within the project tests
|
81
52
|
#
|
82
|
-
# @return [
|
83
|
-
def
|
84
|
-
@
|
53
|
+
# @return [Array<Location>] the backtrace lines from within the tests
|
54
|
+
def test_locations
|
55
|
+
@test_locations ||= project_locations.select(&:test_file?)
|
85
56
|
end
|
86
57
|
|
87
58
|
# All source code entries from the backtrace (i.e. excluding tests)
|
88
59
|
#
|
89
|
-
# @return [
|
90
|
-
def
|
91
|
-
@
|
92
|
-
end
|
93
|
-
|
94
|
-
# All lines of the backtrace converted to Backtrace::Line's
|
95
|
-
#
|
96
|
-
# @return [Line] the full set of backtrace lines parsed as Backtrace::Line instances
|
97
|
-
def parsed_entries
|
98
|
-
return [] if raw_backtrace.nil?
|
99
|
-
|
100
|
-
@parsed_entries ||= raw_backtrace.map { |entry| Backtrace::Line.parse_backtrace(entry) }
|
60
|
+
# @return [Array<Location>] the backtrace lines from within the source code
|
61
|
+
def source_code_locations
|
62
|
+
@source_code_locations ||= project_locations.select(&:source_code_file?)
|
101
63
|
end
|
102
64
|
end
|
103
65
|
end
|
data/lib/minitest/heat/hit.rb
CHANGED
@@ -5,8 +5,10 @@ require 'forwardable'
|
|
5
5
|
module Minitest
|
6
6
|
module Heat
|
7
7
|
# Kind of like an issue, but instead of focusing on a failing test, it covers all issues for a
|
8
|
-
# given file to build a heat map of the affected files
|
8
|
+
# given file to build a heat map of the affected files and line numbers
|
9
9
|
class Hit
|
10
|
+
Trace = Struct.new(:type, :line_number, :locations)
|
11
|
+
|
10
12
|
# So we can sort hot spots by liklihood of being the most important spot to check out before
|
11
13
|
# trying to fix something. These are ranked based on the possibility they represent ripple
|
12
14
|
# effects where fixing one problem could potentially fix multiple other failures.
|
@@ -23,7 +25,7 @@ module Minitest
|
|
23
25
|
slow: 0
|
24
26
|
}.freeze
|
25
27
|
|
26
|
-
attr_reader :pathname, :issues
|
28
|
+
attr_reader :pathname, :issues, :lines
|
27
29
|
|
28
30
|
# Creates an instance of a Hit for the given pathname. It must be the full pathname to
|
29
31
|
# uniquely identify the file or we could run into collisions that muddy the water and
|
@@ -34,16 +36,26 @@ module Minitest
|
|
34
36
|
def initialize(pathname)
|
35
37
|
@pathname = Pathname(pathname)
|
36
38
|
@issues = {}
|
39
|
+
@lines = {}
|
37
40
|
end
|
38
41
|
|
39
42
|
# Adds a record of a given issue type for the line number
|
40
43
|
# @param type [Symbol] one of Issue::TYPES
|
41
44
|
# @param line_number [Integer,String] the line number to record the issue on
|
45
|
+
# @param backtrace: nil [Array<Location>] the project locations from the backtrace
|
42
46
|
#
|
43
|
-
# @return [
|
44
|
-
def log(type, line_number)
|
45
|
-
|
46
|
-
|
47
|
+
# @return [void]
|
48
|
+
def log(type, line_number, backtrace: [])
|
49
|
+
line_number = Integer(line_number)
|
50
|
+
issue_type = type.to_sym
|
51
|
+
|
52
|
+
# Store issues by issue type with an array of line numbers
|
53
|
+
@issues[issue_type] ||= []
|
54
|
+
@issues[issue_type] << line_number
|
55
|
+
|
56
|
+
# Store issues by line number with an array of Traces
|
57
|
+
@lines[line_number.to_s] ||= []
|
58
|
+
@lines[line_number.to_s] << Trace.new(issue_type, line_number, backtrace)
|
47
59
|
end
|
48
60
|
|
49
61
|
# Calcuates an approximate weight to serve as a proxy for which files are most likely to be
|
data/lib/minitest/heat/issue.rb
CHANGED
@@ -18,7 +18,7 @@ module Minitest
|
|
18
18
|
}.freeze
|
19
19
|
|
20
20
|
attr_reader :assertions,
|
21
|
-
:
|
21
|
+
:locations,
|
22
22
|
:message,
|
23
23
|
:test_class,
|
24
24
|
:test_identifier,
|
@@ -27,7 +27,7 @@ module Minitest
|
|
27
27
|
:error,
|
28
28
|
:skipped
|
29
29
|
|
30
|
-
def_delegators :@
|
30
|
+
def_delegators :@locations, :backtrace, :test_definition_line, :test_failure_line
|
31
31
|
|
32
32
|
# Extracts the necessary data from result.
|
33
33
|
# @param result [Minitest::Result] the instance of Minitest::Result to examine
|
@@ -39,7 +39,7 @@ module Minitest
|
|
39
39
|
|
40
40
|
new(
|
41
41
|
assertions: result.assertions,
|
42
|
-
|
42
|
+
test_location: result.source_location,
|
43
43
|
test_class: result.klass,
|
44
44
|
test_identifier: result.name,
|
45
45
|
execution_time: result.time,
|
@@ -47,7 +47,7 @@ module Minitest
|
|
47
47
|
error: result.error?,
|
48
48
|
skipped: result.skipped?,
|
49
49
|
message: exception&.message,
|
50
|
-
backtrace: exception&.backtrace
|
50
|
+
backtrace: exception&.backtrace
|
51
51
|
)
|
52
52
|
end
|
53
53
|
|
@@ -57,7 +57,7 @@ module Minitest
|
|
57
57
|
# @param assertions: 1 [Integer] the number of assertions in the result
|
58
58
|
# @param message: nil [String] exception if there is one
|
59
59
|
# @param backtrace: [] [Array<String>] the array of backtrace lines from an exception
|
60
|
-
# @param
|
60
|
+
# @param test_location: nil [Array<String, Integer>] the locations identifier for a test
|
61
61
|
# @param test_class: nil [String] the class name for the test result's containing class
|
62
62
|
# @param test_identifier: nil [String] the name of the test
|
63
63
|
# @param execution_time: nil [Float] the time it took to run the test
|
@@ -66,11 +66,11 @@ module Minitest
|
|
66
66
|
# @param skipped: false [Boolean] true if the test was skipped
|
67
67
|
#
|
68
68
|
# @return [type] [description]
|
69
|
-
def initialize(assertions: 1,
|
69
|
+
def initialize(assertions: 1, test_location: ['Unrecognized Test File', 1], backtrace: [], execution_time: 0.0, message: nil, test_class: nil, test_identifier: nil, passed: false, error: false, skipped: false)
|
70
70
|
@message = message
|
71
71
|
|
72
72
|
@assertions = Integer(assertions)
|
73
|
-
@
|
73
|
+
@locations = Locations.new(test_location, backtrace)
|
74
74
|
|
75
75
|
@test_class = test_class
|
76
76
|
@test_identifier = test_identifier
|
@@ -99,9 +99,9 @@ module Minitest
|
|
99
99
|
:skipped
|
100
100
|
elsif !passed?
|
101
101
|
:failure
|
102
|
-
elsif painful?
|
102
|
+
elsif passed? && painful?
|
103
103
|
:painful
|
104
|
-
elsif slow?
|
104
|
+
elsif passed? && slow?
|
105
105
|
:slow
|
106
106
|
else
|
107
107
|
:success
|
@@ -116,37 +116,55 @@ module Minitest
|
|
116
116
|
!passed? || slow? || painful?
|
117
117
|
end
|
118
118
|
|
119
|
+
# The number, in seconds, for a test to be considered "slow"
|
120
|
+
#
|
121
|
+
# @return [Float] number of seconds after which a test is considered slow
|
122
|
+
def slow_threshold
|
123
|
+
# Using a method here so that this can eventually be configurable such that the constant is
|
124
|
+
# only a fallback value if it's not specified anywhere else
|
125
|
+
SLOW_THRESHOLDS[:slow]
|
126
|
+
end
|
127
|
+
|
128
|
+
# The number, in seconds, for a test to be considered "painfully slow"
|
129
|
+
#
|
130
|
+
# @return [Float] number of seconds after which a test is considered painfully slow
|
131
|
+
def painfully_slow_threshold
|
132
|
+
# Using a method here so that this can eventually be configurable such that the constant is
|
133
|
+
# only a fallback value if it's not specified anywhere else
|
134
|
+
SLOW_THRESHOLDS[:painful]
|
135
|
+
end
|
136
|
+
|
119
137
|
# Determines if a test should be considered slow by comparing it to the low end definition of
|
120
138
|
# what is considered slow.
|
121
139
|
#
|
122
|
-
# @return [Boolean] true if the test took longer to run than `
|
140
|
+
# @return [Boolean] true if the test took longer to run than `slow_threshold`
|
123
141
|
def slow?
|
124
|
-
execution_time >=
|
142
|
+
execution_time >= slow_threshold && execution_time < painfully_slow_threshold
|
125
143
|
end
|
126
144
|
|
127
145
|
# Determines if a test should be considered painfully slow by comparing it to the high end
|
128
146
|
# definition of what is considered slow.
|
129
147
|
#
|
130
|
-
# @return [Boolean] true if the test took longer to run than `
|
148
|
+
# @return [Boolean] true if the test took longer to run than `painfully_slow_threshold`
|
131
149
|
def painful?
|
132
|
-
execution_time >=
|
150
|
+
execution_time >= painfully_slow_threshold
|
133
151
|
end
|
134
152
|
|
135
153
|
# Determines if the issue is an exception that was raised from directly within a test
|
136
154
|
# definition. In these cases, it's more likely to be a quick fix.
|
137
155
|
#
|
138
|
-
# @return [Boolean] true if the final
|
156
|
+
# @return [Boolean] true if the final locations of the stacktrace was a test file
|
139
157
|
def in_test?
|
140
|
-
|
158
|
+
locations.broken_test?
|
141
159
|
end
|
142
160
|
|
143
161
|
# Determines if the issue is an exception that was raised from directly within the project
|
144
162
|
# codebase.
|
145
163
|
#
|
146
|
-
# @return [Boolean] true if the final
|
164
|
+
# @return [Boolean] true if the final locations of the stacktrace was a file from the project
|
147
165
|
# (as opposed to a dependency or Ruby library)
|
148
166
|
def in_source?
|
149
|
-
|
167
|
+
locations.proper_failure?
|
150
168
|
end
|
151
169
|
|
152
170
|
# Was the result a pass? i.e. Skips aren't passes or failures. Slows are still passes. So this
|