SlideShare una empresa de Scribd logo
1 de 63
Descargar para leer sin conexión
DEIXE O TESTE INFECTAR
VOCÊ
AUTOMATIZANDO OS TESTES DE SUAS
APLICA ÕES RUBYÇ
Hercules Lemke Merscher - @hlmerscher
IT'S ME, HERCULES.
DESENVOLVEDOR
CRIADOR DO “DOJO, ONDE?”
http://dojoonde.herculesdev.com.br
Integrante do TUX-ES
POR QUE AUTOMATIZAR?
PORQUE SIM!!!
NÃO É RESPOTA
MOTIVOS
Erros recorrentes
MOTIVOS
O COMPUTADOR TESTA MUITO MAIS RÁPIDO
MOTIVOS
O COMPUTADOR TESTA TUDO SEM CANSAR
MOTIVOS
LEI DE MURPHY
#include<stdio.h>
int main(){
printf("Hello Worldn");
return 0;
}
NO INÍCIO
TESTANDO
$ gcc hello.c -o hello
$ ./hello
Hello World
OK
MAIS UM POUCO
#include<stdio.h>
int soma(int a, int b){
return a + b;
}
int main(){
printf("%dn", soma(2, 2) );
return 0;
}
TESTANDO
$ gcc soma.c -o soma
$ ./soma
4
CARA EXPERTO
#include<stdio.h>
int soma(int a, int b){
return a + b;
}
int main(){
printf("A soma de 2+2 = ");
printf("%dn", soma(2, 2) );
return 0;
}
NOVAMENTE... COM ÉQUIO
$ gcc soma.c -o soma
$ ./soma
A soma de 2+2 = 4
AGORA VAMOS AO MUNDO
REAL?
E SE,
TESTASSEMOS PRIMEIRO?
É POSSÍVEL!
TEST DRIVEN DEVELOPMENT
CICLOS DO TDD
BABY STEPS
FRAMEWORKS DE TESTE
PARA RUBY
Test Unit
http://test-unit.rubyforge.org/
RSpec
http://rspec.info/
Mini Test
http://docs.seattlerb.org/minitest/
INSTALANDO
Test Unit
$ gem install test-unit
RSpec
$ gem install rspec
Mini Test
$ gem install minitest
TEST UNIT
require "test/unit"
require "./calc"
class CalculadoraTest < Test::Unit::TestCase
def test_soma_2_mais_2
calc = Calculadora.new
assert_equal 4, calc.soma(2, 2)
end
end
RED
$ ruby calc_test.rb
Run options:
# Running tests:
E
Finished tests in 0.000854s, 1171.2208 tests/s, 0.0000
assertions/s.
1) Error:
test_soma_2_mais_2(CalculadoraTest):
NameError: uninitialized constant CalculadoraTest::Calculadora
calc_test.rb:5:in `test_soma_2_mais_2'
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
RED
class Calculadora
end
RED
$ ruby calc_test.rb
Run options:
# Running tests:
E
Finished tests in 0.000807s, 1238.5972 tests/s, 0.0000
assertions/s.
1) Error:
test_soma_2_mais_2(CalculadoraTest):
NoMethodError: undefined method `soma' for
#<Calculadora:0x00000000ef0b00>
calc_test.rb:7:in `test_soma_2_mais_2'
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
RED
class Calculadora
def soma(a, b)
– end
–
end
RED
$ ruby calc_test.rb
Run options:
# Running tests:
F
Finished tests in 0.001068s, 936.3173 tests/s, 936.3173
assertions/s.
1) Failure:
test_soma_2_mais_2(CalculadoraTest) [calc_test.rb:7]:
<4> expected but was
<nil>.
1 tests, 1 assertions, 1 failures, 0 errors, 0 skips
RED
class Calculadora
def soma(a, b)
4
– end
–
end
GREEN
$ ruby calc_test.rb
Run options:
# Running tests:
.
Finished tests in 0.000806s, 1240.3147
tests/s, 1240.3147 assertions/s.
1 tests, 1 assertions, 0 failures, 0 errors,
0 skips
LEMBRE-SE DO BABY STEPS
GREEN
require "test/unit"
require "./calc"
class CalculadoraTest < Test::Unit::TestCase
– # test_soma_2_mais_2
def test_soma_5_mais_3
calc = Calculadora.new
assert_equal 8, calc.soma(5, 3)
end
end
RED
$ ruby calc_test.rb
Run options:
# Running tests:
.F
Finished tests in 0.001050s, 1903.8843 tests/s, 1903.8843
assertions/s.
1) Failure:
test_soma_5_mais_3(CalculadoraTest) [calc_test.rb:12]:
<8> expected but was
<4>.
2 tests, 2 assertions, 1 failures, 0 errors, 0 skips
RED
class Calculadora
def soma(a, b)
a + b
– end
–
end
GREEN
$ ruby calc_test.rb
Run options:
# Running tests:
..
Finished tests in 0.000776s, 2577.7647
tests/s, 2577.7647 assertions/s.
2 tests, 2 assertions, 0 failures, 0 errors,
0 skips
RSPEC
require "./calc"
describe Calculadora do
it "deve somar 2 + 2" do
calc = Calculadora.new
calc.soma(2,2).should == 4
end
it "deve somar 5 + 3" do
calc = Calculadora.new
calc.soma(5,3).should == 8
end
end
RSPEC
$ rspec calc_spec.rb
FF
Failures:
1) Calculadora deve somar 2 + 2
Failure/Error: calc.soma(2,2).should == 4
expected: 4
got: 0 (using ==)
# ./calc_spec.rb:6:in `block (2 levels) in <top (required)>'
(...)
Finished in 0.00088 seconds
2 examples, 2 failures
Failed examples:
rspec ./calc_spec.rb:4 # Calculadora deve somar 2 + 2
rspec ./calc_spec.rb:9 # Calculadora deve somar 5 + 3
RSPEC
..
Finished in 0.0007 seconds
2 examples, 0 failures
TESTES DE
REGRESSÃO
Que bicho é esse?
ACCEPTANCE TEST DRIVEN
DEVELOPMENT
CAPYBARA NO RAILS
$ gem install capybara
…
require “capybara/rails”
CAPYBARA
$ rails generate integration_test calc
invoke mini_test
create test/integration/calc_test.rb
CAPYBARA
require "test_helper"
class CalcTest < ActionDispatch::IntegrationTest
test "deve somar 2 + 2" do
visit "/"
fill_in "primeiro", with: 2
fill_in "segundo", with: 2
click_on "somar"
assert page.has_content?("resultado = 4")
end
end
CAPYBARA
$ rake minitest
Run options:
# Running tests:
E
Fabulous tests in 0.056458s, 17.7121 tests/s, 0.0000
assertions/s.
1) Error:
test_deve_somar_2_+_2(CalcTest):
ActionController::RoutingError: No route matches [GET]
"/"
...
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
CAPYBARA
root to: “calc#soma”
CAPYBARA
$ rake minitest
Run options:
# Running tests:
E
Fabulous tests in 0.278528s, 3.5903 tests/s, 0.0000
assertions/s.
1) Error:
test_deve_somar_2_+_2(CalcTest):
ActionView::MissingTemplate: Missing template calculadora/soma,
application/soma with {:locale=>[:en], :formats=>[:html],
:handlers=>[:erb, :builder]}. Searched in:
...
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
CAPYBARA
$ touch app/views/calc/soma.html.erb
CAPYBARA
$ rake minitest
Run options:
# Running tests:
E
Fabulous tests in 0.278528s, 3.5903 tests/s, 0.0000
assertions/s.
1) Error:
test_deve_somar_2_+_2(CalcTest):
Capybara::ElementNotFound: Unable to find field
"primeiro"
...
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
CAPYBARA
<%= form_tag("/calc/resultado",
method: “post”) do %>
<%= label_tag(:primeiro, "primeiro") %>
<%= text_field_tag(:primeiro) %>
<% end %>
CAPYBARA
$ rake minitest
Run options:
# Running tests:
E
Fabulous tests in 0.278528s, 3.5903 tests/s, 0.0000
assertions/s.
1) Error:
test_deve_somar_2_+_2(CalcTest):
Capybara::ElementNotFound: Unable to find field "segundo"
...
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
CAPYBARA
<%= form_tag("/calc/resultado",
method: “post”) do %>
<%= label_tag(:primeiro, "primeiro") %>
<%= text_field_tag(:primeiro) %>
<%= label_tag(:segundo, "segundo") %>
<%= text_field_tag(:segundo) %>
<%= submit_tag(“somar”) %>
<% end %>
CAPYBARA
$ rake minitest
Run options:
# Running tests:
E
Fabulous tests in 0.278528s, 3.5903 tests/s, 0.0000
assertions/s.
1) Error:
test_deve_somar_2_+_2(CalcTest):
ActionView::Template::Error: No route
matches{:controller=>"calc", :action=>"resultado"}
...
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
CAPYBARA
root to: "calc#soma"
–
post "calc/resultado"
CAPYBARA
$ rake minitest
Run options:
# Running tests:
E
Fabulous tests in 0.278528s, 3.5903 tests/s, 0.0000
assertions/s.
1) Error:
test_deve_somar_2_+_2(CalcTest):
ActionView::MissingTemplate: Missing template calc/resultado,
application/resultado with {:locale=>[:en],
:formats=>[:html], :handlers=>[:erb, :builder]}.
...
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
CAPYBARA
CONTROLLER
def resultado
primeiro = params[:primeiro].to_i
segundo = params[:segundo].to_i
@resultado = primeiro + segundo
end
VIEW
$ touch app/views/calc/resultado.html.erb
<p> resultado = <%= @resultado %> </p>
CAPYBARA
$ ruby -Itest test/integration/calc_test.rb
Run options:
Run options:
# Running tests:
.
Finished tests in 0.779280s, 1.2832 tests/s, 1.2832
assertions/s.
...
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
LIVROS
LIVROS
DÚVIDAS?
OBRIGADO!
http://herculesdev.com.br/
hlmerscher@gmail.com
twitter.com/hlmerscher
github.com/hlmerscher

Más contenido relacionado

La actualidad más candente

Compatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensionsCompatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensions
Kai Cui
 
Django’s nasal passage
Django’s nasal passageDjango’s nasal passage
Django’s nasal passage
Erik Rose
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101
Nando Vieira
 
(Meta 2.3) figura de auto con simbolos dev c++
(Meta 2.3) figura de auto con simbolos dev c++ (Meta 2.3) figura de auto con simbolos dev c++
(Meta 2.3) figura de auto con simbolos dev c++
Eli Diaz
 
Getting Started with Maven and Cucumber in Eclipse
Getting Started with Maven and Cucumber in EclipseGetting Started with Maven and Cucumber in Eclipse
Getting Started with Maven and Cucumber in Eclipse
Tom Arend
 
How Danga::Socket handles asynchronous processing and how to write asynchrono...
How Danga::Socket handles asynchronous processing and how to write asynchrono...How Danga::Socket handles asynchronous processing and how to write asynchrono...
How Danga::Socket handles asynchronous processing and how to write asynchrono...
Gosuke Miyashita
 

La actualidad más candente (20)

Compatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensionsCompatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensions
 
Django’s nasal passage
Django’s nasal passageDjango’s nasal passage
Django’s nasal passage
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101
 
Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101
 
ZendCon 2017 - Build a Bot Workshop - Async Primer
ZendCon 2017 - Build a Bot Workshop - Async PrimerZendCon 2017 - Build a Bot Workshop - Async Primer
ZendCon 2017 - Build a Bot Workshop - Async Primer
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to Production
 
Perl Sucks - and what to do about it
Perl Sucks - and what to do about itPerl Sucks - and what to do about it
Perl Sucks - and what to do about it
 
(Meta 2.3) figura de auto con simbolos dev c++
(Meta 2.3) figura de auto con simbolos dev c++ (Meta 2.3) figura de auto con simbolos dev c++
(Meta 2.3) figura de auto con simbolos dev c++
 
Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)
 
Testing Javascript with Jasmine
Testing Javascript with JasmineTesting Javascript with Jasmine
Testing Javascript with Jasmine
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with Karma
 
Practical Ext JS Debugging
Practical Ext JS DebuggingPractical Ext JS Debugging
Practical Ext JS Debugging
 
Perlbal Tutorial
Perlbal TutorialPerlbal Tutorial
Perlbal Tutorial
 
From typing the test to testing the type
From typing the test to testing the typeFrom typing the test to testing the type
From typing the test to testing the type
 
Getting Started with Maven and Cucumber in Eclipse
Getting Started with Maven and Cucumber in EclipseGetting Started with Maven and Cucumber in Eclipse
Getting Started with Maven and Cucumber in Eclipse
 
CoffeeScript: JavaScript, but Better!
CoffeeScript: JavaScript, but Better! CoffeeScript: JavaScript, but Better!
CoffeeScript: JavaScript, but Better!
 
How Danga::Socket handles asynchronous processing and how to write asynchrono...
How Danga::Socket handles asynchronous processing and how to write asynchrono...How Danga::Socket handles asynchronous processing and how to write asynchrono...
How Danga::Socket handles asynchronous processing and how to write asynchrono...
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
 
PhpUnit Best Practices
PhpUnit Best PracticesPhpUnit Best Practices
PhpUnit Best Practices
 
Cramp websockets
Cramp websocketsCramp websockets
Cramp websockets
 

Destacado (7)

RSpec - Testando suas aplicações Ruby on Rails
RSpec - Testando suas aplicações Ruby on RailsRSpec - Testando suas aplicações Ruby on Rails
RSpec - Testando suas aplicações Ruby on Rails
 
Linux Desktop (Campus Party Recife)
Linux Desktop (Campus Party Recife)Linux Desktop (Campus Party Recife)
Linux Desktop (Campus Party Recife)
 
Programação funcional no dia a dia
Programação funcional no dia a diaProgramação funcional no dia a dia
Programação funcional no dia a dia
 
Workshop Ubuntu
Workshop UbuntuWorkshop Ubuntu
Workshop Ubuntu
 
Projeto codigo de processo civil quadro comparativo
Projeto codigo de processo civil   quadro comparativoProjeto codigo de processo civil   quadro comparativo
Projeto codigo de processo civil quadro comparativo
 
Desenvolvimento incremental e iterativo
Desenvolvimento incremental e iterativoDesenvolvimento incremental e iterativo
Desenvolvimento incremental e iterativo
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 

Similar a Deixe o teste infectar você

Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
Kerry Buckley
 
Test-driven Development no Rails
Test-driven Development no RailsTest-driven Development no Rails
Test-driven Development no Rails
elliando dias
 

Similar a Deixe o teste infectar você (20)

Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
 
Hidden Gems of Ruby 1.9
Hidden Gems of Ruby 1.9Hidden Gems of Ruby 1.9
Hidden Gems of Ruby 1.9
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Pro Java Fx – Developing Enterprise Applications
Pro Java Fx – Developing Enterprise ApplicationsPro Java Fx – Developing Enterprise Applications
Pro Java Fx – Developing Enterprise Applications
 
Rails Testing
Rails TestingRails Testing
Rails Testing
 
New Features Of Test Unit 2.x
New Features Of Test Unit 2.xNew Features Of Test Unit 2.x
New Features Of Test Unit 2.x
 
Ruby on Rails testing with Rspec
Ruby on Rails testing with RspecRuby on Rails testing with Rspec
Ruby on Rails testing with Rspec
 
Test driven development_for_php
Test driven development_for_phpTest driven development_for_php
Test driven development_for_php
 
Test Drive Development in Ruby On Rails
Test Drive Development in Ruby On RailsTest Drive Development in Ruby On Rails
Test Drive Development in Ruby On Rails
 
Testing Legacy Rails Apps
Testing Legacy Rails AppsTesting Legacy Rails Apps
Testing Legacy Rails Apps
 
Ruby Metaprogramming
Ruby MetaprogrammingRuby Metaprogramming
Ruby Metaprogramming
 
Ch ch-changes cake php2
Ch ch-changes cake php2Ch ch-changes cake php2
Ch ch-changes cake php2
 
Test Coverage in Rails
Test Coverage in RailsTest Coverage in Rails
Test Coverage in Rails
 
Test-driven Development no Rails
Test-driven Development no RailsTest-driven Development no Rails
Test-driven Development no Rails
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
 
Thomas Fuchs Presentation
Thomas Fuchs PresentationThomas Fuchs Presentation
Thomas Fuchs Presentation
 
Rails and security
Rails and securityRails and security
Rails and security
 
Oracle APEX Performance
Oracle APEX PerformanceOracle APEX Performance
Oracle APEX Performance
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End Development
 
Surviving javascript.pptx
Surviving javascript.pptxSurviving javascript.pptx
Surviving javascript.pptx
 

Último

Último (20)

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
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
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
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...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
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...
 
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
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
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
 

Deixe o teste infectar você