SlideShare a Scribd company logo
1 of 54
Download to read offline
The	
  hitchhicker’s	
  
guide	
  to	
  unit	
  tes1ng	
  
Rémy-­‐Christophe	
  Schermesser	
  
@el_picador	
  
Ruby!	
  
Scala!	
  
Java!	
  
Python!	
  
PHP!	
  
Ruby!	
  
Scala!	
  
Java!	
  
Python!	
  
PHP!	
  
But	
  don’t	
  forget	
  your	
  towel	
  
Test::Unit	
  
ScalaTest	
  
jUnit	
  
uniFest	
  
PHPUnit	
  
Test::Unit	
  
ScalaTest	
  
jUnit	
  
uniFest	
  
PHPUnit	
  
Again	
  don’t	
  forget	
  your	
  towel	
  
JUnit	
  
assertEquals	
  
At	
  the	
  beginning,	
  we	
  had	
  
Then	
  
assertThatMyTestFitsOn
OneLine(whatIExpect,	
  
whatMyCodeIsDoing);	
  
And	
  
void	
  testWithCamelCase
ToReadItBeFer()	
  {	
  ...	
  }	
  
And	
  again	
  
@Test	
  
void	
  annotaZonsAreGood
ForYourHealth()	
  {	
  ...	
  }	
  
And	
  again	
  again	
  
void	
  testMyTest()	
  {	
  	
  
	
  Obj	
  obj	
  =	
  new	
  Obj();	
  
	
  //	
  10	
  lignes	
  of	
  things	
  
	
  assertEquals(…);	
  
}	
  
JUnit	
  
JUnit	
  
Mocks	
  
JUnit	
  
Fixtures	
  
Mocks	
  
JUnit	
  
Behavior	
  
tes1ng	
  
with	
  
RSpec	
  
Problem	
  
void	
  testMyTest()	
  {	
  	
  
	
  Obj	
  obj	
  =	
  new	
  Obj();	
  
	
  //	
  10	
  lignes	
  of	
  things	
  
	
  assertEquals(…);	
  
}	
  
Behavior	
  tesZng,	
  don’t	
  test,	
  do	
  describe	
  
Describe	
  what	
  
your	
  program	
  
should	
  do	
  
One	
  test	
  
One	
  (english)	
  
sentence	
  
Behavior	
  tesZng,	
  don’t	
  test,	
  do	
  describe	
  
RSpec,	
  don’t	
  panic,	
  
factorize	
  and	
  do	
  DSL	
  
describe	
  CompaniesController	
  do	
  
	
  	
  	
  describe	
  "POST	
  create"	
  do	
  
	
  	
  	
  	
  	
  	
  context	
  "when	
  recruiter	
  	
  
signed_in	
  with	
  no	
  company"	
  do	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  …	
  
	
  	
  	
  	
  	
  	
  end	
  
	
  	
  	
  end	
  
end	
  
describe	
  CompaniesController	
  do	
  
	
  	
  	
  describe	
  "POST	
  create"	
  do	
  
	
  	
  	
  	
  	
  	
  context	
  "when	
  recruiter	
  	
  
signed_in	
  with	
  no	
  company"	
  do	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  …	
  
	
  	
  	
  	
  	
  	
  end	
  
	
  	
  	
  end	
  
end	
  
describe	
  CompaniesController	
  do	
  
	
  	
  	
  describe	
  "POST	
  create"	
  do	
  
	
  	
  	
  	
  	
  	
  context	
  "when	
  recruiter	
  	
  
signed_in	
  with	
  no	
  company	
  an	
  email	
  is	
  
sent"	
  do	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  …	
  
	
  	
  	
  	
  	
  	
  end	
  
	
  	
  	
  end	
  
end	
  
let!(:recruiter)	
  {	
  login_recruiter	
  create(:recruiter,	
  	
   	
  
	
   	
   	
   	
   	
   	
  company_id:	
  nil)	
  }	
  
	
  	
  
context	
  "when	
  good	
  params"	
  do	
  
	
  let(:params)	
  {	
  …	
  }	
  
	
  	
  
	
  	
  it	
  {	
  expect	
  {	
  post	
  :create,	
  params	
  }.to	
  change(Company,	
  :count).by	
  1	
  }	
  
	
  	
  it	
  {	
  expect	
  {	
  post	
  :create,	
  params	
  }.to	
  
	
   	
   	
   	
  change(Ac1onMailer::Base.deliveries,	
  :count).by	
  2	
  }	
  
	
  
end	
  
“When	
  recruiter	
  signed_in	
  with	
  no	
  company”
let!(:recruiter)	
  {	
  login_recruiter	
  create(:recruiter,	
  company_id:	
  nil)	
  }	
  
	
  	
  
context	
  "when	
  good	
  params"	
  do	
  
	
  let(:params)	
  {	
  …	
  }	
  
	
  	
  
	
  	
  it	
  {	
  expect	
  {	
  post	
  :create,	
  params	
  }.to	
  change(Company,	
  :count).by	
  1	
  }	
  
	
  	
  it	
  {	
  expect	
  {	
  post	
  :create,	
  params	
  }.to	
  
	
   	
   	
   	
  change(Ac1onMailer::Base.deliveries,	
  :count).by	
  2	
  }	
  
	
  
end	
  
“When	
  recruiter	
  signed_in	
  with	
  no	
  company”
let!(:recruiter)	
  {	
  login_recruiter	
  create(:recruiter,	
  company_id:	
  nil)	
  }	
  
	
  	
  
context	
  "when	
  good	
  params"	
  do	
  
	
  let(:params)	
  {	
  …	
  }	
  
	
  	
  
	
  	
  it	
  {	
  expect	
  {	
  post	
  :create,	
  params	
  }.to	
  change(Company,	
  :count).by	
  1	
  }	
  
	
  	
  it	
  {	
  expect	
  {	
  post	
  :create,	
  params	
  }.to	
  
	
   	
   	
   	
  change(Ac1onMailer::Base.deliveries,	
  :count).by	
  2	
  }	
  
	
  
end	
  
“When	
  recruiter	
  signed_in	
  with	
  no	
  company”
let!(:recruiter)	
  {	
  login_recruiter	
  create(:recruiter,	
  company_id:	
  nil)	
  }	
  
	
  	
  
context	
  "when	
  good	
  params"	
  do	
  
	
  let(:params)	
  {	
  …	
  }	
  
	
  	
  
	
  	
  it	
  {	
  expect	
  {	
  post	
  :create,	
  params	
  }.to	
   	
   	
   	
  
	
   	
   	
   	
   	
  change(Company,	
  :count).by	
  1	
  }	
  
	
  	
  it	
  {	
  expect	
  {	
  post	
  :create,	
  params	
  }.to	
   	
   	
   	
  
	
   	
   	
  change(Ac1onMailer::Base.deliveries,	
  :count).by	
  2	
  }	
  
	
  
end	
  
“When	
  recruiter	
  signed_in	
  with	
  no	
  company”
Like	
  a	
  towel,	
  use	
  it	
  every	
  day	
  
JUnit	
  
Muta1on	
  
tes1ng	
  
Behavior	
  
tes1ng	
  
with	
  
Javalanche	
  
Code	
  coverage	
  
has	
  limits	
  
Code:	
  ctrl+c	
  
Test:	
  ctrl+v	
  
Code	
  a	
  class	
  and	
  test	
  it	
  
Mutate	
  it	
  
&&	
  
++	
  
!=	
  
>	
  
…	
  
||	
  
-­‐-­‐	
  
==	
  
<	
  
…	
  
Mutate	
  it	
  
if(a	
  &&	
  b)	
  {	
  
	
  	
  	
  	
  i++;	
  
}	
  else	
  {	
  
	
  	
  	
  	
  i-­‐-­‐;	
  
}	
  
if(a || b) {	

    i++;	

} else {	

    i--;	

}	

if(a && b) {	

    i--;	

} else {	

    i--;	

}	

Mutate	
  it	
  
Kill	
  it	
  
mvn	
  test	
  
ant	
  -­‐f	
  javalanche.xml	
  mutaZonTest	
  
Kill	
  it	
  
Run	
  tests	
  
Green	
  tests	
  
Something’s	
  
wrong	
  
Run	
  tests	
  
Red	
  tests	
  
Great	
  job!	
  
Coverage	
  data	
  
Equivalent	
  mutant	
  
if(index	
  >=	
  10)	
  break	
  
and	
  
if(index	
  ==	
  10)	
  break	
  
Selec1ve	
  muta1on	
  
Parallel	
  execu1on	
  
Choose	
  your	
  mutants	
  wisely	
  
Using	
  code	
  coverage	
  to	
  
reduce	
  the	
  tests	
  to	
  run	
  
Speed-­‐up	
  
The	
  right	
  tool	
  
Behavior	
  
tes1ng	
  
JUnit	
  
Property	
  
tes1ng	
   Muta1on	
  
tes1ng	
  
with	
  
ScalaCheck	
  
How	
  to	
  test	
  string	
  
concatenaZon	
  ?	
  
assert(	
  ("ta"	
  +	
  "a")	
  ==	
  "taa"	
  )	
  
How	
  to	
  test	
  string	
  
concatenaZon	
  ?	
  
assert(	
  ("ta"	
  +	
  "a")	
  ==	
  "taa"	
  )	
  
assert(	
  ("ta"	
  +	
  "b")	
  ==	
  "tab"	
  )	
  
How	
  to	
  test	
  string	
  
concatenaZon	
  ?	
  
assert(	
  ("ta"	
  +	
  "a")	
  ==	
  "taa"	
  )	
  
assert(	
  ("ta"	
  +	
  "b")	
  ==	
  "tab"	
  )	
  
…	
  
How	
  to	
  test	
  string	
  
concatenaZon	
  ?	
  
assert(	
  ("ta"	
  +	
  "a")	
  ==	
  "taa"	
  )	
  
assert(	
  ("ta"	
  +	
  "b")	
  ==	
  "tab"	
  )	
  
assert(	
  ("ta"	
  +	
  "z")	
  ==	
  "taz"	
  )	
  
…	
  
How	
  to	
  test	
  string	
  
concatenaZon	
  ?	
  
assert(	
  ("ta"	
  +	
  "a")	
  ==	
  "taa"	
  )	
  
assert(	
  ("ta"	
  +	
  "b")	
  ==	
  "tab"	
  )	
  
assert(	
  ("ta"	
  +	
  "z")	
  ==	
  "taz"	
  )	
  
…	
  
But	
  boring	
  
∀n∈N,	
  ∃!k∈N	
  
(n	
  =	
  2k	
  ⋁	
  n	
  =	
  2k+1)	
  
Remember	
  math	
  class?	
  
∀n,	
  n	
  =	
  42	
  
val	
  n:	
  Int	
  
val	
  k:	
  Int	
  
	
  
(n	
  ==	
  2k	
  ||	
  n	
  ==	
  2k	
  +	
  1)	
  ==	
  true	
  
(n	
  %	
  2	
  	
  ==	
  0	
  ||	
  n	
  %	
  2	
  ==	
  1)	
  ==	
  true	
  
	
  
In	
  code	
  
val	
  a:	
  String	
  
val	
  b:	
  String	
  
	
  
((a+b)	
  endsWith	
  b)	
   	
  ==	
  true	
  
((a+b)	
  startsWith	
  a)	
  	
  ==	
  true	
  
	
  
(a+b).length	
  ==	
  a.length	
  +	
  b.length	
  
String	
  concatenaZon	
  properZes	
  
List[Int]	
  =>	
  isPalindrome(list)	
  
	
  
(list.reverse	
  ==	
  list)	
  ==>	
  isPalindrome(list)	
  
	
  
(list.reverse	
  !=	
  list)	
  ==>	
  !isPalindrome(list)	
  
Limits	
  
Behavior	
  tesZng	
  	
  	
   	
  Every	
  day	
  
MutaZon	
  tesZng	
  	
  	
   	
  CriZcal	
  code	
  
Property	
  tesZng	
   	
  à	
   	
  CriZcal	
  code	
  
Share	
  and	
  Enjoy	
  
So	
  Long,	
  and	
  
Thanks	
  for	
  All	
  
the	
  Fish	
  
Rémy-­‐Christophe	
  Schermesser	
  
@el_picador	
  
Rémy-­‐Christophe	
  Schermesser	
  
@el_picador	
  
Behavior	
  tesZng	
  
Rspec	
  (ruby)	
  
Jasmine	
  (javascript)	
  
	
  
MutaZon	
  tesZng	
  
Javalanche	
  (java)	
  
Mutant	
  (ruby)	
  
Property	
  tesZng	
  
ScalaCheck	
  (scala)	
  
QuickCheck	
  (haskell)	
  
MrProper	
  (ruby)	
  

More Related Content

What's hot

How to Clone Flappy Bird in Swift
How to Clone Flappy Bird in SwiftHow to Clone Flappy Bird in Swift
How to Clone Flappy Bird in Swift
Giordano Scalzo
 
String in .net
String in .netString in .net
String in .net
Larry Nung
 
GR8Conf 2011: Effective Groovy
GR8Conf 2011: Effective GroovyGR8Conf 2011: Effective Groovy
GR8Conf 2011: Effective Groovy
GR8Conf
 

What's hot (20)

The Ring programming language version 1.5.4 book - Part 34 of 185
The Ring programming language version 1.5.4 book - Part 34 of 185The Ring programming language version 1.5.4 book - Part 34 of 185
The Ring programming language version 1.5.4 book - Part 34 of 185
 
How to Clone Flappy Bird in Swift
How to Clone Flappy Bird in SwiftHow to Clone Flappy Bird in Swift
How to Clone Flappy Bird in Swift
 
String in .net
String in .netString in .net
String in .net
 
Miracle of std lib
Miracle of std libMiracle of std lib
Miracle of std lib
 
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
 
Promise: async programming hero
Promise: async programming heroPromise: async programming hero
Promise: async programming hero
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
The Ring programming language version 1.7 book - Part 16 of 196
The Ring programming language version 1.7 book - Part 16 of 196The Ring programming language version 1.7 book - Part 16 of 196
The Ring programming language version 1.7 book - Part 16 of 196
 
GR8Conf 2011: Effective Groovy
GR8Conf 2011: Effective GroovyGR8Conf 2011: Effective Groovy
GR8Conf 2011: Effective Groovy
 
Ian 20150116 java script oop
Ian 20150116 java script oopIan 20150116 java script oop
Ian 20150116 java script oop
 
Rxjs vienna
Rxjs viennaRxjs vienna
Rxjs vienna
 
The Ring programming language version 1.6 book - Part 15 of 189
The Ring programming language version 1.6 book - Part 15 of 189The Ring programming language version 1.6 book - Part 15 of 189
The Ring programming language version 1.6 book - Part 15 of 189
 
Java binary subtraction
Java binary subtractionJava binary subtraction
Java binary subtraction
 
Why react matters
Why react mattersWhy react matters
Why react matters
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
 
Rxjs ppt
Rxjs pptRxjs ppt
Rxjs ppt
 
"Kotlin и rx в android" Дмитрий Воронин (Avito)
"Kotlin и rx в android" Дмитрий Воронин  (Avito)"Kotlin и rx в android" Дмитрий Воронин  (Avito)
"Kotlin и rx в android" Дмитрий Воронин (Avito)
 
Rxjs ngvikings
Rxjs ngvikingsRxjs ngvikings
Rxjs ngvikings
 
Akka in-action
Akka in-actionAkka in-action
Akka in-action
 
Eta
EtaEta
Eta
 

Similar to The hitchhicker’s guide to unit testing

Adodb Scripts And Some Sample Scripts[1]
Adodb Scripts And Some Sample Scripts[1]Adodb Scripts And Some Sample Scripts[1]
Adodb Scripts And Some Sample Scripts[1]
testduser1
 
Adodb Scripts And Some Sample Scripts[1]
Adodb Scripts And Some Sample Scripts[1]Adodb Scripts And Some Sample Scripts[1]
Adodb Scripts And Some Sample Scripts[1]
User1test
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4
Abed Bukhari
 

Similar to The hitchhicker’s guide to unit testing (20)

Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
 
Scala @ TomTom
Scala @ TomTomScala @ TomTom
Scala @ TomTom
 
Go testdeep
Go testdeepGo testdeep
Go testdeep
 
Ruby on Rails testing with Rspec
Ruby on Rails testing with RspecRuby on Rails testing with Rspec
Ruby on Rails testing with Rspec
 
Adodb Scripts And Some Sample Scripts[1]
Adodb Scripts And Some Sample Scripts[1]Adodb Scripts And Some Sample Scripts[1]
Adodb Scripts And Some Sample Scripts[1]
 
Adodb Scripts And Some Sample Scripts[1]
Adodb Scripts And Some Sample Scripts[1]Adodb Scripts And Some Sample Scripts[1]
Adodb Scripts And Some Sample Scripts[1]
 
Cocoa Design Patterns in Swift
Cocoa Design Patterns in SwiftCocoa Design Patterns in Swift
Cocoa Design Patterns in Swift
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 
The Ring programming language version 1.8 book - Part 94 of 202
The Ring programming language version 1.8 book - Part 94 of 202The Ring programming language version 1.8 book - Part 94 of 202
The Ring programming language version 1.8 book - Part 94 of 202
 
How to not write a boring test in Golang
How to not write a boring test in GolangHow to not write a boring test in Golang
How to not write a boring test in Golang
 
Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to Swift
 
Container adapters
Container adaptersContainer adapters
Container adapters
 
Monadologie
MonadologieMonadologie
Monadologie
 
JavaScript 101
JavaScript 101JavaScript 101
JavaScript 101
 
DIWE - Programming with JavaScript
DIWE - Programming with JavaScriptDIWE - Programming with JavaScript
DIWE - Programming with JavaScript
 
Introduction to Client-Side Javascript
Introduction to Client-Side JavascriptIntroduction to Client-Side Javascript
Introduction to Client-Side Javascript
 
iRODS Rule Language Cheat Sheet
iRODS Rule Language Cheat SheetiRODS Rule Language Cheat Sheet
iRODS Rule Language Cheat Sheet
 

Recently uploaded

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
Safe Software
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Recently uploaded (20)

CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
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, ...
 
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
 
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...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
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...
 
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
 
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
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
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...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 

The hitchhicker’s guide to unit testing

  • 1. The  hitchhicker’s   guide  to  unit  tes1ng   Rémy-­‐Christophe  Schermesser   @el_picador  
  • 2. Ruby!   Scala!   Java!   Python!   PHP!  
  • 3. Ruby!   Scala!   Java!   Python!   PHP!   But  don’t  forget  your  towel  
  • 4. Test::Unit   ScalaTest   jUnit   uniFest   PHPUnit  
  • 5. Test::Unit   ScalaTest   jUnit   uniFest   PHPUnit   Again  don’t  forget  your  towel  
  • 7. assertEquals   At  the  beginning,  we  had  
  • 10. And  again   @Test   void  annotaZonsAreGood ForYourHealth()  {  ...  }  
  • 11. And  again  again   void  testMyTest()  {      Obj  obj  =  new  Obj();    //  10  lignes  of  things    assertEquals(…);   }  
  • 15. JUnit   Behavior   tes1ng   with   RSpec  
  • 16. Problem   void  testMyTest()  {      Obj  obj  =  new  Obj();    //  10  lignes  of  things    assertEquals(…);   }  
  • 17. Behavior  tesZng,  don’t  test,  do  describe   Describe  what   your  program   should  do  
  • 18. One  test   One  (english)   sentence   Behavior  tesZng,  don’t  test,  do  describe  
  • 19. RSpec,  don’t  panic,   factorize  and  do  DSL  
  • 20. describe  CompaniesController  do        describe  "POST  create"  do              context  "when  recruiter     signed_in  with  no  company"  do                    …              end        end   end  
  • 21. describe  CompaniesController  do        describe  "POST  create"  do              context  "when  recruiter     signed_in  with  no  company"  do                    …              end        end   end  
  • 22. describe  CompaniesController  do        describe  "POST  create"  do              context  "when  recruiter     signed_in  with  no  company  an  email  is   sent"  do                    …              end        end   end  
  • 23. let!(:recruiter)  {  login_recruiter  create(:recruiter,                  company_id:  nil)  }       context  "when  good  params"  do    let(:params)  {  …  }          it  {  expect  {  post  :create,  params  }.to  change(Company,  :count).by  1  }      it  {  expect  {  post  :create,  params  }.to          change(Ac1onMailer::Base.deliveries,  :count).by  2  }     end   “When  recruiter  signed_in  with  no  company”
  • 24. let!(:recruiter)  {  login_recruiter  create(:recruiter,  company_id:  nil)  }       context  "when  good  params"  do    let(:params)  {  …  }          it  {  expect  {  post  :create,  params  }.to  change(Company,  :count).by  1  }      it  {  expect  {  post  :create,  params  }.to          change(Ac1onMailer::Base.deliveries,  :count).by  2  }     end   “When  recruiter  signed_in  with  no  company”
  • 25. let!(:recruiter)  {  login_recruiter  create(:recruiter,  company_id:  nil)  }       context  "when  good  params"  do    let(:params)  {  …  }          it  {  expect  {  post  :create,  params  }.to  change(Company,  :count).by  1  }      it  {  expect  {  post  :create,  params  }.to          change(Ac1onMailer::Base.deliveries,  :count).by  2  }     end   “When  recruiter  signed_in  with  no  company”
  • 26. let!(:recruiter)  {  login_recruiter  create(:recruiter,  company_id:  nil)  }       context  "when  good  params"  do    let(:params)  {  …  }          it  {  expect  {  post  :create,  params  }.to                  change(Company,  :count).by  1  }      it  {  expect  {  post  :create,  params  }.to              change(Ac1onMailer::Base.deliveries,  :count).by  2  }     end   “When  recruiter  signed_in  with  no  company”
  • 27. Like  a  towel,  use  it  every  day  
  • 28. JUnit   Muta1on   tes1ng   Behavior   tes1ng   with   Javalanche  
  • 29. Code  coverage   has  limits   Code:  ctrl+c   Test:  ctrl+v  
  • 30. Code  a  class  and  test  it  
  • 32. &&   ++   !=   >   …   ||   -­‐-­‐   ==   <   …   Mutate  it  
  • 33. if(a  &&  b)  {          i++;   }  else  {          i-­‐-­‐;   }   if(a || b) {     i++; } else {     i--; } if(a && b) {     i--; } else {     i--; } Mutate  it  
  • 35. mvn  test   ant  -­‐f  javalanche.xml  mutaZonTest   Kill  it  
  • 36. Run  tests   Green  tests   Something’s   wrong  
  • 37. Run  tests   Red  tests   Great  job!  
  • 38. Coverage  data   Equivalent  mutant   if(index  >=  10)  break   and   if(index  ==  10)  break   Selec1ve  muta1on   Parallel  execu1on   Choose  your  mutants  wisely   Using  code  coverage  to   reduce  the  tests  to  run   Speed-­‐up   The  right  tool  
  • 39.
  • 40.
  • 41. Behavior   tes1ng   JUnit   Property   tes1ng   Muta1on   tes1ng   with   ScalaCheck  
  • 42. How  to  test  string   concatenaZon  ?   assert(  ("ta"  +  "a")  ==  "taa"  )  
  • 43. How  to  test  string   concatenaZon  ?   assert(  ("ta"  +  "a")  ==  "taa"  )   assert(  ("ta"  +  "b")  ==  "tab"  )  
  • 44. How  to  test  string   concatenaZon  ?   assert(  ("ta"  +  "a")  ==  "taa"  )   assert(  ("ta"  +  "b")  ==  "tab"  )   …  
  • 45. How  to  test  string   concatenaZon  ?   assert(  ("ta"  +  "a")  ==  "taa"  )   assert(  ("ta"  +  "b")  ==  "tab"  )   assert(  ("ta"  +  "z")  ==  "taz"  )   …  
  • 46. How  to  test  string   concatenaZon  ?   assert(  ("ta"  +  "a")  ==  "taa"  )   assert(  ("ta"  +  "b")  ==  "tab"  )   assert(  ("ta"  +  "z")  ==  "taz"  )   …   But  boring  
  • 47. ∀n∈N,  ∃!k∈N   (n  =  2k  ⋁  n  =  2k+1)   Remember  math  class?   ∀n,  n  =  42  
  • 48. val  n:  Int   val  k:  Int     (n  ==  2k  ||  n  ==  2k  +  1)  ==  true   (n  %  2    ==  0  ||  n  %  2  ==  1)  ==  true     In  code  
  • 49. val  a:  String   val  b:  String     ((a+b)  endsWith  b)    ==  true   ((a+b)  startsWith  a)    ==  true     (a+b).length  ==  a.length  +  b.length   String  concatenaZon  properZes  
  • 50. List[Int]  =>  isPalindrome(list)     (list.reverse  ==  list)  ==>  isPalindrome(list)     (list.reverse  !=  list)  ==>  !isPalindrome(list)   Limits  
  • 51.
  • 52. Behavior  tesZng        Every  day   MutaZon  tesZng        CriZcal  code   Property  tesZng    à    CriZcal  code   Share  and  Enjoy  
  • 53. So  Long,  and   Thanks  for  All   the  Fish   Rémy-­‐Christophe  Schermesser   @el_picador  
  • 54. Rémy-­‐Christophe  Schermesser   @el_picador   Behavior  tesZng   Rspec  (ruby)   Jasmine  (javascript)     MutaZon  tesZng   Javalanche  (java)   Mutant  (ruby)   Property  tesZng   ScalaCheck  (scala)   QuickCheck  (haskell)   MrProper  (ruby)