RSpec Best Friends @ TDC Florianópolis 2014

Mauro George
Mauro GeorgeDesenvolvedor em Estou Jogando
RSpec Best Friends
Mauro quem...
RSpec Best Friends @ TDC Florianópolis 2014
RSpec Best Friends @ TDC Florianópolis 2014
RSpec Best Friends @ TDC Florianópolis 2014
RSpec Best
Friends
RSpec Best
Friends
maurogeorge.com.br
RSpec
sintaxe de expectativa
RSpec
spec/models/pokemon_spec.rb
it 'exibe o nome e o id nacional' do
pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6)
pokemon.nome_completo.should eq('Charizard - 6')
end
spec/models/pokemon_spec.rb
it 'exibe o nome e o id nacional' do
pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6)
expect(pokemon.nome_completo).to eq('Charizard - 6')
end
spec/models/pokemon_spec.rb
it { expect(subject).to be_a(ActiveRecord::Base) }
spec/models/pokemon_spec.rb
it { should be_a(ActiveRecord::Base) }
spec/models/pokemon_spec.rb
it { is_expected.to be_a(ActiveRecord::Base) }
Somente RSpec 3
spec/spec_helper.rb
RSpec.configure do |config|
# ...
config.expect_with :rspec do |c|
c.syntax = :expect
end
end
descrevendo melhor os testes
RSpec
spec/models/pokemon_spec.rb
it 'exibe o nome e o id nacional' do
pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6)
expect(pokemon.nome_completo).to eq('Charizard - 6')
end
spec/models/pokemon_spec.rb
describe '#nome_completo' do
it 'exibe o nome e o id nacional' do
pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6)
expect(pokemon.nome_completo).to eq('Charizard - 6')
end
end
não teste apenas o happy path
RSpec
spec/models/pokemon_spec.rb
describe '#nome_completo' do
it 'exibe o nome e o id nacional' do
pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6)
expect(pokemon.nome_completo).to eq('Charizard - 6')
end
end
spec/models/pokemon_spec.rb
describe '#nome_completo' do
it 'exibe o nome e o id nacional quando possui os valores' do
pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6)
expect(pokemon.nome_completo).to eq('Charizard - 6')
end
it 'é nil quando não possui o nome e o id nacional' do
pokemon = Pokemon.new
expect(pokemon.nome_completo).to be_nil
end
end
contextos para a melhor descrição
RSpec
spec/models/pokemon_spec.rb
describe '#nome_completo' do
context 'quando possui nome e o id nacional' do
it 'exibe o nome e o id nacional' do
# ...
end
end
context 'quando não possui o nome e o id nacional' do
it 'é nil' do
# ...
end
end
end
de!nindo o sujeito
RSpec
spec/models/pokemon_spec.rb
context 'quando possui nome e o id nacional' do
before do
@pokemon = Pokemon.new(nome: 'Charizard', id_nacional: 6)
end
it 'exibe o nome e o id nacional' do
expect(@pokemon.nome_completo).to eq('Charizard - 6')
end
end
spec/models/pokemon_spec.rb
context 'quando possui nome e o id nacional' do
let(:pokemon) do
Pokemon.new(nome: 'Charizard', id_nacional: 6)
end
it 'exibe o nome e o id nacional' do
expect(pokemon.nome_completo).to eq('Charizard - 6')
end
end
spec/models/pokemon_spec.rb
context 'quando possui nome e o id nacional' do
subject do
Pokemon.new(nome: 'Charizard', id_nacional: 6)
end
it 'exibe o nome e o id nacional' do
expect(subject.nome_completo).to eq('Charizard - 6')
end
end
utilize sempre os matchers
RSpec
spec/models/pokemon_spec.rb
it 'é nil' do
expect(subject.nome_completo).to eq(nil)
end
spec/models/pokemon_spec.rb
it 'é nil' do
expect(subject.nome_completo).to be_nil
end
não use should
RSpec
spec/models/pokemon_spec.rb
it 'should have the name and the national_id' do
expect(pokemon.full_name).to eq('Charizard - 6')
end
spec/models/pokemon_spec.rb
it 'does have the name and the national_id' do
expect(pokemon.full_name).to eq('Charizard - 6')
end
ordem aleatória nos testes
RSpec
spec/spec_helper.rb
RSpec.configure do |config|
# ...
config.order = "random"
end
coding style
RSpec
https://github.com/mongoid/mongoid
coding style
RSpec
https://github.com/mongoid/mongoid
https://github.com/bbatsov/ruby-style-guide
coding style
RSpec
https://github.com/mongoid/mongoid
https://github.com/bbatsov/ruby-style-guide
https://github.com/bbatsov/rails-style-guide
coding style
RSpec
Testes que acessam rede
introdução
Testes que acessam rede
Testes lentos
introdução
Testes que acessam rede
Testes lentos
Testes quebradiços
introdução
Testes que acessam rede
Testes lentos
Testes quebradiços
Não poder testar sem rede
introdução
Testes que acessam rede
app/services/criador_pokemon.rb
class CriadorPokemon
# ...
def criar
Pokemon.create(nome: nome)
end
private
# ...
def cria_info
resposta = Net::HTTP.get(endpoint)
@info = JSON.parse(resposta)
end
end
spec/services/criador_pokemon_spec.rb
describe 'pokemon criado' do
before do
criador_pokemon.criar
end
subject do
Pokemon.last
end
it 'possui o nome correto' do
expect(subject.nome).to eq('Charizard')
end
end
webmock
Testes que acessam rede
webmock: feedback rápido
Testes que acessam rede
bash
Failure/Error: CriadorPokemon.new(6)
WebMock::NetConnectNotAllowedError:
Real HTTP connections are disabled. Unregistered request: GET http://
pokeapi.co/api/v1/pokemon/6/ with headers {'Accept'=>'*/*', 'Accept-
Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'pokeapi.co', 'User-
Agent'=>'Ruby'}
You can stub this request with the following snippet:
stub_request(:get, "http://pokeapi.co/api/v1/pokemon/6/").
with(:headers => {'Accept'=>'*/*', 'Accept-
Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'pokeapi.co', 'User-
Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
webmock: forjando a resposta
Testes que acessam rede
spec/services/criador_pokemon_spec.rb
describe 'pokemon criado' do
before do
body = '{' 
' "name": "Charizard"' 
'}'
stub_request(:get, 'http://pokeapi.co/api/v1/pokemon/6/')
.to_return(status: 200, body: body, headers: {})
criador_pokemon.criar
end
end
webmock: forjando com cURL
Testes que acessam rede
bash
$ curl -is http://pokeapi.co/api/v1/pokemon/6/ > 
spec/fixtures/services/criador_pokemon/resposta.txt
spec/services/criador_pokemon_spec.rb
describe 'pokemon criado' do
before do
caminho_arquivo = 'spec/fixtures/services/criador_pokemon/resposta.txt'
arquivo_resposta = File.new(caminho_arquivo)
stub_request(:get, 'http://pokeapi.co/api/v1/pokemon/6/')
.to_return(arquivo_resposta)
criador_pokemon.criar
end
end
vcr
Testes que acessam rede
vcr: con!guração
Testes que acessam rede
spec/support/vcr.rb
VCR.configure do |c|
c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
c.hook_into :webmock
end
vcr: feedback rápido
Testes que acessam rede
bash
Failure/Error: CriadorPokemon.new(6)
VCR::Errors::UnhandledHTTPRequestError:
=====================================================================
An HTTP request has been made that VCR does not know how to handle:
GET http://pokeapi.co/api/v1/pokemon/6/
There is currently no cassette in use. There are a few ways
you can configure VCR to handle this request:
...
vcr: forjando a resposta
Testes que acessam rede
spec/services/criador_pokemon_spec.rb
describe 'pokemon criado' do
before do
VCR.use_cassette('CriadorPokemon/criar') do
criador_pokemon.criar
end
end
#...
it 'possui o nome correto' do
expect(subject.nome).to eq('Charizard')
end
end
vcr: RSpec metadata
Testes que acessam rede
spec/support/vcr.rb
VCR.configure do |c|
# ...
c.configure_rspec_metadata!
end
spec/spec_helper.rb
RSpec.configure do |config|
# ...
config.treat_symbols_as_metadata_keys_with_true_values = true
end
spec/services/criador_pokemon_spec.rb
describe 'pokemon criado', :vcr do
before do
criador_pokemon.criar
end
#...
it 'possui o nome correto' do
expect(subject.nome).to eq('Charizard')
end
end
factory_girl
!xtures X factories
factory_girl
criando uma factory
factory_girl
spec/factories/usuarios.rb
FactoryGirl.define do
factory :usuario do
nome 'Mauro'
email 'mauro@helabs.com.br'
end
end
console rails
FactoryGirl.create(:usuario)
FactoryGirl.create(:usuario, email: 'mauro@helabs.com.br')
con!gurando
factory_girl
spec/spec_helper.rb
RSpec.configure do |config|
# ...
config.include FactoryGirl::Syntax::Methods
end
Em um teste qualquer
let!(:artigo) do
create(:artigo)
end
attributes_for
factory_girl
spec/controllers/posts_controller_spec.rb
describe "POST 'create'" do
let(:params) do
{
artigo: {
titulo: 'Meu titulo',
conteudo: 'Conteudo do artigo'
}
}
end
end
spec/controllers/posts_controller_spec.rb
describe "POST 'create'" do
let(:params) do
{ artigo: attributes_for(:artigo) }
end
end
herança
factory_girl
spec/factories/artigos.rb
factory :artigo do
titulo 'Diversas dicas do RSpec'
conteudo 'Conteúdo de Diversas dicas do RSpec'
factory :artigo_aprovado do
aprovado true
end
factory :artigo_nao_aprovado do
aprovado false
end
end
console rails
FactoryGirl.create(:artigo_aprovado)
FactoryGirl.create(:artigo_nao_aprovado)
traits
factory_girl
spec/factories/artigos.rb
factory :artigo do
titulo 'Diversas dicas do RSpec'
conteudo 'Conteúdo de Diversas dicas do RSpec'
trait :aprovado do
aprovado true
end
trait :nao_aprovado do
aprovado false
end
end
console rails
FactoryGirl.create(:artigo, :aprovado)
FactoryGirl.create(:artigo, :nao_aprovado)
dependent attributes
factory_girl
spec/factories/artigos.rb
factory :artigo do
titulo 'Diversas dicas do RSpec'
conteudo { "Conteúdo do artigo #{titulo}. Aprovado: #{aprovado}" }
end
sequence
factory_girl
spec/factories/artigos.rb
factory :artigo do
sequence(:titulo) { |n| "Diversas dicas do RSpec #{n}" }
conteudo { "Conteúdo do artigo #{titulo}. Aprovado: #{aprovado}" }
end
associações
factory_girl
console rails
usuario = FactoryGirl.create(:usuario)
FactoryGirl.create(:artigo, usuario: usuario)
spec/factories/artigos.rb
factory :artigo do
titulo 'Diversas dicas do RSpec'
conteudo { "Conteúdo do artigo #{titulo}. Aprovado: #{aprovado}" }
usuario
end
aliases
factory_girl
spec/factories/artigos.rb
factory :usuario, aliases: [:autor] do
nome 'Mauro'
email { "#{nome}@helabs.com.br" }
end
strategies
factory_girl
console rails
pokemon = FactoryGirl.build(:pokemon)
console rails
pokemon = FactoryGirl.build_stubbed(:pokemon)
lint
factory_girl
spec/support/factory_girl.rb
RSpec.configure do |config|
config.before(:suite) do
begin
DatabaseCleaner.start
FactoryGirl.lint
ensure
DatabaseCleaner.clean
end
end
end
timecop
app/models/pokemon.rb
class Pokemon < ActiveRecord::Base
scope :escolhidos_ontem, -> do
where(escolhido_em: 1.day.ago.midnight..Time.zone.now.midnight)
end
end
spec/models/pokemon_spec.rb
describe '.escolhidos_ontem' do
let!(:pokemon_escolhido_ontem) do
create(:pokemon, escolhido_em: Time.zone.local(2014, 5, 16, 10, 45))
end
subject do
Pokemon.escolhidos_ontem
end
it 'tem o pokemon escolhido ontem' do
expect(subject).to include(pokemon_escolhido_ontem)
end
end
spec/models/pokemon_spec.rb
describe '.escolhidos_ontem' do
# ...
it 'tem o pokemon escolhido ontem' do
Timecop.freeze(Time.zone.local((2014, 5, 17, 10, 45)) do
expect(subject).to include(pokemon_escolhido_ontem)
end
end
end
simplecov
veri!cando a cobertura
simplecov
spec/spec_helper.rb
require 'simplecov'
SimpleCov.start 'rails'
Primeira linha do
spec_helper.rb
RSpec Best Friends @ TDC Florianópolis 2014
RSpec Best Friends @ TDC Florianópolis 2014
O falso 100%
simplecov
app/models/pokemon.rb
class Pokemon < ActiveRecord::Base
validates :nome, :id_nacional, presence: true
scope :escolhidos_ontem, -> do
where(escolhido_em: 1.day.ago.midnight..Time.zone.now.midnight)
end
end
Não teste associações, validações ou
escopos do Active Record
simplecov
teste associações, validações e escopos do
Active Record
simplecov
devo ter 100% de cobertura de testes?
simplecov
shoulda-matchers
app/models/pokemon.rb
class Pokemon < ActiveRecord::Base
validates :nome, :id_nacional, presence: true
validates :id_nacional, numericality: { only_integer: true, greater_than: 0 }
end
spec/models/pokemon_spec.rb
describe 'validações' do
it { should validate_presence_of(:nome) }
it { should validate_presence_of(:id_nacional) }
it { should validate_numericality_of(:id_nacional).only_integer
.is_greater_than(0) }
end
os matchers
shoulda-matchers
ActiveModel
os matchers
shoulda-matchers
ActiveModel
ActiveRecord
os matchers
shoulda-matchers
ActiveModel
ActiveRecord
ActionController
os matchers
shoulda-matchers
além do shoulda-matchers
shoulda-matchers
https://github.com/bmabey/email-spec
além do shoulda-matchers
shoulda-matchers
https://github.com/bmabey/email-spec
https://github.com/philostler/rspec-sidekiq
além do shoulda-matchers
shoulda-matchers
https://github.com/bmabey/email-spec
https://github.com/philostler/rspec-sidekiq
https://github.com/evansagge/mongoid-rspec
além do shoulda-matchers
shoulda-matchers
Obrigado!
maurogeorge.com.br
1 de 122

Recomendados

RSpec Best Friends @ TDC São Paulo 2014 por
RSpec Best Friends @ TDC São Paulo 2014RSpec Best Friends @ TDC São Paulo 2014
RSpec Best Friends @ TDC São Paulo 2014Mauro George
836 visualizações107 slides
RSpec Best Friends @ Rupy Natal 2014 por
RSpec Best Friends @ Rupy Natal 2014RSpec Best Friends @ Rupy Natal 2014
RSpec Best Friends @ Rupy Natal 2014Mauro George
1.3K visualizações72 slides
Php 02 Primeiros Passos por
Php 02 Primeiros PassosPhp 02 Primeiros Passos
Php 02 Primeiros PassosRegis Magalhães
1K visualizações72 slides
Prog web 02-php-primeiros-passos por
Prog web 02-php-primeiros-passosProg web 02-php-primeiros-passos
Prog web 02-php-primeiros-passosRegis Magalhães
903 visualizações72 slides
Palestra - Ariana Luz por
Palestra - Ariana LuzPalestra - Ariana Luz
Palestra - Ariana LuzZoom Comunicação
173 visualizações74 slides
Danone Waters Community Case Netnografia por
Danone Waters Community Case Netnografia Danone Waters Community Case Netnografia
Danone Waters Community Case Netnografia Plugged Research
1K visualizações19 slides

Mais conteúdo relacionado

Destaque

A Análise de Conteúdo em Plataformas de Interação Online: Aplicação Comparati... por
A Análise de Conteúdo em Plataformas de Interação Online: Aplicação Comparati...A Análise de Conteúdo em Plataformas de Interação Online: Aplicação Comparati...
A Análise de Conteúdo em Plataformas de Interação Online: Aplicação Comparati...Kadu Fernandiz
632 visualizações24 slides
Best of Esomar Belgium 2010_Flores por
Best of Esomar Belgium 2010_FloresBest of Esomar Belgium 2010_Flores
Best of Esomar Belgium 2010_FloresSchillewaert Niels
379 visualizações28 slides
Best Practices for Online Longitudinal Qualitative Research por
Best Practices for Online Longitudinal Qualitative ResearchBest Practices for Online Longitudinal Qualitative Research
Best Practices for Online Longitudinal Qualitative Researchlvanpatten
927 visualizações32 slides
NETNOGRAPHY vs. Web Monitoring = “Qual. VS Quant. ?” por
NETNOGRAPHY vs. Web Monitoring = “Qual. VS Quant. ?”NETNOGRAPHY vs. Web Monitoring = “Qual. VS Quant. ?”
NETNOGRAPHY vs. Web Monitoring = “Qual. VS Quant. ?”Steffen Hück
4.2K visualizações32 slides
Palestra Engajamento 2.0: Redes sociais corporativas por
Palestra Engajamento 2.0: Redes sociais corporativasPalestra Engajamento 2.0: Redes sociais corporativas
Palestra Engajamento 2.0: Redes sociais corporativasComunicação Integrada - Cursos e Soluções (Isabela Pimentel)
458 visualizações30 slides
TDC2016SP - Trilha Análise de Negócios por
TDC2016SP - Trilha Análise de NegóciosTDC2016SP - Trilha Análise de Negócios
TDC2016SP - Trilha Análise de Negóciostdc-globalcode
342 visualizações42 slides

Destaque(6)

A Análise de Conteúdo em Plataformas de Interação Online: Aplicação Comparati... por Kadu Fernandiz
A Análise de Conteúdo em Plataformas de Interação Online: Aplicação Comparati...A Análise de Conteúdo em Plataformas de Interação Online: Aplicação Comparati...
A Análise de Conteúdo em Plataformas de Interação Online: Aplicação Comparati...
Kadu Fernandiz632 visualizações
Best of Esomar Belgium 2010_Flores por Schillewaert Niels
Best of Esomar Belgium 2010_FloresBest of Esomar Belgium 2010_Flores
Best of Esomar Belgium 2010_Flores
Schillewaert Niels379 visualizações
Best Practices for Online Longitudinal Qualitative Research por lvanpatten
Best Practices for Online Longitudinal Qualitative ResearchBest Practices for Online Longitudinal Qualitative Research
Best Practices for Online Longitudinal Qualitative Research
lvanpatten927 visualizações
NETNOGRAPHY vs. Web Monitoring = “Qual. VS Quant. ?” por Steffen Hück
NETNOGRAPHY vs. Web Monitoring = “Qual. VS Quant. ?”NETNOGRAPHY vs. Web Monitoring = “Qual. VS Quant. ?”
NETNOGRAPHY vs. Web Monitoring = “Qual. VS Quant. ?”
Steffen Hück4.2K visualizações
TDC2016SP - Trilha Análise de Negócios por tdc-globalcode
TDC2016SP - Trilha Análise de NegóciosTDC2016SP - Trilha Análise de Negócios
TDC2016SP - Trilha Análise de Negócios
tdc-globalcode342 visualizações

Mais de Mauro George

Aprendendo com projetos open source @ RubyConf 2015 por
Aprendendo com projetos open source @ RubyConf 2015Aprendendo com projetos open source @ RubyConf 2015
Aprendendo com projetos open source @ RubyConf 2015Mauro George
775 visualizações58 slides
Rails front-end com bourbon e sua familia @ Front in Maceió 2014 por
Rails front-end com bourbon e sua familia @ Front in Maceió 2014Rails front-end com bourbon e sua familia @ Front in Maceió 2014
Rails front-end com bourbon e sua familia @ Front in Maceió 2014Mauro George
794 visualizações45 slides
Testes automatizados o time e o cliente saem ganhando! @ Agile Vale 2014 por
Testes automatizados o time e o cliente saem ganhando! @ Agile Vale 2014Testes automatizados o time e o cliente saem ganhando! @ Agile Vale 2014
Testes automatizados o time e o cliente saem ganhando! @ Agile Vale 2014Mauro George
956 visualizações45 slides
O cliente e o time juntos por um só objetivo! @ CONADEV 2014 por
O cliente e o time juntos por um só objetivo! @ CONADEV 2014O cliente e o time juntos por um só objetivo! @ CONADEV 2014
O cliente e o time juntos por um só objetivo! @ CONADEV 2014Mauro George
731 visualizações27 slides
Model of the colossus @ Rupy Brazil 2013 por
Model of the colossus @ Rupy Brazil 2013 Model of the colossus @ Rupy Brazil 2013
Model of the colossus @ Rupy Brazil 2013 Mauro George
1.6K visualizações38 slides
Model of the colossus @ Café com Dev por
Model of the colossus @ Café com DevModel of the colossus @ Café com Dev
Model of the colossus @ Café com DevMauro George
1.2K visualizações47 slides

Mais de Mauro George(7)

Aprendendo com projetos open source @ RubyConf 2015 por Mauro George
Aprendendo com projetos open source @ RubyConf 2015Aprendendo com projetos open source @ RubyConf 2015
Aprendendo com projetos open source @ RubyConf 2015
Mauro George775 visualizações
Rails front-end com bourbon e sua familia @ Front in Maceió 2014 por Mauro George
Rails front-end com bourbon e sua familia @ Front in Maceió 2014Rails front-end com bourbon e sua familia @ Front in Maceió 2014
Rails front-end com bourbon e sua familia @ Front in Maceió 2014
Mauro George794 visualizações
Testes automatizados o time e o cliente saem ganhando! @ Agile Vale 2014 por Mauro George
Testes automatizados o time e o cliente saem ganhando! @ Agile Vale 2014Testes automatizados o time e o cliente saem ganhando! @ Agile Vale 2014
Testes automatizados o time e o cliente saem ganhando! @ Agile Vale 2014
Mauro George956 visualizações
O cliente e o time juntos por um só objetivo! @ CONADEV 2014 por Mauro George
O cliente e o time juntos por um só objetivo! @ CONADEV 2014O cliente e o time juntos por um só objetivo! @ CONADEV 2014
O cliente e o time juntos por um só objetivo! @ CONADEV 2014
Mauro George731 visualizações
Model of the colossus @ Rupy Brazil 2013 por Mauro George
Model of the colossus @ Rupy Brazil 2013 Model of the colossus @ Rupy Brazil 2013
Model of the colossus @ Rupy Brazil 2013
Mauro George1.6K visualizações
Model of the colossus @ Café com Dev por Mauro George
Model of the colossus @ Café com DevModel of the colossus @ Café com Dev
Model of the colossus @ Café com Dev
Mauro George1.2K visualizações
Git para iniciantes v1.3.0 @ PHP Conference Brasil 2012 por Mauro George
Git para iniciantes v1.3.0 @ PHP Conference Brasil 2012Git para iniciantes v1.3.0 @ PHP Conference Brasil 2012
Git para iniciantes v1.3.0 @ PHP Conference Brasil 2012
Mauro George990 visualizações

Último

MAPA - SAÚDE - FUNDAMENTOS DE FARMACOLOGIA - 54/2023 por
MAPA - SAÚDE - FUNDAMENTOS DE FARMACOLOGIA - 54/2023MAPA - SAÚDE - FUNDAMENTOS DE FARMACOLOGIA - 54/2023
MAPA - SAÚDE - FUNDAMENTOS DE FARMACOLOGIA - 54/2023AcademicaDlaUnicesum
6 visualizações3 slides
Skills e Squads, como trabalhar? por
Skills e Squads, como trabalhar?Skills e Squads, como trabalhar?
Skills e Squads, como trabalhar?Annelise Gripp
32 visualizações13 slides
TechConnection 2023 Floripa Azure Container Apps por
TechConnection 2023 Floripa Azure Container AppsTechConnection 2023 Floripa Azure Container Apps
TechConnection 2023 Floripa Azure Container AppsWalter Coan
6 visualizações14 slides
DevFest2023-Pragmatismo da Internet das Coisas por
DevFest2023-Pragmatismo da Internet das CoisasDevFest2023-Pragmatismo da Internet das Coisas
DevFest2023-Pragmatismo da Internet das CoisasWalter Coan
25 visualizações40 slides
certificado excel.pdf por
certificado excel.pdfcertificado excel.pdf
certificado excel.pdfjuniorcarvalho136
5 visualizações1 slide
Conheça agora o UiPath Autopilot™ para o Studio.pdf por
Conheça agora o UiPath Autopilot™ para o Studio.pdfConheça agora o UiPath Autopilot™ para o Studio.pdf
Conheça agora o UiPath Autopilot™ para o Studio.pdfBrunaCavalcanti29
14 visualizações8 slides

Último(9)

MAPA - SAÚDE - FUNDAMENTOS DE FARMACOLOGIA - 54/2023 por AcademicaDlaUnicesum
MAPA - SAÚDE - FUNDAMENTOS DE FARMACOLOGIA - 54/2023MAPA - SAÚDE - FUNDAMENTOS DE FARMACOLOGIA - 54/2023
MAPA - SAÚDE - FUNDAMENTOS DE FARMACOLOGIA - 54/2023
AcademicaDlaUnicesum6 visualizações
Skills e Squads, como trabalhar? por Annelise Gripp
Skills e Squads, como trabalhar?Skills e Squads, como trabalhar?
Skills e Squads, como trabalhar?
Annelise Gripp32 visualizações
TechConnection 2023 Floripa Azure Container Apps por Walter Coan
TechConnection 2023 Floripa Azure Container AppsTechConnection 2023 Floripa Azure Container Apps
TechConnection 2023 Floripa Azure Container Apps
Walter Coan6 visualizações
DevFest2023-Pragmatismo da Internet das Coisas por Walter Coan
DevFest2023-Pragmatismo da Internet das CoisasDevFest2023-Pragmatismo da Internet das Coisas
DevFest2023-Pragmatismo da Internet das Coisas
Walter Coan25 visualizações
certificado excel.pdf por juniorcarvalho136
certificado excel.pdfcertificado excel.pdf
certificado excel.pdf
juniorcarvalho1365 visualizações
Conheça agora o UiPath Autopilot™ para o Studio.pdf por BrunaCavalcanti29
Conheça agora o UiPath Autopilot™ para o Studio.pdfConheça agora o UiPath Autopilot™ para o Studio.pdf
Conheça agora o UiPath Autopilot™ para o Studio.pdf
BrunaCavalcanti2914 visualizações
Shift left DevOps Experience por Walter Coan
Shift left DevOps ExperienceShift left DevOps Experience
Shift left DevOps Experience
Walter Coan5 visualizações
VIRTUS 1.6 MSI.pdf por FbioVieira85
VIRTUS 1.6 MSI.pdfVIRTUS 1.6 MSI.pdf
VIRTUS 1.6 MSI.pdf
FbioVieira855 visualizações
ProxySQL no MySQL: Apenas um load balancer? por Roberto Garcia de Bem
ProxySQL no MySQL: Apenas um load balancer?ProxySQL no MySQL: Apenas um load balancer?
ProxySQL no MySQL: Apenas um load balancer?
Roberto Garcia de Bem6 visualizações

RSpec Best Friends @ TDC Florianópolis 2014