SlideShare a Scribd company logo
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	
  
The hitchhicker’s guide to unit testing
The hitchhicker’s guide to unit testing
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	
  
The hitchhicker’s guide to unit testing
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

PDF
Redux saga: managing your side effects. Also: generators in es6
PDF
Workshop Sul Refactoring Agile Day 2008
PDF
The Ring programming language version 1.9 book - Part 92 of 210
PDF
The Ring programming language version 1.10 book - Part 17 of 212
PDF
The Ring programming language version 1.6 book - Part 41 of 189
PPT
OO JS for AS3 Devs
PPTX
Groovy puzzlers по русски с Joker 2014
Redux saga: managing your side effects. Also: generators in es6
Workshop Sul Refactoring Agile Day 2008
The Ring programming language version 1.9 book - Part 92 of 210
The Ring programming language version 1.10 book - Part 17 of 212
The Ring programming language version 1.6 book - Part 41 of 189
OO JS for AS3 Devs
Groovy puzzlers по русски с Joker 2014

What's hot (20)

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

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

PDF
Real life-coffeescript
PPSX
Scala @ TomTom
PDF
Go testdeep
PPT
Ruby on Rails testing with Rspec
DOC
Adodb Scripts And Some Sample Scripts[1]
DOC
Adodb Scripts And Some Sample Scripts[1]
PDF
Cocoa Design Patterns in Swift
PPT
Whats new in_csharp4
ODP
Scala introduction
PDF
Damn Fine CoffeeScript
PDF
The Ring programming language version 1.8 book - Part 94 of 202
PDF
How to not write a boring test in Golang
PDF
A swift introduction to Swift
PDF
Pooya Khaloo Presentation on IWMC 2015
PDF
Container adapters
PDF
Monadologie
PPTX
JavaScript 101
PPSX
DIWE - Programming with JavaScript
PPTX
Introduction to Client-Side Javascript
PDF
iRODS Rule Language Cheat Sheet
Real life-coffeescript
Scala @ TomTom
Go testdeep
Ruby on Rails testing with Rspec
Adodb Scripts And Some Sample Scripts[1]
Adodb Scripts And Some Sample Scripts[1]
Cocoa Design Patterns in Swift
Whats new in_csharp4
Scala introduction
Damn Fine CoffeeScript
The Ring programming language version 1.8 book - Part 94 of 202
How to not write a boring test in Golang
A swift introduction to Swift
Pooya Khaloo Presentation on IWMC 2015
Container adapters
Monadologie
JavaScript 101
DIWE - Programming with JavaScript
Introduction to Client-Side Javascript
iRODS Rule Language Cheat Sheet
Ad

Recently uploaded (20)

PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
A Presentation on Artificial Intelligence
PDF
Approach and Philosophy of On baking technology
PDF
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
PPTX
Spectroscopy.pptx food analysis technology
PPTX
Tartificialntelligence_presentation.pptx
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
Machine Learning_overview_presentation.pptx
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Electronic commerce courselecture one. Pdf
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Machine learning based COVID-19 study performance prediction
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
“AI and Expert System Decision Support & Business Intelligence Systems”
Advanced methodologies resolving dimensionality complications for autism neur...
The Rise and Fall of 3GPP – Time for a Sabbatical?
A Presentation on Artificial Intelligence
Approach and Philosophy of On baking technology
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
Spectroscopy.pptx food analysis technology
Tartificialntelligence_presentation.pptx
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Assigned Numbers - 2025 - Bluetooth® Document
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Machine Learning_overview_presentation.pptx
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Encapsulation_ Review paper, used for researhc scholars
Reach Out and Touch Someone: Haptics and Empathic Computing
Electronic commerce courselecture one. Pdf
MYSQL Presentation for SQL database connectivity
Machine learning based COVID-19 study performance prediction
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Per capita expenditure prediction using model stacking based on satellite ima...

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  
  • 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  
  • 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)