palkan_tula
palkan
+
Reduce costs
3
d =
(
1 −
T
new
Told )
− test suite speed improvement
C
dev
− cost of an hour of profiling/optimization work
C
build
= avg(t
minutes
(b
i
)) × CI
min
− cost of a build
N
builds
× C
build
× d ≫ N
hours
× C
dev
Slide 5
Slide 5 text
palkan_tula
palkan
+
Example
4
N
builds
× C
build
× d ≫ N
hours
× C
dev
d =
(
1 −
T
new
Told )
= 0.2
C
dev
= 200
C
build
= avg(t
minutes
(b
i
)) × CI
min
= 30 × 0.01 = 0.3
Slide 6
Slide 6 text
palkan_tula
palkan
+
N
builds
× 0.3 × 0.2 ≫ N
hours
× 200
Example
4
d =
(
1 −
T
new
Told )
= 0.2
C
dev
= 200
C
build
= avg(t
minutes
(b
i
)) × CI
min
= 30 × 0.01 = 0.3
Slide 7
Slide 7 text
palkan_tula
palkan
+
Example
4
d =
(
1 −
T
new
Told )
= 0.2
C
dev
= 200
C
build
= avg(t
minutes
(b
i
)) × CI
min
= 30 × 0.01 = 0.3
N
builds
≫ N
hours
× 3333
Slide 8
Slide 8 text
palkan_tula
palkan
+
Example
4
d =
(
1 −
T
new
Told )
= 0.2
C
dev
= 200
C
build
= avg(t
minutes
(b
i
)) × CI
min
= 30 × 0.01 = 0.3
N
builds
≫ 16 × 3333 ≈ 53000
Slide 9
Slide 9 text
–Undisclosed TestProf user
“Our CI pipeline currently takes about 2
hours. We calculated that reducing from
120 min to 30 min would be equivalent to
adding 2 full-time engineers per year.”
5
–Undisclosed TestProf user
“When asked “How we can we improve the
developer experience?”, top themes that
emerged included speed (test suite is slow)
and flaky specs”
13
Slide 22
Slide 22 text
–Undisclosed Evil Martians client
“When asked “How we can we improve the
developer experience?”, top themes that
emerged included speed (test suite is slow)
and flaky specs”
13
Slide 23
Slide 23 text
Did I introduce
myself?
Slide 24
Slide 24 text
palkan_tula
palkan
+
Ich heiße Vova
15
github.com/palkan
Slide 25
Slide 25 text
palkan_tula
palkan
+
Ich komme vom Mars
16
evilmartians.com
Slide 26
Slide 26 text
palkan_tula
palkan
+
Ich habe ein Buch
17
Slide 27
Slide 27 text
Profiling
tests
Slide 28
Slide 28 text
palkan_tula
palkan
+
1.
2.
3.
4.
5.
137 0
0
- -
19
HOW DO YOU PROFILE TESTS?
Slide 29
Slide 29 text
palkan_tula
palkan
+
1.
2.
3.
4.
5.
137 0
19
HOW DO YOU PROFILE TESTS?
99
1. bin/rspec - -profile 99
99
Slide 30
Slide 30 text
20
Rails 7.1
Slide 31
Slide 31 text
21
Slide 32
Slide 32 text
22
evilmartians.com/events
Slide 33
Slide 33 text
–Steven Baker
“On anything but the slowest of test
suites, you get more mileage out of
making often-used things faster .”
23
Slide 34
Slide 34 text
Finding
often-used
things
Slide 35
Slide 35 text
palkan_tula
palkan
+
25
Specialized profiler for Ruby test
suites
Optimization toolbox to speed up
tests with less refactoring
TestProf
test-prof.evilmartians.io
Slide 36
Slide 36 text
palkan_tula
palkan
+
26
Based on techniques used in a
large Rails monolith (Fountain)
Helped to gain 4x test time
reduction (from 170 to 700 TPM*)
TestProf
test-prof.evilmartians.io
* TPM = Tests per minutes
Slide 37
Slide 37 text
palkan_tula
palkan
+
27
Used by GitHub, Discourse,
Gitlab, Dev.to, and many more
TestProf
test-prof.evilmartians.io
Slide 38
Slide 38 text
palkan_tula
palkan
+
27
Used by GitHub, Discourse,
Gitlab, Dev.to, and many more
Used by YOU after this
conference!
TestProf
test-prof.evilmartians.io
Slide 39
Slide 39 text
The TestProf
Way
bundle add test-prof -g test
Slide 40
Slide 40 text
Think
globally
Step 1
Slide 41
Slide 41 text
palkan_tula
palkan
+
30
Give general Ruby profilers a try
Profile with StackProf,
RubyProf, or Vernier via
TestProf integrations
Use tests sampling
Think globally
Start with not-so-specialized profilers
palkan_tula
palkan
+
The 6% phenomenon
33
# config/environments/test.rb
config.logger = Logger.new(nil)
config.log_level = :fatal
Just two lines of code to make your Rails tests faster
palkan_tula
palkan
+
37
General profilers are good in
finding performance issues but
fail to identify code patterns
that make your tests slow
Slide 49
Slide 49 text
Focus
Step 2
Slide 50
Slide 50 text
palkan_tula
palkan
+
39
Tests of a similar type (model,
request, etc.) have similar
problems
High chance to find one trick
to fix them all
Focus
Don't try to fix everything, locate the suite's subset
with the greatest improvement potential
palkan_tula
palkan
+
$
44
EVENT_PROF=factory.create EVENT_PROF_STAMP=slow:factory \
EVENT_PROF_TOP 20 bin/rspec
Total time: 34 04.665 of 37 12.515 (91.59%)
Total events: 15260
Top 20 slowest suites (by time):
User (./spec/models/user_spec.rb:3) – 02 32.577 (951 / 583) of
02 50.654 (89.41%)
Appointment (./spec/models/appointment_spec.rb:4) – 02 16.524
(822 / 401) of 02 38.911 (85.91%)
Slide 56
Slide 56 text
palkan_tula
palkan
+
45
Pick the most time-consuming
group ("models" in our
example)
Continue profiling only within
this group, ignore everything
else (for now)
Focus
Slide 57
Slide 57 text
Be specific
Step 3
Slide 58
Slide 58 text
palkan_tula
palkan
+
47
Profile factories with
FactoryDoctor and
FactoryProf
Profile specs layout with
RSpecDissect
Be specific
It's time to dust off one of the specialized profilers
Slide 59
Slide 59 text
palkan_tula
palkan
+
$
.....................................
[TEST PROF INFO] FactoryDoctor enabled
48
FDOC 1 bin/rspec
[TEST PROF INFO] FactoryDoctor report
Total (potentially) bad examples: 1428
Total wasted time: 07 06.446
Group (./spec/models/group_spec.rb:3) (367 records created,
00 09.312)
Assignment (./spec/models/assignment_spec.rb:3) (217 records
created, 00 05.749)
Slide 60
Slide 60 text
palkan_tula
palkan
+
FactoryDoctor
49
# bad
it "validates name" do
user = create(:user)
expect(user).not_to be_valid
end
# good
it "validates name" do
user = build_stubbed(:user)
expect(user).not_to be_valid
end