SlideShare ist ein Scribd-Unternehmen logo
1 von 58
Downloaden Sie, um offline zu lesen
An introduction and future
of Ruby coverage library
RubyKaigi 2017 (19th Sep. )
Yusuke Endoh (@mametter)
Yusuke Endoh (@mametter)
• Ruby committer (2008—)
• Full-time Ruby committer (2017—)
• My goal: make Ruby programs robust
– Test coverage, and type system?
Method.
Put the cream cheese into the mixing bowl.
Put the sour cream into the mixing bowl.
Put the white sugar into the mixing bowl.
Put the yogrut into the mixing bowl.
Put the unsalted butter into the mixing bowl.
Combine the milk.
Put the cake flour into the mixing bowl.
Combine the corn starch.
Put the brown sugar into the mixing bowl.
Combine the egg whites.
Combine the egg yolks.
Put the lemon juice into the mixing bowl.
Stir for 7 minutes.
Liquify the contents of the mixing bowl.
Pour contents of the mixing bowl into the baking dish
Bake the cake mixture.
Watch the cake mixture until baked.
Serves 4.
Cheese cake in Chef.
Ingredients.
100 g cream cheese
97 g sour cream
107 g yogrut
112 g white sugar
11 g brown sugar
37 g unsalted butter
37 g cake flour
3 g corn starch
3 ml milk
3 egg yolks
3 egg whites
10 ml lemon juice
0 g cake mixture
Cooking time: 80 minutes.
‘d’
‘a’
‘k’
‘p’
11*3*3=99 ‘c’
37*3=111 ‘o’
¥n
‘o’
Push characters
‘¥n’ ‘d’ ‘a’ ‘p’ ‘k’ ‘o’ ‘o’ ‘c’
into the stack
Convert them to a string
and “serve” it.
data
code
Esoteric Recipe
• Polyglot of Chef and
real recipe
– Japanese version
https://cookpad.com/
recipe/4649810
– English version
https://cookpad.com/us/
recipes/3335222
My main contributions for Ruby
• Implementation of some features:
keyword arguments, deadlock detection, etc.
• Release management for Ruby 1.9.2 and 2.0.0
• Optcarrot: A NES emulator for Ruby3x3
benchmark
• Enhancement of
the test suite of Ruby
• coverage.so: the core library
for coverage measurement
’06B ’07A ’07B ’08A
60
70
80
90
100
coverage(%)
70%
85%
line coverage
Today’s theme
• An introduction of test coverage
• An improvement plan of Ruby’s
coverage measurement feature
towards 2.5
Survey [1/3]
• Q. Do you use Ruby/RoR in production?
– Raise your hand, please!
Survey [2/3]
• Q. In those, do you test your code?
Survey [3/3]
• Q. In those, do you use “coverage”?
– Do you check the result of SimpleCov?
Agenda
• What is coverage
• How to understand and use coverage
• The current status of Ruby coverage
feature
• The future plan of Ruby coverage
feature
• Conclusion
Agenda
☞ What is coverage
• How to understand and use coverage
• The current status of Ruby coverage
feature
• The future plan of Ruby coverage
feature
• Conclusion
What is coverage?
• A measure of “goodness” of a test suite
– Also called “test coverage” or “code coverage”
• Allows you:
– Find untested code
– Decide whether your test suite is good enough
or not yet
• (This is arguable, but I think we can use it as an
advice)
• Types of coverage
– Function coverage, line coverage, branch
coverage, …
Function coverage
• How many functions are executed by
the tests
# code
def foo; …; end # ✓
def bar; …; end # ✗
def baz; …; end # ✓
# test
foo
baz
2/3
(67%)
• Advantage
• Easy to understand
• Easy to visualize
• Disadvantage
• Too weak as a measure
Line coverage
• How many lines are executed
# code
def foo(x) # ✓
if x == 0 # ✓
p :foo # ✗
else
p :bar # ✓
end
end
# test
foo(1)
3/4
(75%)
Non-significant line is
ignored
• Advantage
• Easy to understand
• Easy to visualize
• Disadvantage
• Still weak as a measure
• foo() if x == 0
Branch coverage
• How many branches are taken true
and false
# code
def foo(x)
p :foo if x == 0 # ✓
p :bar if x < 2 # ✗
end
# test
foo(0)
foo(1)
1/2
(50%)
• Advantage
• Relatively exhaustive
• Disadvantage
• Difficult to visualize
true-case and false-case are
both executed
Coverage types
Coverage type Easy to
understand/
visualize
Exhaustive
Function
coverage
○ ✕
Line
coverage
○ △
Branch
coverage
△ ○
Currently, Ruby supports only line coverage
Other types of coverage
• Condition coverage
– How many conditions
(not branches) are taken
both true and false
• Path coverage
– How many paths are executed
– Combinatorial explosion
• Other advanced ones
– Data-flow coverage
– MC/DC coverage
if a && b
branch
conditioncondition
Trivia
• “C0/C1/C2 coverages” have difference
meanings to different people
– C0 coverage = line coverage
– C1 coverage = branch coverage or path
coverage?
– C2 coverage = condition coverage or
path coverage?
Coverage and Ruby
• In Ruby, Coverage is crucial!
– A test is the only way to ensure quality
– Coverage is important to measure test goodness
• Considering it, coverage is not used so
much…
– Coverage is not well-known?
– It is not well-known how to use coverage?
– Ruby’s coverage measurement feature is not
enough?
• I’d like to improve the situation with this talk
Agenda
• What is coverage
☞ How to understand and use
coverage
• The current status of Ruby coverage
feature
• The future plan of Ruby coverage
feature
• Conclusion
What is a good test suite?
• Covers the code
– Coverage measures this
• Also covers the design of program
– Coverage does not measure this directly
How to understand coverage
• Coverage is just a measure
• Coverage is not a goal
If coverage XX% is required as a
goal…
• Developers will
1. Pick untested code that looks easiest to
cover
2. Write a trivial test just for the code
3. Iterate this procedure until XX% is achieved
• It will result in trivial, not-so-good test
suite
– It may be exhaustive for the code itself, but
– It won't be exhaustive for the design
A good way to improve
coverage
• Developers should
1. Look at untested code
2. Consider what “test design” is insufficient
3. Write them
– In consequence of them, the untested code
is executed
• It will result in good test suite
– It will be exhaustive not only for the code
but also for the design
How many % is
needed/enough?
• It depends upon the module being tested
– Aim 100% for a significant module (e.g., injure
someone)
– Don't worry too much for a non-significant
module
• It also depends upon cost performance
– For non-significant module, write a test only if it
is not so hard
• Again: Coverage is not a goal
Agenda
• What is coverage
• How to understand and use coverage
☞ The current status of Ruby
coverage feature
• The future plan of Ruby coverage
feature
• Conclusion
Ruby's coverage ecosystem
• SimpleCov
• coverage.so
• Concov
SimpleCov
• A wrapper library for coverage.so
• Visualization with HTML
• Useful features: merging, filtering, for Rails app
• Author: Christoph Olszowka (@colszowka)
Usage of SimpleCov
• Write this at the top of
test/test_helper.rb
• Run the test suite
• coverage/index.html will be produced
– Note: SimpleCov cannot measure already-
loaded files before SimpleCov.start
require "simplecov"
SimpleCov.start
coverage.so
• The only implementation of coverage
measurement for Ruby 1.9+
• SimpleCov is a wrapper for
coverage.so
• Author: me
Basic usage
# test.rb
require "coverage"
Coverage.start
load "target.rb"
p Coverage.result
#=> {"target.rb"=>
# [nil,nil,1,1,1,nil,
# 0,nil,nil,nil,1]}
Start measuring coverage
Load the target file
Stop measuring
and get the result
Coverage data
Coverage data
# target.rb
def foo(x)
if x == 0
p 0
else
p 1
end
end
foo(1)
[nil,
nil
1
1
0
nil
1
nil
nil
nil
1]
nil:
Non-significant line
Number:
Count executed
Untested line!
Method definition is code in
Ruby
# target.rb
def foo(x)
if x == 0
p 0
else
p 1
end
end
[nil,
nil
1
0
0
nil
0
nil
nil]
Method definition is
counted as an
execution
(It is not a count of
method invocation!)
I regret the design of
coverage.so
• Support only line coverage
• Excuse: I introduced it just for test
enhancement of Ruby itself
– I didn't deliberate the API for external
project…
• I have wanted to make the next version
better
ext/coverage/coverage.c:
69 /* Coverage provides coverage measurement feature for Ruby.
70 * This feature is experimental, so these APIs may be changed in future.
71 *
Concov
• CONtinuous COVerage
– Detects temporal change (degradation) of
coverage
• Developed for monitoring Ruby's coverage
• Author: me
• Presented at RubyKaigi 2009, and then…
– It has not been used by everyone (including me)
– It was based on Ramaze (old web framework)!
Concov reveals reality of Ruby dev.
(Enumerable#join, 2009/07/07, M***)
New feature
introduced
with no tests!
Concov reveals reality of Ruby dev.
(File#size, 2009/02/25, M***)
Concov reveals reality of Ruby dev.
(Etc::Passwd.each, 2009/02/19, N*****)
Concov reveals reality of Ruby dev.
(Dir.home, 2009/02/03, N*****)
Concov reveals reality of Ruby dev.
(Array#sort_by!, 2009/02/03, M***)
Concov reveals reality of Ruby dev.
(rb_to_float, 2008/12/30, M***)
Coverage ecosystem for other
languages
• C/C++: GCOV/LCOV
– Integrated with gcc:
gcc -coverage target.c
• Java: A lot of tools
– Cobertura, Emma,
Clover, JaCoCo
– Integrated with CI tools
and/or IDEs
• JavaScript: Istanbul
Jenkins Cobertura plugin
LCOV result
Agenda
• What is coverage
• How to understand and use coverage
• The current status of Ruby coverage
feature
☞ The future plan of Ruby coverage
feature
• Conclusion
A plan towards Ruby 2.5
• Support function and branch coverage
– There have been multiple requests and
some PoC patches…
• To make the API better, any
comments are welcome
– https://bugs.ruby-lang.org/issues/13901
API: to start measuring
# compatible layer
Coverage.start
Coverage.result
#=> {"file.rb"=>[nil, 1, 0, …], … }
# new API
Coverage.start(lines: true)
Coverage.result
#=> {"file.rb" => { :lines => [nil, 1, 0, …] } }
API: to start other types of
coverage
# enable branch and function coverage
Coverage.start(lines:true,
branches:true,
methods:true)
Coverage.result
#=> {"file.rb" => { :lines => [nil, 1, 0, …],
# :branches => {…},
# :methods => {…} } }
# shorthand
Coverage.start(:all)
Coverage.result for branch
coverage
{"target1.rb"=>
{:lines=>[…],
:branches=>{
[:if, 0, 2]=>{
[:then, 1, 3]=>2,
[:else, 2, 5]=>1
}
},
:methods=>{
[:test_if, 1]=>3
}}}
# target1.rb
1: def test_if(x)
2: if x == 0
3: p "x == 0"
4: else
5: p "x != 0"
6: end
7: end
8:
9: test_if(0)
10: test_if(0)
11: test_if(1)
From if at Line 2
Jumped to
then clause
at Line 3
twice
Jumped to
else clause
at Line 5
once
Coverage.result for branch
coverage
{"target2.rb"=>
{:lines=>[1, 1, 1, nil, nil, 1],
:branches=>
{[:if, 0, 2]=>{
[:then, 1, 2]=>1,
[:else, 2, 2]=>0},
[:if, 3, 3]=>{
[:then, 4, 3]=>0,
[:else, 5, 3]=>1}},
:methods=>{
[:test_if, 1]=>3
}}}
# target2.rb
1: def test_if_oneline(x)
2: p "x == 0" if x == 0
3: p "x != 0" if x != 0
4: end
5:
6: test_if_oneline(0)
Line coverage 100%
Branch coverage tells you
there are untested cases
Discussion of API design
• 100% compatible
• [<label>, <numbering>, <line-no>]
– e.g., [:if, 0, 1], [:while, 1, 1], [:case, 2, 1]
– <numbering> is a unique ID to avoid conflicts for the
case where there are multiple branches in one line
• LCOV-style
– Other candidates:
• [<label>, <line-no>, <column-no>]
– How to handle TAB character
• [<label>, <offset from file head>]
– Looks good, but hard to implement (I'll try later)
Overhead of coverage
measurement
(just preliminary experiment)
# Example 2
1: foo()
2: foo()
…
99: foo()
100: foo()
Benchmark w/o cov. w/ cov. Overhead
Example 1 0.322 μs 6.21 μs x19.3
Example 2 1.55 μs 7.16 μs x4.61
make test-all 485 s 550 s x1.13
# Example 1
1: x = 1
2: x = 1
…
99: x = 1
100: x = 1
Demo
• Applied the new coverage.so to Ruby
• Integrated with C code coverage by
GCOV and Visualized by LCOV
Ruby code
in stdlib
make exam with
gcc -coverage
make exam
COVERAGE=1
test-
coverage
.dat
*.gcda gcov
my script
run test
C code
of MRI
cov. datasource aggregate
lcov HTML
Jenkins Cobertura Plugin
Agenda
• What is coverage
• How to understand and use coverage
• The current status of Ruby coverage
feature
• The future plan of Ruby coverage
feature
☞ Conclusion
Acknowledgement
• @_ko1
• @t_wada
• @kazu_cocoa
• @moro
• @makimoto
• @dev_shia
• @tanaka_akr
• @nalsh
• @spikeolaf
• @k_tsj
Conclusion
• What is coverage, how important in Ruby,
and how to understand coverage
• The current status of Ruby's coverage
measurement and ecosystem
• A plan towards Ruby 2.5 and preliminary
demo
– Any comments are welcome!
– https://bugs.ruby-lang.org/issues/13901
Future work
• Determine the API
• define_method as method coverage
• &. as branch coverage
• Callsite coverage
• Block coverage
obj.foo.bar
ary.map { …… }

Weitere ähnliche Inhalte

Was ist angesagt?

OSS Security the hard way
OSS Security the hard wayOSS Security the hard way
OSS Security the hard wayHiroshi SHIBATA
 
20140425 ruby conftaiwan2014
20140425 ruby conftaiwan201420140425 ruby conftaiwan2014
20140425 ruby conftaiwan2014Hiroshi SHIBATA
 
How to develop Jenkins plugin using to ruby and Jenkins.rb
How to develop Jenkins plugin using to ruby and Jenkins.rbHow to develop Jenkins plugin using to ruby and Jenkins.rb
How to develop Jenkins plugin using to ruby and Jenkins.rbHiroshi SHIBATA
 
20140419 oedo rubykaigi04
20140419 oedo rubykaigi0420140419 oedo rubykaigi04
20140419 oedo rubykaigi04Hiroshi SHIBATA
 
The Future of library dependency management of Ruby
 The Future of library dependency management of Ruby The Future of library dependency management of Ruby
The Future of library dependency management of RubyHiroshi SHIBATA
 
The Future of library dependency manageement of Ruby
The Future of library dependency manageement of RubyThe Future of library dependency manageement of Ruby
The Future of library dependency manageement of RubyHiroshi SHIBATA
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mrubyHiroshi SHIBATA
 
The Future of Dependency Management for Ruby
The Future of Dependency Management for RubyThe Future of Dependency Management for Ruby
The Future of Dependency Management for RubyHiroshi SHIBATA
 
tDiary annual report 2009 - Sapporo Ruby Kaigi02
tDiary annual report 2009 - Sapporo Ruby Kaigi02tDiary annual report 2009 - Sapporo Ruby Kaigi02
tDiary annual report 2009 - Sapporo Ruby Kaigi02Hiroshi SHIBATA
 
Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Hiroshi SHIBATA
 
Ruby in office time reboot
Ruby in office time rebootRuby in office time reboot
Ruby in office time rebootKentaro Goto
 
Improve extension API: C++ as better language for extension
Improve extension API: C++ as better language for extensionImprove extension API: C++ as better language for extension
Improve extension API: C++ as better language for extensionKouhei Sutou
 
20140626 red dotrubyconf2014
20140626 red dotrubyconf201420140626 red dotrubyconf2014
20140626 red dotrubyconf2014Hiroshi SHIBATA
 
Dependency Resolution with Standard Libraries
Dependency Resolution with Standard LibrariesDependency Resolution with Standard Libraries
Dependency Resolution with Standard LibrariesHiroshi SHIBATA
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the worldHiroshi SHIBATA
 

Was ist angesagt? (20)

OSS Security the hard way
OSS Security the hard wayOSS Security the hard way
OSS Security the hard way
 
20140425 ruby conftaiwan2014
20140425 ruby conftaiwan201420140425 ruby conftaiwan2014
20140425 ruby conftaiwan2014
 
How to develop Jenkins plugin using to ruby and Jenkins.rb
How to develop Jenkins plugin using to ruby and Jenkins.rbHow to develop Jenkins plugin using to ruby and Jenkins.rb
How to develop Jenkins plugin using to ruby and Jenkins.rb
 
20140419 oedo rubykaigi04
20140419 oedo rubykaigi0420140419 oedo rubykaigi04
20140419 oedo rubykaigi04
 
20140925 rails pacific
20140925 rails pacific20140925 rails pacific
20140925 rails pacific
 
What's new in RubyGems3
What's new in RubyGems3What's new in RubyGems3
What's new in RubyGems3
 
The Future of library dependency management of Ruby
 The Future of library dependency management of Ruby The Future of library dependency management of Ruby
The Future of library dependency management of Ruby
 
How DSL works on Ruby
How DSL works on RubyHow DSL works on Ruby
How DSL works on Ruby
 
The Future of library dependency manageement of Ruby
The Future of library dependency manageement of RubyThe Future of library dependency manageement of Ruby
The Future of library dependency manageement of Ruby
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mruby
 
The Future of Dependency Management for Ruby
The Future of Dependency Management for RubyThe Future of Dependency Management for Ruby
The Future of Dependency Management for Ruby
 
tDiary annual report 2009 - Sapporo Ruby Kaigi02
tDiary annual report 2009 - Sapporo Ruby Kaigi02tDiary annual report 2009 - Sapporo Ruby Kaigi02
tDiary annual report 2009 - Sapporo Ruby Kaigi02
 
Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0
 
From 'Legacy' to 'Edge'
From 'Legacy' to 'Edge'From 'Legacy' to 'Edge'
From 'Legacy' to 'Edge'
 
Ruby in office time reboot
Ruby in office time rebootRuby in office time reboot
Ruby in office time reboot
 
Gems on Ruby
Gems on RubyGems on Ruby
Gems on Ruby
 
Improve extension API: C++ as better language for extension
Improve extension API: C++ as better language for extensionImprove extension API: C++ as better language for extension
Improve extension API: C++ as better language for extension
 
20140626 red dotrubyconf2014
20140626 red dotrubyconf201420140626 red dotrubyconf2014
20140626 red dotrubyconf2014
 
Dependency Resolution with Standard Libraries
Dependency Resolution with Standard LibrariesDependency Resolution with Standard Libraries
Dependency Resolution with Standard Libraries
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the world
 

Andere mochten auch

AndApp開発における全て #denatechcon
AndApp開発における全て #denatechconAndApp開発における全て #denatechcon
AndApp開発における全て #denatechconDeNA
 
神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)guregu
 
Spiderストレージエンジンの使い方と利用事例 他ストレージエンジンの紹介
Spiderストレージエンジンの使い方と利用事例 他ストレージエンジンの紹介Spiderストレージエンジンの使い方と利用事例 他ストレージエンジンの紹介
Spiderストレージエンジンの使い方と利用事例 他ストレージエンジンの紹介Kentoku
 
AWS X-Rayによるアプリケーションの分析とデバッグ
AWS X-Rayによるアプリケーションの分析とデバッグAWS X-Rayによるアプリケーションの分析とデバッグ
AWS X-Rayによるアプリケーションの分析とデバッグAmazon Web Services Japan
 
MongoDBの可能性の話
MongoDBの可能性の話MongoDBの可能性の話
MongoDBの可能性の話Akihiro Kuwano
 
golang.tokyo #6 (in Japanese)
golang.tokyo #6 (in Japanese)golang.tokyo #6 (in Japanese)
golang.tokyo #6 (in Japanese)Yuichi Murata
 
ScalaからGoへ
ScalaからGoへScalaからGoへ
ScalaからGoへJames Neve
 
Operations: Production Readiness Review – How to stop bad things from Happening
Operations: Production Readiness Review – How to stop bad things from HappeningOperations: Production Readiness Review – How to stop bad things from Happening
Operations: Production Readiness Review – How to stop bad things from HappeningAmazon Web Services
 
Streaming Data Analytics with Amazon Redshift and Kinesis Firehose
Streaming Data Analytics with Amazon Redshift and Kinesis FirehoseStreaming Data Analytics with Amazon Redshift and Kinesis Firehose
Streaming Data Analytics with Amazon Redshift and Kinesis FirehoseAmazon Web Services
 
Apache Spark Streaming + Kafka 0.10 with Joan Viladrosariera
Apache Spark Streaming + Kafka 0.10 with Joan ViladrosarieraApache Spark Streaming + Kafka 0.10 with Joan Viladrosariera
Apache Spark Streaming + Kafka 0.10 with Joan ViladrosarieraSpark Summit
 
Swaggerでのapi開発よもやま話
Swaggerでのapi開発よもやま話Swaggerでのapi開発よもやま話
Swaggerでのapi開発よもやま話KEISUKE KONISHI
 
Fast and Reliable Swift APIs with gRPC
Fast and Reliable Swift APIs with gRPCFast and Reliable Swift APIs with gRPC
Fast and Reliable Swift APIs with gRPCTim Burks
 
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法Takuya Ueda
 
So You Wanna Go Fast?
So You Wanna Go Fast?So You Wanna Go Fast?
So You Wanna Go Fast?Tyler Treat
 
Solving anything in VCL
Solving anything in VCLSolving anything in VCL
Solving anything in VCLFastly
 

Andere mochten auch (20)

AndApp開発における全て #denatechcon
AndApp開発における全て #denatechconAndApp開発における全て #denatechcon
AndApp開発における全て #denatechcon
 
SLOのすすめ
SLOのすすめSLOのすすめ
SLOのすすめ
 
神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)
 
Spiderストレージエンジンの使い方と利用事例 他ストレージエンジンの紹介
Spiderストレージエンジンの使い方と利用事例 他ストレージエンジンの紹介Spiderストレージエンジンの使い方と利用事例 他ストレージエンジンの紹介
Spiderストレージエンジンの使い方と利用事例 他ストレージエンジンの紹介
 
AWS X-Rayによるアプリケーションの分析とデバッグ
AWS X-Rayによるアプリケーションの分析とデバッグAWS X-Rayによるアプリケーションの分析とデバッグ
AWS X-Rayによるアプリケーションの分析とデバッグ
 
Blockchain on Go
Blockchain on GoBlockchain on Go
Blockchain on Go
 
MongoDBの可能性の話
MongoDBの可能性の話MongoDBの可能性の話
MongoDBの可能性の話
 
golang.tokyo #6 (in Japanese)
golang.tokyo #6 (in Japanese)golang.tokyo #6 (in Japanese)
golang.tokyo #6 (in Japanese)
 
ScalaからGoへ
ScalaからGoへScalaからGoへ
ScalaからGoへ
 
What’s New in Amazon Aurora
What’s New in Amazon AuroraWhat’s New in Amazon Aurora
What’s New in Amazon Aurora
 
Operations: Production Readiness Review – How to stop bad things from Happening
Operations: Production Readiness Review – How to stop bad things from HappeningOperations: Production Readiness Review – How to stop bad things from Happening
Operations: Production Readiness Review – How to stop bad things from Happening
 
Streaming Data Analytics with Amazon Redshift and Kinesis Firehose
Streaming Data Analytics with Amazon Redshift and Kinesis FirehoseStreaming Data Analytics with Amazon Redshift and Kinesis Firehose
Streaming Data Analytics with Amazon Redshift and Kinesis Firehose
 
Apache Spark Streaming + Kafka 0.10 with Joan Viladrosariera
Apache Spark Streaming + Kafka 0.10 with Joan ViladrosarieraApache Spark Streaming + Kafka 0.10 with Joan Viladrosariera
Apache Spark Streaming + Kafka 0.10 with Joan Viladrosariera
 
Microservices at Mercari
Microservices at MercariMicroservices at Mercari
Microservices at Mercari
 
Swaggerでのapi開発よもやま話
Swaggerでのapi開発よもやま話Swaggerでのapi開発よもやま話
Swaggerでのapi開発よもやま話
 
Fast and Reliable Swift APIs with gRPC
Fast and Reliable Swift APIs with gRPCFast and Reliable Swift APIs with gRPC
Fast and Reliable Swift APIs with gRPC
 
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法
 
So You Wanna Go Fast?
So You Wanna Go Fast?So You Wanna Go Fast?
So You Wanna Go Fast?
 
Solving anything in VCL
Solving anything in VCLSolving anything in VCL
Solving anything in VCL
 
Google Home and Google Assistant Workshop: Build your own serverless Action o...
Google Home and Google Assistant Workshop: Build your own serverless Action o...Google Home and Google Assistant Workshop: Build your own serverless Action o...
Google Home and Google Assistant Workshop: Build your own serverless Action o...
 

Ähnlich wie An introduction and future of Ruby coverage library

Behavior Driven Development - TdT@Cluj #15
Behavior Driven Development - TdT@Cluj #15Behavior Driven Development - TdT@Cluj #15
Behavior Driven Development - TdT@Cluj #15Tabăra de Testare
 
Node.js Deeper Dive
Node.js Deeper DiveNode.js Deeper Dive
Node.js Deeper DiveJustin Reock
 
2016 07 - CloudBridge Python library (XSEDE16)
2016 07 - CloudBridge Python library (XSEDE16)2016 07 - CloudBridge Python library (XSEDE16)
2016 07 - CloudBridge Python library (XSEDE16)Enis Afgan
 
Getting your mobile test automation process in place - using Cucumber and Cal...
Getting your mobile test automation process in place - using Cucumber and Cal...Getting your mobile test automation process in place - using Cucumber and Cal...
Getting your mobile test automation process in place - using Cucumber and Cal...Niels Frydenholm
 
TDD on OSGi, in practice.
TDD on OSGi, in practice.TDD on OSGi, in practice.
TDD on OSGi, in practice.Elian, I.
 
Cloud Native CI/CD with Spring Cloud Pipelines
Cloud Native CI/CD with Spring Cloud PipelinesCloud Native CI/CD with Spring Cloud Pipelines
Cloud Native CI/CD with Spring Cloud PipelinesLars Rosenquist
 
Cloud Native CI/CD with Spring Cloud Pipelines
Cloud Native CI/CD with Spring Cloud PipelinesCloud Native CI/CD with Spring Cloud Pipelines
Cloud Native CI/CD with Spring Cloud PipelinesLars Rosenquist
 
Exploring Ruby on Rails and PostgreSQL
Exploring Ruby on Rails and PostgreSQLExploring Ruby on Rails and PostgreSQL
Exploring Ruby on Rails and PostgreSQLBarry Jones
 
Virtual Meetup: Mule 4 Error Handling and Logging
Virtual Meetup: Mule 4 Error Handling and LoggingVirtual Meetup: Mule 4 Error Handling and Logging
Virtual Meetup: Mule 4 Error Handling and LoggingJimmy Attia
 
Groovy In the Cloud
Groovy In the CloudGroovy In the Cloud
Groovy In the CloudJim Driscoll
 
Pipeline 101 Lorelei Mccollum
Pipeline 101 Lorelei MccollumPipeline 101 Lorelei Mccollum
Pipeline 101 Lorelei MccollumLorelei McCollum
 
Devops - why, what and how?
Devops - why, what and how?Devops - why, what and how?
Devops - why, what and how?Malinda Kapuruge
 
ASP.NET MVC Best Practices malisa ncube
ASP.NET MVC Best Practices   malisa ncubeASP.NET MVC Best Practices   malisa ncube
ASP.NET MVC Best Practices malisa ncubeMalisa Ncube
 
Topic production code
Topic production codeTopic production code
Topic production codeKavi Kumar
 
Pragmatic Monolith-First, easy to decompose, clean architecture
Pragmatic Monolith-First, easy to decompose, clean architecturePragmatic Monolith-First, easy to decompose, clean architecture
Pragmatic Monolith-First, easy to decompose, clean architecturePiotr Pelczar
 
MvvmCross Introduction
MvvmCross IntroductionMvvmCross Introduction
MvvmCross IntroductionStuart Lodge
 
MvvmCross Seminar
MvvmCross SeminarMvvmCross Seminar
MvvmCross SeminarXamarin
 

Ähnlich wie An introduction and future of Ruby coverage library (20)

Cucumber in Practice(en)
Cucumber in Practice(en)Cucumber in Practice(en)
Cucumber in Practice(en)
 
Behavior Driven Development - TdT@Cluj #15
Behavior Driven Development - TdT@Cluj #15Behavior Driven Development - TdT@Cluj #15
Behavior Driven Development - TdT@Cluj #15
 
Node.js Deeper Dive
Node.js Deeper DiveNode.js Deeper Dive
Node.js Deeper Dive
 
2016 07 - CloudBridge Python library (XSEDE16)
2016 07 - CloudBridge Python library (XSEDE16)2016 07 - CloudBridge Python library (XSEDE16)
2016 07 - CloudBridge Python library (XSEDE16)
 
Getting your mobile test automation process in place - using Cucumber and Cal...
Getting your mobile test automation process in place - using Cucumber and Cal...Getting your mobile test automation process in place - using Cucumber and Cal...
Getting your mobile test automation process in place - using Cucumber and Cal...
 
TDD on OSGi, in practice.
TDD on OSGi, in practice.TDD on OSGi, in practice.
TDD on OSGi, in practice.
 
Cloud Native CI/CD with Spring Cloud Pipelines
Cloud Native CI/CD with Spring Cloud PipelinesCloud Native CI/CD with Spring Cloud Pipelines
Cloud Native CI/CD with Spring Cloud Pipelines
 
Cloud Native CI/CD with Spring Cloud Pipelines
Cloud Native CI/CD with Spring Cloud PipelinesCloud Native CI/CD with Spring Cloud Pipelines
Cloud Native CI/CD with Spring Cloud Pipelines
 
Exploring Ruby on Rails and PostgreSQL
Exploring Ruby on Rails and PostgreSQLExploring Ruby on Rails and PostgreSQL
Exploring Ruby on Rails and PostgreSQL
 
Virtual Meetup: Mule 4 Error Handling and Logging
Virtual Meetup: Mule 4 Error Handling and LoggingVirtual Meetup: Mule 4 Error Handling and Logging
Virtual Meetup: Mule 4 Error Handling and Logging
 
Groovy In the Cloud
Groovy In the CloudGroovy In the Cloud
Groovy In the Cloud
 
Pipeline 101 Lorelei Mccollum
Pipeline 101 Lorelei MccollumPipeline 101 Lorelei Mccollum
Pipeline 101 Lorelei Mccollum
 
Devops - why, what and how?
Devops - why, what and how?Devops - why, what and how?
Devops - why, what and how?
 
ASP.NET MVC Best Practices malisa ncube
ASP.NET MVC Best Practices   malisa ncubeASP.NET MVC Best Practices   malisa ncube
ASP.NET MVC Best Practices malisa ncube
 
Topic production code
Topic production codeTopic production code
Topic production code
 
Pragmatic Monolith-First, easy to decompose, clean architecture
Pragmatic Monolith-First, easy to decompose, clean architecturePragmatic Monolith-First, easy to decompose, clean architecture
Pragmatic Monolith-First, easy to decompose, clean architecture
 
MvvmCross Introduction
MvvmCross IntroductionMvvmCross Introduction
MvvmCross Introduction
 
MvvmCross Seminar
MvvmCross SeminarMvvmCross Seminar
MvvmCross Seminar
 
Design Patterns
Design PatternsDesign Patterns
Design Patterns
 
Javascript best practices
Javascript best practicesJavascript best practices
Javascript best practices
 

Mehr von mametter

error_highlight: User-friendly Error Diagnostics
error_highlight: User-friendly Error Diagnosticserror_highlight: User-friendly Error Diagnostics
error_highlight: User-friendly Error Diagnosticsmametter
 
TRICK 2022 Results
TRICK 2022 ResultsTRICK 2022 Results
TRICK 2022 Resultsmametter
 
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料mametter
 
Enjoy Ruby Programming in IDE and TypeProf
Enjoy Ruby Programming in IDE and TypeProfEnjoy Ruby Programming in IDE and TypeProf
Enjoy Ruby Programming in IDE and TypeProfmametter
 
TypeProf for IDE: Enrich Development Experience without Annotations
TypeProf for IDE: Enrich Development Experience without AnnotationsTypeProf for IDE: Enrich Development Experience without Annotations
TypeProf for IDE: Enrich Development Experience without Annotationsmametter
 
Ruby 3の型解析に向けた計画
Ruby 3の型解析に向けた計画Ruby 3の型解析に向けた計画
Ruby 3の型解析に向けた計画mametter
 
emruby: ブラウザで動くRuby
emruby: ブラウザで動くRubyemruby: ブラウザで動くRuby
emruby: ブラウザで動くRubymametter
 
Type Profiler: Ambitious Type Inference for Ruby 3
Type Profiler: Ambitious Type Inference for Ruby 3Type Profiler: Ambitious Type Inference for Ruby 3
Type Profiler: Ambitious Type Inference for Ruby 3mametter
 
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析mametter
 
Ruby 3の型推論やってます
Ruby 3の型推論やってますRuby 3の型推論やってます
Ruby 3の型推論やってますmametter
 
マニアックなRuby 2.7新機能紹介
マニアックなRuby 2.7新機能紹介マニアックなRuby 2.7新機能紹介
マニアックなRuby 2.7新機能紹介mametter
 
A Static Type Analyzer of Untyped Ruby Code for Ruby 3
A Static Type Analyzer of Untyped Ruby Code for Ruby 3A Static Type Analyzer of Untyped Ruby Code for Ruby 3
A Static Type Analyzer of Untyped Ruby Code for Ruby 3mametter
 
A Plan towards Ruby 3 Types
A Plan towards Ruby 3 TypesA Plan towards Ruby 3 Types
A Plan towards Ruby 3 Typesmametter
 
Ruby 3 の型解析に向けた計画
Ruby 3 の型解析に向けた計画Ruby 3 の型解析に向けた計画
Ruby 3 の型解析に向けた計画mametter
 
A Type-level Ruby Interpreter for Testing and Understanding
A Type-level Ruby Interpreter for Testing and UnderstandingA Type-level Ruby Interpreter for Testing and Understanding
A Type-level Ruby Interpreter for Testing and Understandingmametter
 
本番環境で使える実行コード記録機能
本番環境で使える実行コード記録機能本番環境で使える実行コード記録機能
本番環境で使える実行コード記録機能mametter
 
Transcendental Programming in Ruby
Transcendental Programming in RubyTranscendental Programming in Ruby
Transcendental Programming in Rubymametter
 
Cookpad Hackarade #04: Create Your Own Interpreter
Cookpad Hackarade #04: Create Your Own InterpreterCookpad Hackarade #04: Create Your Own Interpreter
Cookpad Hackarade #04: Create Your Own Interpretermametter
 
Ruby 3のキーワード引数について考える
Ruby 3のキーワード引数について考えるRuby 3のキーワード引数について考える
Ruby 3のキーワード引数について考えるmametter
 
TRICK 2018 results
TRICK 2018 resultsTRICK 2018 results
TRICK 2018 resultsmametter
 

Mehr von mametter (20)

error_highlight: User-friendly Error Diagnostics
error_highlight: User-friendly Error Diagnosticserror_highlight: User-friendly Error Diagnostics
error_highlight: User-friendly Error Diagnostics
 
TRICK 2022 Results
TRICK 2022 ResultsTRICK 2022 Results
TRICK 2022 Results
 
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
クックパッド春の超絶技巧パンまつり 超絶技巧プログラミング編 資料
 
Enjoy Ruby Programming in IDE and TypeProf
Enjoy Ruby Programming in IDE and TypeProfEnjoy Ruby Programming in IDE and TypeProf
Enjoy Ruby Programming in IDE and TypeProf
 
TypeProf for IDE: Enrich Development Experience without Annotations
TypeProf for IDE: Enrich Development Experience without AnnotationsTypeProf for IDE: Enrich Development Experience without Annotations
TypeProf for IDE: Enrich Development Experience without Annotations
 
Ruby 3の型解析に向けた計画
Ruby 3の型解析に向けた計画Ruby 3の型解析に向けた計画
Ruby 3の型解析に向けた計画
 
emruby: ブラウザで動くRuby
emruby: ブラウザで動くRubyemruby: ブラウザで動くRuby
emruby: ブラウザで動くRuby
 
Type Profiler: Ambitious Type Inference for Ruby 3
Type Profiler: Ambitious Type Inference for Ruby 3Type Profiler: Ambitious Type Inference for Ruby 3
Type Profiler: Ambitious Type Inference for Ruby 3
 
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
 
Ruby 3の型推論やってます
Ruby 3の型推論やってますRuby 3の型推論やってます
Ruby 3の型推論やってます
 
マニアックなRuby 2.7新機能紹介
マニアックなRuby 2.7新機能紹介マニアックなRuby 2.7新機能紹介
マニアックなRuby 2.7新機能紹介
 
A Static Type Analyzer of Untyped Ruby Code for Ruby 3
A Static Type Analyzer of Untyped Ruby Code for Ruby 3A Static Type Analyzer of Untyped Ruby Code for Ruby 3
A Static Type Analyzer of Untyped Ruby Code for Ruby 3
 
A Plan towards Ruby 3 Types
A Plan towards Ruby 3 TypesA Plan towards Ruby 3 Types
A Plan towards Ruby 3 Types
 
Ruby 3 の型解析に向けた計画
Ruby 3 の型解析に向けた計画Ruby 3 の型解析に向けた計画
Ruby 3 の型解析に向けた計画
 
A Type-level Ruby Interpreter for Testing and Understanding
A Type-level Ruby Interpreter for Testing and UnderstandingA Type-level Ruby Interpreter for Testing and Understanding
A Type-level Ruby Interpreter for Testing and Understanding
 
本番環境で使える実行コード記録機能
本番環境で使える実行コード記録機能本番環境で使える実行コード記録機能
本番環境で使える実行コード記録機能
 
Transcendental Programming in Ruby
Transcendental Programming in RubyTranscendental Programming in Ruby
Transcendental Programming in Ruby
 
Cookpad Hackarade #04: Create Your Own Interpreter
Cookpad Hackarade #04: Create Your Own InterpreterCookpad Hackarade #04: Create Your Own Interpreter
Cookpad Hackarade #04: Create Your Own Interpreter
 
Ruby 3のキーワード引数について考える
Ruby 3のキーワード引数について考えるRuby 3のキーワード引数について考える
Ruby 3のキーワード引数について考える
 
TRICK 2018 results
TRICK 2018 resultsTRICK 2018 results
TRICK 2018 results
 

Kürzlich hochgeladen

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 

Kürzlich hochgeladen (20)

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 

An introduction and future of Ruby coverage library

  • 1. An introduction and future of Ruby coverage library RubyKaigi 2017 (19th Sep. ) Yusuke Endoh (@mametter)
  • 2. Yusuke Endoh (@mametter) • Ruby committer (2008—) • Full-time Ruby committer (2017—) • My goal: make Ruby programs robust – Test coverage, and type system?
  • 3.
  • 4.
  • 5. Method. Put the cream cheese into the mixing bowl. Put the sour cream into the mixing bowl. Put the white sugar into the mixing bowl. Put the yogrut into the mixing bowl. Put the unsalted butter into the mixing bowl. Combine the milk. Put the cake flour into the mixing bowl. Combine the corn starch. Put the brown sugar into the mixing bowl. Combine the egg whites. Combine the egg yolks. Put the lemon juice into the mixing bowl. Stir for 7 minutes. Liquify the contents of the mixing bowl. Pour contents of the mixing bowl into the baking dish Bake the cake mixture. Watch the cake mixture until baked. Serves 4. Cheese cake in Chef. Ingredients. 100 g cream cheese 97 g sour cream 107 g yogrut 112 g white sugar 11 g brown sugar 37 g unsalted butter 37 g cake flour 3 g corn starch 3 ml milk 3 egg yolks 3 egg whites 10 ml lemon juice 0 g cake mixture Cooking time: 80 minutes. ‘d’ ‘a’ ‘k’ ‘p’ 11*3*3=99 ‘c’ 37*3=111 ‘o’ ¥n ‘o’ Push characters ‘¥n’ ‘d’ ‘a’ ‘p’ ‘k’ ‘o’ ‘o’ ‘c’ into the stack Convert them to a string and “serve” it. data code
  • 6. Esoteric Recipe • Polyglot of Chef and real recipe – Japanese version https://cookpad.com/ recipe/4649810 – English version https://cookpad.com/us/ recipes/3335222
  • 7. My main contributions for Ruby • Implementation of some features: keyword arguments, deadlock detection, etc. • Release management for Ruby 1.9.2 and 2.0.0 • Optcarrot: A NES emulator for Ruby3x3 benchmark • Enhancement of the test suite of Ruby • coverage.so: the core library for coverage measurement ’06B ’07A ’07B ’08A 60 70 80 90 100 coverage(%) 70% 85% line coverage
  • 8. Today’s theme • An introduction of test coverage • An improvement plan of Ruby’s coverage measurement feature towards 2.5
  • 9. Survey [1/3] • Q. Do you use Ruby/RoR in production? – Raise your hand, please!
  • 10. Survey [2/3] • Q. In those, do you test your code?
  • 11. Survey [3/3] • Q. In those, do you use “coverage”? – Do you check the result of SimpleCov?
  • 12. Agenda • What is coverage • How to understand and use coverage • The current status of Ruby coverage feature • The future plan of Ruby coverage feature • Conclusion
  • 13. Agenda ☞ What is coverage • How to understand and use coverage • The current status of Ruby coverage feature • The future plan of Ruby coverage feature • Conclusion
  • 14. What is coverage? • A measure of “goodness” of a test suite – Also called “test coverage” or “code coverage” • Allows you: – Find untested code – Decide whether your test suite is good enough or not yet • (This is arguable, but I think we can use it as an advice) • Types of coverage – Function coverage, line coverage, branch coverage, …
  • 15. Function coverage • How many functions are executed by the tests # code def foo; …; end # ✓ def bar; …; end # ✗ def baz; …; end # ✓ # test foo baz 2/3 (67%) • Advantage • Easy to understand • Easy to visualize • Disadvantage • Too weak as a measure
  • 16. Line coverage • How many lines are executed # code def foo(x) # ✓ if x == 0 # ✓ p :foo # ✗ else p :bar # ✓ end end # test foo(1) 3/4 (75%) Non-significant line is ignored • Advantage • Easy to understand • Easy to visualize • Disadvantage • Still weak as a measure • foo() if x == 0
  • 17. Branch coverage • How many branches are taken true and false # code def foo(x) p :foo if x == 0 # ✓ p :bar if x < 2 # ✗ end # test foo(0) foo(1) 1/2 (50%) • Advantage • Relatively exhaustive • Disadvantage • Difficult to visualize true-case and false-case are both executed
  • 18. Coverage types Coverage type Easy to understand/ visualize Exhaustive Function coverage ○ ✕ Line coverage ○ △ Branch coverage △ ○ Currently, Ruby supports only line coverage
  • 19. Other types of coverage • Condition coverage – How many conditions (not branches) are taken both true and false • Path coverage – How many paths are executed – Combinatorial explosion • Other advanced ones – Data-flow coverage – MC/DC coverage if a && b branch conditioncondition
  • 20. Trivia • “C0/C1/C2 coverages” have difference meanings to different people – C0 coverage = line coverage – C1 coverage = branch coverage or path coverage? – C2 coverage = condition coverage or path coverage?
  • 21. Coverage and Ruby • In Ruby, Coverage is crucial! – A test is the only way to ensure quality – Coverage is important to measure test goodness • Considering it, coverage is not used so much… – Coverage is not well-known? – It is not well-known how to use coverage? – Ruby’s coverage measurement feature is not enough? • I’d like to improve the situation with this talk
  • 22. Agenda • What is coverage ☞ How to understand and use coverage • The current status of Ruby coverage feature • The future plan of Ruby coverage feature • Conclusion
  • 23. What is a good test suite? • Covers the code – Coverage measures this • Also covers the design of program – Coverage does not measure this directly
  • 24. How to understand coverage • Coverage is just a measure • Coverage is not a goal
  • 25. If coverage XX% is required as a goal… • Developers will 1. Pick untested code that looks easiest to cover 2. Write a trivial test just for the code 3. Iterate this procedure until XX% is achieved • It will result in trivial, not-so-good test suite – It may be exhaustive for the code itself, but – It won't be exhaustive for the design
  • 26. A good way to improve coverage • Developers should 1. Look at untested code 2. Consider what “test design” is insufficient 3. Write them – In consequence of them, the untested code is executed • It will result in good test suite – It will be exhaustive not only for the code but also for the design
  • 27. How many % is needed/enough? • It depends upon the module being tested – Aim 100% for a significant module (e.g., injure someone) – Don't worry too much for a non-significant module • It also depends upon cost performance – For non-significant module, write a test only if it is not so hard • Again: Coverage is not a goal
  • 28. Agenda • What is coverage • How to understand and use coverage ☞ The current status of Ruby coverage feature • The future plan of Ruby coverage feature • Conclusion
  • 29. Ruby's coverage ecosystem • SimpleCov • coverage.so • Concov
  • 30. SimpleCov • A wrapper library for coverage.so • Visualization with HTML • Useful features: merging, filtering, for Rails app • Author: Christoph Olszowka (@colszowka)
  • 31. Usage of SimpleCov • Write this at the top of test/test_helper.rb • Run the test suite • coverage/index.html will be produced – Note: SimpleCov cannot measure already- loaded files before SimpleCov.start require "simplecov" SimpleCov.start
  • 32. coverage.so • The only implementation of coverage measurement for Ruby 1.9+ • SimpleCov is a wrapper for coverage.so • Author: me
  • 33. Basic usage # test.rb require "coverage" Coverage.start load "target.rb" p Coverage.result #=> {"target.rb"=> # [nil,nil,1,1,1,nil, # 0,nil,nil,nil,1]} Start measuring coverage Load the target file Stop measuring and get the result Coverage data
  • 34. Coverage data # target.rb def foo(x) if x == 0 p 0 else p 1 end end foo(1) [nil, nil 1 1 0 nil 1 nil nil nil 1] nil: Non-significant line Number: Count executed Untested line!
  • 35. Method definition is code in Ruby # target.rb def foo(x) if x == 0 p 0 else p 1 end end [nil, nil 1 0 0 nil 0 nil nil] Method definition is counted as an execution (It is not a count of method invocation!)
  • 36. I regret the design of coverage.so • Support only line coverage • Excuse: I introduced it just for test enhancement of Ruby itself – I didn't deliberate the API for external project… • I have wanted to make the next version better ext/coverage/coverage.c: 69 /* Coverage provides coverage measurement feature for Ruby. 70 * This feature is experimental, so these APIs may be changed in future. 71 *
  • 37. Concov • CONtinuous COVerage – Detects temporal change (degradation) of coverage • Developed for monitoring Ruby's coverage • Author: me • Presented at RubyKaigi 2009, and then… – It has not been used by everyone (including me) – It was based on Ramaze (old web framework)!
  • 38. Concov reveals reality of Ruby dev. (Enumerable#join, 2009/07/07, M***) New feature introduced with no tests!
  • 39. Concov reveals reality of Ruby dev. (File#size, 2009/02/25, M***)
  • 40. Concov reveals reality of Ruby dev. (Etc::Passwd.each, 2009/02/19, N*****)
  • 41. Concov reveals reality of Ruby dev. (Dir.home, 2009/02/03, N*****)
  • 42. Concov reveals reality of Ruby dev. (Array#sort_by!, 2009/02/03, M***)
  • 43. Concov reveals reality of Ruby dev. (rb_to_float, 2008/12/30, M***)
  • 44. Coverage ecosystem for other languages • C/C++: GCOV/LCOV – Integrated with gcc: gcc -coverage target.c • Java: A lot of tools – Cobertura, Emma, Clover, JaCoCo – Integrated with CI tools and/or IDEs • JavaScript: Istanbul Jenkins Cobertura plugin LCOV result
  • 45. Agenda • What is coverage • How to understand and use coverage • The current status of Ruby coverage feature ☞ The future plan of Ruby coverage feature • Conclusion
  • 46. A plan towards Ruby 2.5 • Support function and branch coverage – There have been multiple requests and some PoC patches… • To make the API better, any comments are welcome – https://bugs.ruby-lang.org/issues/13901
  • 47. API: to start measuring # compatible layer Coverage.start Coverage.result #=> {"file.rb"=>[nil, 1, 0, …], … } # new API Coverage.start(lines: true) Coverage.result #=> {"file.rb" => { :lines => [nil, 1, 0, …] } }
  • 48. API: to start other types of coverage # enable branch and function coverage Coverage.start(lines:true, branches:true, methods:true) Coverage.result #=> {"file.rb" => { :lines => [nil, 1, 0, …], # :branches => {…}, # :methods => {…} } } # shorthand Coverage.start(:all)
  • 49. Coverage.result for branch coverage {"target1.rb"=> {:lines=>[…], :branches=>{ [:if, 0, 2]=>{ [:then, 1, 3]=>2, [:else, 2, 5]=>1 } }, :methods=>{ [:test_if, 1]=>3 }}} # target1.rb 1: def test_if(x) 2: if x == 0 3: p "x == 0" 4: else 5: p "x != 0" 6: end 7: end 8: 9: test_if(0) 10: test_if(0) 11: test_if(1) From if at Line 2 Jumped to then clause at Line 3 twice Jumped to else clause at Line 5 once
  • 50. Coverage.result for branch coverage {"target2.rb"=> {:lines=>[1, 1, 1, nil, nil, 1], :branches=> {[:if, 0, 2]=>{ [:then, 1, 2]=>1, [:else, 2, 2]=>0}, [:if, 3, 3]=>{ [:then, 4, 3]=>0, [:else, 5, 3]=>1}}, :methods=>{ [:test_if, 1]=>3 }}} # target2.rb 1: def test_if_oneline(x) 2: p "x == 0" if x == 0 3: p "x != 0" if x != 0 4: end 5: 6: test_if_oneline(0) Line coverage 100% Branch coverage tells you there are untested cases
  • 51. Discussion of API design • 100% compatible • [<label>, <numbering>, <line-no>] – e.g., [:if, 0, 1], [:while, 1, 1], [:case, 2, 1] – <numbering> is a unique ID to avoid conflicts for the case where there are multiple branches in one line • LCOV-style – Other candidates: • [<label>, <line-no>, <column-no>] – How to handle TAB character • [<label>, <offset from file head>] – Looks good, but hard to implement (I'll try later)
  • 52. Overhead of coverage measurement (just preliminary experiment) # Example 2 1: foo() 2: foo() … 99: foo() 100: foo() Benchmark w/o cov. w/ cov. Overhead Example 1 0.322 μs 6.21 μs x19.3 Example 2 1.55 μs 7.16 μs x4.61 make test-all 485 s 550 s x1.13 # Example 1 1: x = 1 2: x = 1 … 99: x = 1 100: x = 1
  • 53. Demo • Applied the new coverage.so to Ruby • Integrated with C code coverage by GCOV and Visualized by LCOV Ruby code in stdlib make exam with gcc -coverage make exam COVERAGE=1 test- coverage .dat *.gcda gcov my script run test C code of MRI cov. datasource aggregate lcov HTML
  • 55. Agenda • What is coverage • How to understand and use coverage • The current status of Ruby coverage feature • The future plan of Ruby coverage feature ☞ Conclusion
  • 56. Acknowledgement • @_ko1 • @t_wada • @kazu_cocoa • @moro • @makimoto • @dev_shia • @tanaka_akr • @nalsh • @spikeolaf • @k_tsj
  • 57. Conclusion • What is coverage, how important in Ruby, and how to understand coverage • The current status of Ruby's coverage measurement and ecosystem • A plan towards Ruby 2.5 and preliminary demo – Any comments are welcome! – https://bugs.ruby-lang.org/issues/13901
  • 58. Future work • Determine the API • define_method as method coverage • &. as branch coverage • Callsite coverage • Block coverage obj.foo.bar ary.map { …… }