SlideShare una empresa de Scribd logo
1 de 72
Descargar para leer sin conexión
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!()

Más contenido relacionado

Similar a 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
 

Similar a 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
 

Último

Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
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
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
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
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfOverkill Security
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 

Último (20)

Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
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
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
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
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 

Straight Up RSpec 3 - a neat Ruby BDD tool