Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
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	  assertThatMyTestFitsOnOneLine(whatIExpect,	  whatMyCodeIsDoing);	  
And	  void	  testWithCamelCaseToReadItBeFer()	  {	  ...	  }	  
And	  again	  @Test	  void	  annotaZonsAreGoodForYourHealth()	  {	  ...	  }	  
And	  again	  again	  void	  testMyTest()	  {	  	  	  Obj	  obj	  =	  new	  Obj();	  	  //	  10	  lignes	  of	  things	  	...
JUnit	  
JUnit	  Mocks	  
JUnit	  Fixtures	  Mocks	  
JUnit	  Behavior	  tes1ng	  with	  RSpec	  
Problem	  void	  testMyTest()	  {	  	  	  Obj	  obj	  =	  new	  Obj();	  	  //	  10	  lignes	  of	  things	  	  assertEqua...
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	  recru...
describe	  CompaniesController	  do	  	  	  	  describe	  "POST	  create"	  do	  	  	  	  	  	  	  context	  "when	  recru...
describe	  CompaniesController	  do	  	  	  	  describe	  "POST	  create"	  do	  	  	  	  	  	  	  context	  "when	  recru...
let!(:recruiter)	  {	  login_recruiter	  create(:recruiter,	  	   	  	   	   	   	   	   	  company_id:	  nil)	  }	  	  	 ...
let!(:recruiter)	  {	  login_recruiter	  create(:recruiter,	  company_id:	  nil)	  }	  	  	  context	  "when	  good	  para...
let!(:recruiter)	  {	  login_recruiter	  create(:recruiter,	  company_id:	  nil)	  }	  	  	  context	  "when	  good	  para...
let!(:recruiter)	  {	  login_recruiter	  create(:recruiter,	  company_id:	  nil)	  }	  	  	  context	  "when	  good	  para...
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--;	...
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	  muta1...
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")	  =...
How	  to	  test	  string	  concatenaZon	  ?	  assert(	  ("ta"	  +	  "a")	  ==	  "taa"	  )	  assert(	  ("ta"	  +	  "b")	  =...
How	  to	  test	  string	  concatenaZon	  ?	  assert(	  ("ta"	  +	  "a")	  ==	  "taa"	  )	  assert(	  ("ta"	  +	  "b")	  =...
How	  to	  test	  string	  concatenaZon	  ?	  assert(	  ("ta"	  +	  "a")	  ==	  "taa"	  )	  assert(	  ("ta"	  +	  "b")	  =...
∀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	  ||	  ...
val	  a:	  String	  val	  b:	  String	  	  ((a+b)	  endsWith	  b)	   	  ==	  true	  ((a+b)	  startsWith	  a)	  	  ==	  tru...
List[Int]	  =>	  isPalindrome(list)	  	  (list.reverse	  ==	  list)	  ==>	  isPalindrome(list)	  	  (list.reverse	  !=	  l...
Behavior	  tesZng	  	  	   	  Every	  day	  MutaZon	  tesZng	  	  	   	  CriZcal	  code	  Property	  tesZng	   	  à	   ...
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	 ...
The hitchhicker’s guide to unit testing
The hitchhicker’s guide to unit testing
The hitchhicker’s guide to unit testing
Prochain SlideShare
Chargement dans…5
×

The hitchhicker’s guide to unit testing

1 173 vues

Publié le

You already know TDD, your code coverage is almost at 80%, jUnit has no secret for you? But you feel that you could do more with your tests, the tools you use have limitations. Or maybe you're just tired of assertEquals?

Don't panic! We will see how you can code tests. We will look upon:

- Mutation Testing
- BDD, Behaviour Driven Development
- Property Testing

Publié dans : Technologie
  • Soyez le premier à commenter

The hitchhicker’s guide to unit testing

  1. 1. The  hitchhicker’s  guide  to  unit  tes1ng  Rémy-­‐Christophe  Schermesser  @el_picador  
  2. 2. Ruby!  Scala!  Java!  Python!  PHP!  
  3. 3. Ruby!  Scala!  Java!  Python!  PHP!  But  don’t  forget  your  towel  
  4. 4. Test::Unit  ScalaTest  jUnit  uniFest  PHPUnit  
  5. 5. Test::Unit  ScalaTest  jUnit  uniFest  PHPUnit  Again  don’t  forget  your  towel  
  6. 6. JUnit  
  7. 7. assertEquals  At  the  beginning,  we  had  
  8. 8. Then  assertThatMyTestFitsOnOneLine(whatIExpect,  whatMyCodeIsDoing);  
  9. 9. And  void  testWithCamelCaseToReadItBeFer()  {  ...  }  
  10. 10. And  again  @Test  void  annotaZonsAreGoodForYourHealth()  {  ...  }  
  11. 11. And  again  again  void  testMyTest()  {      Obj  obj  =  new  Obj();    //  10  lignes  of  things    assertEquals(…);  }  
  12. 12. JUnit  
  13. 13. JUnit  Mocks  
  14. 14. JUnit  Fixtures  Mocks  
  15. 15. JUnit  Behavior  tes1ng  with  RSpec  
  16. 16. Problem  void  testMyTest()  {      Obj  obj  =  new  Obj();    //  10  lignes  of  things    assertEquals(…);  }  
  17. 17. Behavior  tesZng,  don’t  test,  do  describe  Describe  what  your  program  should  do  
  18. 18. One  test  One  (english)  sentence  Behavior  tesZng,  don’t  test,  do  describe  
  19. 19. RSpec,  don’t  panic,  factorize  and  do  DSL  
  20. 20. describe  CompaniesController  do        describe  "POST  create"  do              context  "when  recruiter    signed_in  with  no  company"  do                    …              end        end  end  
  21. 21. describe  CompaniesController  do        describe  "POST  create"  do              context  "when  recruiter    signed_in  with  no  company"  do                    …              end        end  end  
  22. 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. 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. 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. 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. 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. 27. Like  a  towel,  use  it  every  day  
  28. 28. JUnit  Muta1on  tes1ng  Behavior  tes1ng  with  Javalanche  
  29. 29. Code  coverage  has  limits  Code:  ctrl+c  Test:  ctrl+v  
  30. 30. Code  a  class  and  test  it  
  31. 31. Mutate  it  
  32. 32. &&  ++  !=  >  …  ||  -­‐-­‐  ==  <  …  Mutate  it  
  33. 33. if(a  &&  b)  {          i++;  }  else  {          i-­‐-­‐;  }  if(a || b) {     i++; } else {     i--; } if(a && b) {     i--; } else {     i--; } Mutate  it  
  34. 34. Kill  it  
  35. 35. mvn  test  ant  -­‐f  javalanche.xml  mutaZonTest  Kill  it  
  36. 36. Run  tests  Green  tests  Something’s  wrong  
  37. 37. Run  tests  Red  tests  Great  job!  
  38. 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. 39. Behavior  tes1ng  JUnit  Property  tes1ng   Muta1on  tes1ng  with  ScalaCheck  
  40. 40. How  to  test  string  concatenaZon  ?  assert(  ("ta"  +  "a")  ==  "taa"  )  
  41. 41. How  to  test  string  concatenaZon  ?  assert(  ("ta"  +  "a")  ==  "taa"  )  assert(  ("ta"  +  "b")  ==  "tab"  )  
  42. 42. How  to  test  string  concatenaZon  ?  assert(  ("ta"  +  "a")  ==  "taa"  )  assert(  ("ta"  +  "b")  ==  "tab"  )  …  
  43. 43. How  to  test  string  concatenaZon  ?  assert(  ("ta"  +  "a")  ==  "taa"  )  assert(  ("ta"  +  "b")  ==  "tab"  )  assert(  ("ta"  +  "z")  ==  "taz"  )  …  
  44. 44. How  to  test  string  concatenaZon  ?  assert(  ("ta"  +  "a")  ==  "taa"  )  assert(  ("ta"  +  "b")  ==  "tab"  )  assert(  ("ta"  +  "z")  ==  "taz"  )  …  But  boring  
  45. 45. ∀n∈N,  ∃!k∈N  (n  =  2k  ⋁  n  =  2k+1)  Remember  math  class?  ∀n,  n  =  42  
  46. 46. val  n:  Int  val  k:  Int    (n  ==  2k  ||  n  ==  2k  +  1)  ==  true  (n  %  2    ==  0  ||  n  %  2  ==  1)  ==  true    In  code  
  47. 47. 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  
  48. 48. List[Int]  =>  isPalindrome(list)    (list.reverse  ==  list)  ==>  isPalindrome(list)    (list.reverse  !=  list)  ==>  !isPalindrome(list)  Limits  
  49. 49. Behavior  tesZng        Every  day  MutaZon  tesZng        CriZcal  code  Property  tesZng    à    CriZcal  code  Share  and  Enjoy  
  50. 50. So  Long,  and  Thanks  for  All  the  Fish  Rémy-­‐Christophe  Schermesser  @el_picador  
  51. 51. 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)  

×