SlideShare une entreprise Scribd logo
1  sur  72
Télécharger pour lire hors ligne
Straight Up RSpec 3
a neat Ruby BDD tool
Organization $0
Running Specs $0
Configuration $0
Refactoring Exercise $0
Other Libraries $0
The Menu
Organization
.rspec	
lib/…	
spec/spec_helper.rb	
spec/support/matchers/drink.rb	
spec/martini_spec.rb
spec_helper.rb
require 'barkeep'	
!
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].	
each {|file| require file }	
spec_helper
Running Specs
.rspec
--color	
--warnings	
--require spec_helper
.rspec
.rspec-local
—-format documentation	
--backtrace
.rspec-local
$ rspec spec/martini_spec.rb:15:22
$ rspec --format documentation
$ rspec --fail-fast
$ rspec --tag js:true
$ rspec --profile	
…	
!
Top 10 slowest examples (0.00226 seconds, 57.2% of total time):	
Martini with a mixer #ingredients should include "vermouth"	
0.00058 seconds ./spec/martini_spec.rb:15	
InitializeWithAttrsSpec with attributes #pages should eq 123	
0.00052 seconds ./spec/initialize_with_attrs_spec.rb:16	
…
$ rspec --order random	
…	
Randomized with seed 63958
$ rspec --order random:63958
martini_spec.rb
describe "Martini" do	
	 …	
it "should have ingredients", :focus do	
expect(martini).to respond_to(:ingredients)	
end	
	 …	
end
:focus
martini_spec.rb
describe "Martini" do	
	 …	
fit "should have ingredients" do	
expect(martini).to respond_to(:ingredients)	
end	
	 …	
end
fit
martini_spec.rb
describe "Martini" do	
	 …	
it "should have ingredients", :skip do	
expect(martini).to respond_to(:ingredients)	
end	
	 …	
end
:skip
martini_spec.rb
describe "Martini" do	
	 …	
xit "should have ingredients" do	
expect(martini).to respond_to(:ingredients)	
end	
	 …	
end
xit
martini_spec.rb
describe "Martini" do	
	 …	
pending "should have price" do	
expect(@martini).to be_pricey	
end	
	 …	
end
pending
Configuration
support/configure.rb
RSpec.configure do |config|	
config.include MyMartiniMatchers	
config.include ModelHelpers, :type => :model	
end	
!
!
# spec/model/martini_spec.rb	
!
describe Martini, :type => :model do	
…	
end	
RSpec.configure
support/configure.rb
RSpec.configure do |c|	
c.before(:suite) {} # once	
c.before(:context) {} # once before each group	
c.before(:example) {} # once before each example	
!
c.after(:example) {} # once after each example	
c.after(:context) {} # once after each group	
c.after(:suite) {} # once	
!
# run before each example of type :model	
config.before(:example, :type => :model) {}	
end	
RSpec.configure
support/configure.rb
RSpec.configure do |c|	
c.filter_run focus: true	
c.run_all_when_everything_filtered = true	
end	
!
# in any spec file	
describe "thing" do	
it "does something interesting", :focus do	
# ....	
end	
end
Inclusion
support/configure.rb
RSpec.configure do |c|	
c.exclusion_filter = { :ruby => lambda { |version|	
!(RUBY_VERSION.to_s =~ /^#{version.to_s}/)	
}}	
end	
!
# in any spec file	
describe "something" do	
it "does something", :ruby => 1.8 do	
# ....	
end	
it "does something", :ruby => 2.1 do	
# ....	
Exclusion
Barkeep
github.com/gsterndale/barkeep
an upgrade & refactoring exercise
martini_spec.rb
describe "Barkeep::Martini" do	
before do	
@martini = Barkeep::Martini.new	
end	
it "should have an attribute named booze" do	
@martini.should respond_to(:booze)	
@martini.should respond_to(:booze=)	
end	
it "should have an attribute named garnish" do	
@martini.should respond_to(:garnish)	
@martini.should respond_to(:garnish=)	
end	
end
Original Martini 2.X Spec
martini_spec.rb
describe "Barkeep::Martini" do	
before do	
@martini = Barkeep::Martini.new	
end	
it "should have an attribute named booze" do	
expect(@martini).to respond_to(:booze)	
expect(@martini).to respond_to(:booze=)	
end	
it "should have an attribute named garnish" do	
expect(@martini).to respond_to(:garnish)	
expect(@martini).to respond_to(:garnish=)	
end	
end	
Martini Spec 3.0
have_attribute.rb
module AttributeMatchers	
!
Spec::Matchers.define :have_attribute do |name|	
match do |target|	
getter = name.to_sym	
setter = (name.to_s + "=").to_sym	
target.respond_to?(getter) &&	
target.respond_to?(setter)	
end	
end	
!
end
Custom Matcher
martini_spec.rb
describe "Barkeep::Martini" do	
include AttributeMatchers	
before do	
@martini = Barkeep::Martini.new	
end	
it "should have an attribute named booze" do	
expect(@martini).to have_attribute(:booze)	
end	
it "should have an attribute named garnish" do	
expect(@martini).to have_attribute(:garnish)	
end	
end
Custom Matcher
martini_spec.rb
describe "Barkeep::Martini" do	
include AttributeMatchers	
subject { Barkeep::Martini.new }	
it "should have an attribute named booze" do	
expect(subject).to have_attribute(:booze)	
end	
it "should have an attribute named garnish" do	
expect(subject).to have_attribute(:garnish)	
end	
end
subject()
martini_spec.rb
describe "Barkeep::Martini" do	
include AttributeMatchers	
subject(:martini) { Barkeep::Martini.new }	
it "should have an attribute named booze" do	
expect(martini).to have_attribute(:booze)	
end	
it "should have an attribute named garnish" do	
expect(martini).to have_attribute(:garnish)	
end	
end
Named subject()
martini_spec.rb
describe "Barkeep::Martini" do	
include AttributeMatchers	
subject { Barkeep::Martini.new }	
it "should have an attribute named booze" do	
is_expected.to have_attribute(:booze)	
end	
it "should have an attribute named garnish" do	
is_expected.to have_attribute(:garnish)	
end	
end
Implicit subject()
martini_spec.rb
describe "Barkeep::Martini" do	
include AttributeMatchers	
subject { Barkeep::Martini.new }	
it { is_expected.to have_attribute(:booze) }	
it { is_expected.to have_attribute(:garnish) }	
end
DRY Messages
martini_spec.rb
describe Barkeep::Martini do	
include AttributeMatchers	
it { is_expected.to have_attribute(:booze) }	
it { is_expected.to have_attribute(:garnish) }	
end
Derived subject()
have_attribute.rb
module AttributeMatchers	
…	
end	
!
RSpec.configure do |config|	
config.include AttributeMatchers	
end
config.include()
martini_spec.rb
describe Barkeep::Martini do	
it { is_expected.to have_attribute(:booze) }	
it { is_expected.to have_attribute(:garnish) }	
end
config.include()
martini_spec.rb
describe "Barkeep::Martini" do	
before do	
@martini = Barkeep::Martini.new	
end	
it "should have an attribute named booze" do	
@martini.should respond_to(:booze)	
@martini.should respond_to(:booze=)	
end	
it "should have an attribute named garnish" do	
@martini.should respond_to(:garnish)	
@martini.should respond_to(:garnish=)	
end	
end
Original Martini 2.X Spec
martini_spec.rb
describe Barkeep::Martini do	
it { is_expected.to have_attribute(:booze) }	
it { is_expected.to have_attribute(:garnish) }	
end
Refactored Martini 3.0 Spec
whiskey_spec.rb
describe Barkeep::Whiskey do	
it { is_expected.to have_attribute(:booze) }	
it { is_expected.to have_attribute(:glass) }	
end
New Whiskey Spec
martini_spec.rb
describe Barkeep::Martini do	
it { is_expected.to have_attribute(:booze) }	
it { is_expected.to have_attribute(:glass) }	
it { is_expected.to have_attribute(:garnish) }	
end
Additions to Martini Spec
support/examples/drink.rb
shared_examples_for "a drink" do	
it { is_expected.to have_attribute(:booze) }	
it { is_expected.to have_attribute(:glass) }	
end
Shared Example Group
whiskey_spec.rb
describe Barkeep::Whiskey do	
it_behaves_like "a drink"	
end
Whiskey Spec
whiskey_spec.rb
describe Barkeep::Whiskey do	
include_examples "a drink"	
end
Whiskey Spec
martini_spec.rb
describe Barkeep::Martini do	
it_behaves_like "a drink"	
it { is_expected.to have_attribute(:garnish) }	
end
Martini Spec
support/examples/drink.rb
shared_examples_for "a drink" do |ingredients|	
it { is_expected.to have_attribute(:booze) }	
it { is_expected.to have_attribute(:glass) }	
!
describe "#ingredients" do	
subject { super().ingredients }	
it { is_expected.to be_a Array }	
it { is_expected to include *ingredients }	
end	
end
Whiskey & Martini #ingredients
martini_spec.rb
describe Barkeep::Martini do	
it_behaves_like "a drink", "vodka"	
it { is_expected.to have_attribute(:garnish) }	
end
Martini Spec
martini_spec.rb
describe Barkeep::Martini do	
it_behaves_like "a drink"	
it { is_expected.to have_attribute(:garnish) }	
it { is_expected.to have_attribute(:mixer) }	
context "with a mixer" do	
before do	
@mixer = 'vermouth'	
subject.mixer = @mixer	
end	
it "should include mixer in ingredients" do	
expect(subject.ingredients).to include @mixer	
end	
end	
context()
martini_spec.rb
describe Barkeep::Martini do	
it_behaves_like "a drink"	
it { is_expected.to have_attribute(:garnish) }	
it { is_expected.to have_attribute(:mixer) }	
context "with a mixer" do	
let(:mixer) { 'vermouth' }	
before { subject.mixer = mixer }	
!
it "should include mixer in ingredients" do	
expect(subject.ingredients).to include mixer	
end	
end	
end
let()
martini_spec.rb
describe Barkeep::Martini do	
it_behaves_like "a drink"	
it { is_expected.to have_attribute(:garnish) }	
it { is_expected.to have_attribute(:mixer) }	
context "with a mixer" do	
let(:mixer) { 'vermouth' }	
before { subject.mixer = mixer }	
!
its(:ingredients) { is_expected.to 	
	 	 	 	 	 	 	 	 	 include mixer }	
end	
end
its()
martini_spec.rb
describe Barkeep::Martini do	
it_behaves_like "a drink"	
it { is_expected.to have_attribute(:garnish) }	
it { is_expected.to have_attribute(:mixer) }	
end	
!
describe Barkeep::Martini, ".new with mixer" do	
let(:mixer) { 'vermouth' }	
subject { Barkeep::Martini.new(mixer: mixer) }	
its(:ingredients) { is_expected.to include mixer }	
end
its()
martini_spec.rb
describe Barkeep::Martini, ".new with mixer" do	
let(:mixer) { 'vermouth' }	
subject { Barkeep::Martini.new(:mixer => mixer) }	
its(:ingredients) { is_expected.to include mixer }	
its(:ingredients) { is_expected.to have(1).items }	
end
have()
martini_spec.rb
describe Barkeep::Martini, ".new with mixer" do	
let(:mixer) { 'vermouth' }	
subject { Barkeep::Martini.new(:mixer => mixer) }	
its(:ingredients) { is_expected.to include mixer }	
it { is_expected.to have(1).ingredients }	
end
have()
martini_spec.rb
describe Barkeep::Martini, ".dirty" do	
let(:martini) { Barkeep::Martini.dirty }	
subject { martini.ingredients }	
!
it { is_expected.to include 	
'juice', 'vodka', 'olives', 'vermouth' }	
!
it { is_expected.to contain_exactly 	
'vodka', 'vermouth', 'juice', 'olives' }	
end
Array Matchers
martini_spec.rb
describe Barkeep::Martini, ".dirty" do	
let(:martini) { Barkeep::Martini.dirty }	
subject { martini.ingredients }	
!
it { is_expected.to start_with 'vodka' }	
it { is_expected.to end_with 'olives' }	
end
Array Matchers
martini_spec.rb
describe Barkeep::Martini, ".dirty" do	
let(:martini) { Barkeep::Martini.dirty }	
subject { martini.ingredients }	
!
it { is_expected.to all be_a(String) }	
it { is_expected.to all start_with(/^w/) }	
end
Array Matchers
martini_spec.rb
describe Barkeep::Martini, ".dirty" do	
let(:martini) { Barkeep::Martini.dirty }	
subject { martini.ingredients }	
!
it { is_expected.to all 	
be_a(String) & start_with(/^w/) }	
end
Compound Matchers
martini_spec.rb
describe Barkeep::Martini, ".dirty" do	
let(:martini) { Barkeep::Martini.dirty }	
subject { martini.ingredients }	
!
it { is_expected.to match [	
start_with(/^w/),	
match(/olives?/)	
] }	
end
Composable Matchers
martini_spec.rb
describe Barkeep::Martini, ".dirty" do	
let(:martini) { Barkeep::Martini.dirty }	
subject { martini.ingredients }	
!
it { is_expected.to match [	
a_string_starting_with(/^w/),	
a_string_matching(/olives?/)	
] }	
end
Composable Matchers
terminal_spec.rb
describe Terminal, "#printer" do	
let(:epson) { stub "Espon 5000" }	
let(:terminal) { Terminal.new(:ip => "1.1.1.1") }	
subject { terminal.printer }	
!
before do	
Printer.stub(:by_ip).and_return(epson)	
end	
!
it { should eq epson }	
end	
RSpec 2.X doubles
terminal_spec.rb
describe Terminal, "#printer" do	
let(:epson) { double "Espon 5000" }	
let(:terminal) { Terminal.new(:ip => "1.1.1.1") }	
subject { terminal.printer }	
!
before do	
allow(Printer).to receive_messages(by_ip: epson)	
end	
!
it { is_expected.to eq epson }	
end	
RSpec 3.0 doubles
terminal_spec.rb
describe Terminal, "#printer" do	
let(:epson) { double "Espon 5000" }	
let(:terminal) { Terminal.new(:ip => "1.1.1.1") }	
subject { terminal.printer }	
!
before do	
allow(Printer).to receive_messages(by_ID: epson)	
end	
!
it { is_expected.to eq epson }	
end	
Double checking™
terminal_spec.rb
describe Terminal, "#printer" do	
let(:epson) { stub "Espon 5000" }	
let(:terminal) { Terminal.new(:ip => "1.1.1.1") }	
subject { terminal.printer }	
!
before do	
Printer.should_receive(:by_ip)	
.with("1.1.1.1").and_return(epson)	
end	
!
it { should eq epson }	
end
RSpec 2.X message expectation
terminal_spec.rb
describe Terminal, "#printer" do	
let(:epson) { double "Espon 5000" }	
let(:terminal) { Terminal.new(:ip => "1.1.1.1") }	
before do	
allow(Printer).to receive_messages(by_ip: epson)	
end	
subject! { terminal.printer }	
!
it { is_expected.to eq epson }	
it "finds printer by IP" do	
expect(Printer).to 	
have_received(:by_ip).with("1.1.1.1")	
end	
RSpec 3.0 message expectation
Links
support/configure.rb
Its:	
github.com/rspec/rspec-its	
!
Collection Matchers:	
github.com/rspec/rspec-collection_matchers	
!
RSpec Rails:	
github.com/rspec/rspec-rails	
!
ActiveModel mocks:	
github.com/rspec/rspec-activemodel-mocks
Libraries
support/configure.rb
Step-by-step upgrade instructions:	
relishapp.com/rspec/docs/upgrade	
!
RDoc:	
rubydoc.info/github/rspec/rspec-expectations	
!
Features as documentation:	
relishapp.com/rspec
Documentation
support/configure.rb
Transpec, the RSpec syntax conversion tool:	
yujinakayama.me/transpec/	
!
Myron Marston’s blog:	
myronmars.to
Resources
CHEERS
spec/user_spec.rb
describe User, ".admin_names" do	
let(:admin) { User.create!(:admin => true,	
:first => "Clark",	
:last => "Kent")}	
let(:avg_joe) { User.create!(:admin => false,	
:first => "Joe",	
:last => "Shmo")}	
subject { admin_names }	
!
it { should include "Clark Kent" }	
it { should_not include "Joe Shmo" }	
end
let() gotcha
spec/user_spec.rb
describe User, ".admin_names" do	
let(:admin) { User.create!(:admin => true,	
:first => "Clark",	
:last => "Kent")}	
let(:avg_joe) { User.create!(:admin => false,	
:first => "Joe",	
:last => "Shmo")}	
subject { User.admin_names }	
before { admin && avg_joe }	
!
it { should include "Clark Kent" }	
it { should_not include "Joe Shmo" }	
end
let() work-around
spec/user_spec.rb
describe User, ".admin_names" do	
let!(:admin) { User.create!(:admin => true,	
:first => "Clark",	
:last => "Kent")}	
let!(:avg_joe) { User.create!(:admin => false,	
:first => "Joe",	
:last => "Shmo")}	
subject { User.admin_names }	
!
it { should include "Clark Kent" }	
it { should_not include "Joe Shmo" }	
end
let!()

Contenu connexe

Similaire à Straight Up RSpec 3 - a neat Ruby BDD tool

mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introductionTse-Ching Ho
 
Apache Spark for Library Developers with Erik Erlandson and William Benton
Apache Spark for Library Developers with Erik Erlandson and William BentonApache Spark for Library Developers with Erik Erlandson and William Benton
Apache Spark for Library Developers with Erik Erlandson and William BentonDatabricks
 
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with CucumberBen Mabey
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Coxlachie
 
Angular.js Fundamentals
Angular.js FundamentalsAngular.js Fundamentals
Angular.js FundamentalsMark
 
Open Source Saturday - How can I contribute to Ruby on Rails?
Open Source Saturday - How can I contribute to Ruby on Rails?Open Source Saturday - How can I contribute to Ruby on Rails?
Open Source Saturday - How can I contribute to Ruby on Rails?Pravin Mishra
 
Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)Joao Lucas Santana
 
Making and Breaking Web Services with Ruby
Making and Breaking Web Services with RubyMaking and Breaking Web Services with Ruby
Making and Breaking Web Services with Rubyerr
 
浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編
浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編
浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編Masakuni Kato
 
Rspec presentation
Rspec presentationRspec presentation
Rspec presentationMyo T Kyaw
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientLightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientAdam Wiggins
 
Your own (little) gem: building an online business with Ruby
Your own (little) gem: building an online business with RubyYour own (little) gem: building an online business with Ruby
Your own (little) gem: building an online business with RubyLindsay Holmwood
 
浜松Rails3道場 其の参 Controller編
浜松Rails3道場 其の参 Controller編浜松Rails3道場 其の参 Controller編
浜松Rails3道場 其の参 Controller編Masakuni Kato
 
Merb Slices
Merb SlicesMerb Slices
Merb Sliceshassox
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the FinishYehuda Katz
 
Ruby sittin' on the Couch
Ruby sittin' on the CouchRuby sittin' on the Couch
Ruby sittin' on the Couchlangalex
 
Rspec API Documentation
Rspec API DocumentationRspec API Documentation
Rspec API DocumentationSmartLogic
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialYi-Ting Cheng
 

Similaire à Straight Up RSpec 3 - a neat Ruby BDD tool (20)

mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introduction
 
Apache Spark for Library Developers with Erik Erlandson and William Benton
Apache Spark for Library Developers with Erik Erlandson and William BentonApache Spark for Library Developers with Erik Erlandson and William Benton
Apache Spark for Library Developers with Erik Erlandson and William Benton
 
Writing Software not Code with Cucumber
Writing Software not Code with CucumberWriting Software not Code with Cucumber
Writing Software not Code with Cucumber
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
Angular.js Fundamentals
Angular.js FundamentalsAngular.js Fundamentals
Angular.js Fundamentals
 
Open Source Saturday - How can I contribute to Ruby on Rails?
Open Source Saturday - How can I contribute to Ruby on Rails?Open Source Saturday - How can I contribute to Ruby on Rails?
Open Source Saturday - How can I contribute to Ruby on Rails?
 
Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)
 
Making and Breaking Web Services with Ruby
Making and Breaking Web Services with RubyMaking and Breaking Web Services with Ruby
Making and Breaking Web Services with Ruby
 
浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編
浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編
浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編
 
Rspec presentation
Rspec presentationRspec presentation
Rspec presentation
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientLightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClient
 
Your own (little) gem: building an online business with Ruby
Your own (little) gem: building an online business with RubyYour own (little) gem: building an online business with Ruby
Your own (little) gem: building an online business with Ruby
 
浜松Rails3道場 其の参 Controller編
浜松Rails3道場 其の参 Controller編浜松Rails3道場 其の参 Controller編
浜松Rails3道場 其の参 Controller編
 
Merb Slices
Merb SlicesMerb Slices
Merb Slices
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
Ruby sittin' on the Couch
Ruby sittin' on the CouchRuby sittin' on the Couch
Ruby sittin' on the Couch
 
Ruby gems
Ruby gemsRuby gems
Ruby gems
 
Rspec API Documentation
Rspec API DocumentationRspec API Documentation
Rspec API Documentation
 
RSpec. Part 2
RSpec. Part 2RSpec. Part 2
RSpec. Part 2
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails Turtorial
 

Dernier

The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 

Dernier (20)

The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 

Straight Up RSpec 3 - a neat Ruby BDD tool