test-prof 1.4.0.rc.2 → 1.4.0.rc.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -0
- data/lib/test_prof/factory_default/factory_bot_patch.rb +9 -6
- data/lib/test_prof/tps_prof/profiler.rb +55 -0
- data/lib/test_prof/tps_prof/reporter/text.rb +48 -0
- data/lib/test_prof/tps_prof/rspec.rb +63 -0
- data/lib/test_prof/tps_prof.rb +46 -0
- data/lib/test_prof/version.rb +1 -1
- data/lib/test_prof.rb +1 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55eaa3ce2f79b5cae7992ea0e45a499c28ae1d301b2f7c9e34796d587c0e6090
|
4
|
+
data.tar.gz: 2f5a07b3a9c78304c054e025d0e785a253d310c354005ca767a7ea0674033e0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f26d5cdd70cd05d93fc0cc596302a72089c1718fd5b58084b5a219333ac6b0ba034d09c7a0e57840fa790f4198c7b8ba24f8dfdaa0d0b85a5f7404246b922b07
|
7
|
+
data.tar.gz: 22e6d9304af0c182f4bd1bf7d4b34a9bc8d5435b505100bebe9519cdac2f3d29ba47db3fe7de48179cc88c191cac3da531de4d3b6f506c2275dc52f45b832444
|
data/CHANGELOG.md
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "test_prof/factory_bot"
|
4
|
+
|
3
5
|
module TestProf
|
4
6
|
module FactoryDefault # :nodoc: all
|
5
7
|
module FactoryBotPatch
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
if defined?(TestProf::FactoryBot::FactoryRunner)
|
9
|
+
module RunnerExt
|
10
|
+
refine TestProf::FactoryBot::FactoryRunner do
|
11
|
+
attr_reader :name, :traits, :overrides
|
12
|
+
end
|
9
13
|
end
|
10
|
-
end
|
11
14
|
|
12
|
-
|
15
|
+
using RunnerExt
|
16
|
+
end
|
13
17
|
|
14
18
|
module StrategyExt
|
15
19
|
def association(runner)
|
@@ -53,7 +57,6 @@ module TestProf
|
|
53
57
|
end
|
54
58
|
|
55
59
|
def self.patch
|
56
|
-
require "test_prof/factory_bot"
|
57
60
|
return unless defined?(TestProf::FactoryBot)
|
58
61
|
|
59
62
|
TestProf::FactoryBot::Syntax::Methods.include SyntaxExt
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_prof/utils/sized_ordered_set"
|
4
|
+
|
5
|
+
module TestProf
|
6
|
+
module TPSProf
|
7
|
+
class Profiler
|
8
|
+
attr_reader :top_count, :groups, :total_count, :total_time, :threshold
|
9
|
+
|
10
|
+
def initialize(top_count, threshold: 10)
|
11
|
+
@threshold = threshold
|
12
|
+
@top_count = top_count
|
13
|
+
@total_count = 0
|
14
|
+
@total_time = 0.0
|
15
|
+
@groups = Utils::SizedOrderedSet.new(top_count, sort_by: :tps)
|
16
|
+
end
|
17
|
+
|
18
|
+
def group_started(id)
|
19
|
+
@current_group = id
|
20
|
+
@examples_count = 0
|
21
|
+
@examples_time = 0.0
|
22
|
+
@group_started_at = TestProf.now
|
23
|
+
end
|
24
|
+
|
25
|
+
def group_finished(id)
|
26
|
+
return unless @examples_count >= threshold
|
27
|
+
|
28
|
+
# Context-time
|
29
|
+
group_time = (TestProf.now - @group_started_at) - @examples_time
|
30
|
+
run_time = @examples_time + group_time
|
31
|
+
|
32
|
+
groups << {
|
33
|
+
id: id,
|
34
|
+
run_time: run_time,
|
35
|
+
group_time: group_time,
|
36
|
+
count: @examples_count,
|
37
|
+
tps: -(@examples_count / run_time).round(2)
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def example_started(id)
|
42
|
+
@example_started_at = TestProf.now
|
43
|
+
end
|
44
|
+
|
45
|
+
def example_finished(id)
|
46
|
+
@examples_count += 1
|
47
|
+
@total_count += 1
|
48
|
+
|
49
|
+
time = (TestProf.now - @example_started_at)
|
50
|
+
@examples_time += time
|
51
|
+
@total_time += time
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_prof/ext/float_duration"
|
4
|
+
require "test_prof/ext/string_truncate"
|
5
|
+
|
6
|
+
module TestProf
|
7
|
+
module TPSProf
|
8
|
+
module Reporter
|
9
|
+
class Text
|
10
|
+
include Logging
|
11
|
+
using FloatDuration
|
12
|
+
using StringTruncate
|
13
|
+
|
14
|
+
def print(profiler)
|
15
|
+
groups = profiler.groups
|
16
|
+
|
17
|
+
total_tps = (profiler.total_count / profiler.total_time).round(2)
|
18
|
+
|
19
|
+
msgs = []
|
20
|
+
|
21
|
+
msgs <<
|
22
|
+
<<~MSG
|
23
|
+
Total TPS (tests per second): #{total_tps}
|
24
|
+
|
25
|
+
Top #{profiler.top_count} slowest suites by TPS (tests per second) (min examples per group: #{profiler.threshold}):
|
26
|
+
|
27
|
+
MSG
|
28
|
+
|
29
|
+
groups.each do |group|
|
30
|
+
description = group[:id].top_level_description
|
31
|
+
location = group[:id].metadata[:location]
|
32
|
+
time = group[:run_time]
|
33
|
+
group_time = group[:group_time]
|
34
|
+
count = group[:count]
|
35
|
+
tps = -group[:tps]
|
36
|
+
|
37
|
+
msgs <<
|
38
|
+
<<~GROUP
|
39
|
+
#{description.truncate} (#{location}) – #{tps} TPS (#{time.duration} / #{count}), group time: #{group_time.duration}
|
40
|
+
GROUP
|
41
|
+
end
|
42
|
+
|
43
|
+
log :info, msgs.join
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TestProf
|
4
|
+
module TPSProf
|
5
|
+
class RSpecListener # :nodoc:
|
6
|
+
include Logging
|
7
|
+
|
8
|
+
NOTIFICATIONS = %i[
|
9
|
+
example_group_started
|
10
|
+
example_group_finished
|
11
|
+
example_started
|
12
|
+
example_finished
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
attr_reader :reporter, :profiler
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@profiler = Profiler.new(TPSProf.config.top_count, threshold: TPSProf.config.threshold)
|
19
|
+
@reporter = TPSProf.config.reporter
|
20
|
+
|
21
|
+
log :info, "TPSProf enabled (top-#{TPSProf.config.top_count})"
|
22
|
+
end
|
23
|
+
|
24
|
+
def example_group_started(notification)
|
25
|
+
return unless notification.group.top_level?
|
26
|
+
profiler.group_started notification.group
|
27
|
+
end
|
28
|
+
|
29
|
+
def example_group_finished(notification)
|
30
|
+
return unless notification.group.top_level?
|
31
|
+
profiler.group_finished notification.group
|
32
|
+
end
|
33
|
+
|
34
|
+
def example_started(notification)
|
35
|
+
profiler.example_started notification.example
|
36
|
+
end
|
37
|
+
|
38
|
+
def example_finished(notification)
|
39
|
+
profiler.example_finished notification.example
|
40
|
+
end
|
41
|
+
|
42
|
+
def print
|
43
|
+
reporter.print(profiler)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Register TPSProf listener
|
50
|
+
TestProf.activate("TPS_PROF") do
|
51
|
+
RSpec.configure do |config|
|
52
|
+
listener = nil
|
53
|
+
|
54
|
+
config.before(:suite) do
|
55
|
+
listener = TestProf::TPSProf::RSpecListener.new
|
56
|
+
config.reporter.register_listener(
|
57
|
+
listener, *TestProf::TPSProf::RSpecListener::NOTIFICATIONS
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
config.after(:suite) { listener&.print }
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_prof/tps_prof/profiler"
|
4
|
+
require "test_prof/tps_prof/reporter/text"
|
5
|
+
|
6
|
+
module TestProf
|
7
|
+
# TPSProf shows top-N example group based on their tests-per-second value.
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
#
|
11
|
+
# TPS_PROF=10 rspec ...
|
12
|
+
#
|
13
|
+
module TPSProf
|
14
|
+
class Configuration
|
15
|
+
attr_accessor :top_count, :threshold, :reporter
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@top_count = ENV["TPS_PROF"].to_i
|
19
|
+
@top_count = 10 if @top_count == 1
|
20
|
+
@threshold = ENV.fetch("TPS_PROF_MIN", 10).to_i
|
21
|
+
@reporter = resolve_reporter(ENV["TPS_PROF_FORMAT"])
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def resolve_reporter(format)
|
27
|
+
# TODO: support other formats
|
28
|
+
TPSProf::Reporter::Text.new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class << self
|
33
|
+
def config
|
34
|
+
@config ||= Configuration.new
|
35
|
+
end
|
36
|
+
|
37
|
+
def configure
|
38
|
+
yield config
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
require "test_prof/tps_prof/rspec" if TestProf.rspec?
|
45
|
+
# TODO: Minitest support
|
46
|
+
# require "test_prof/tps_prof/minitest" if TestProf.minitest?
|
data/lib/test_prof/version.rb
CHANGED
data/lib/test_prof.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: test-prof
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.0.rc.
|
4
|
+
version: 1.4.0.rc.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-07-
|
11
|
+
date: 2024-07-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -219,6 +219,10 @@ files:
|
|
219
219
|
- lib/test_prof/tag_prof/printers/simple.rb
|
220
220
|
- lib/test_prof/tag_prof/result.rb
|
221
221
|
- lib/test_prof/tag_prof/rspec.rb
|
222
|
+
- lib/test_prof/tps_prof.rb
|
223
|
+
- lib/test_prof/tps_prof/profiler.rb
|
224
|
+
- lib/test_prof/tps_prof/reporter/text.rb
|
225
|
+
- lib/test_prof/tps_prof/rspec.rb
|
222
226
|
- lib/test_prof/utils.rb
|
223
227
|
- lib/test_prof/utils/html_builder.rb
|
224
228
|
- lib/test_prof/utils/rspec.rb
|