21
[email protected] 1 Automated Debugging with git bisect TDD Camille Bell Agile Coach / Rails Developer [email protected] Twi3er @agilecamille h6p://www.slideshare.net/Camille_Bell/

Automate Debugging with git bisect

Embed Size (px)

DESCRIPTION

Even with the best agile development practices, bugs sometimes slip in. You don't want to manually wade through hundreds of commits and thousands or tens of thousands of lines of code to find your bug. See how find your bug fast using Git, the best (and free) version control software tool. If you are still using CVS, Subversion, or costly commercial version control, you are missing out.

Citation preview

Page 1: Automate Debugging with git bisect

[email protected]              1  

Automated Debugging with  git bisect  

TDD Camille  Bell  

Agile  Coach  /  Rails  Developer  

[email protected]  

Twi3er  @agilecamille  h6p://www.slideshare.net/Camille_Bell/  

Page 2: Automate Debugging with git bisect

[email protected]              2  

How  do  you  find  a  bug  in  a  large    code  base  with  lots  of  commits?  

1st   2nd   3rd   4th   97th   98th   99th   100th  

Page 3: Automate Debugging with git bisect

[email protected]              3  

Debugging  OpNons  

•  Manually  inspect  all  the  code  and  hope  you  

find  the  bug    "

•  Logically  eliminate  some  of  the  code,  inspect  

all  the  rest  and  hope  you  find  the  bug      

•  Use  automaNon  to  find  your  bug  fast      

Page 4: Automate Debugging with git bisect

[email protected]              4  

Steps  to  Target  the  Buggy  Code  

•  Create  new  or  use  an  exisNng  automated  bug  detector  to  disNnguish  between  bug  free  code  from  buggy  code  (usually  an  automated  test)  

•  Determine  the  bug  commit  range  – Use  git log    if  needed  

•  Use  git bisect –  Run  the  test  – Use    git diff    to  narrow  bug  to  code  lines  

Page 5: Automate Debugging with git bisect

[email protected]              5  

AutomaNng  Bug  DetecNon  

•  Perhaps  you  already  have  a  good  automated  test,  but  weren’t  running  it  with  every  commit.  Use  that  test  (and  set  up  a  CI  server  soon).  

•  If  not  create  a  new  test  that  should  fail  (RED)  when  the  bug  is  present  and  pass  (GREEN)  when  the  bug  is  fixed.    

– Write  the  test  in  whatever  test  language  makes  sense  (e.g.  RSpec  for  low  level  Ruby,  Cucumber  high  level  behavior,  Jasmine  for  JavaScript,  JUnit  for  Java,  NUnit  for  C#,  etc.)  

Page 6: Automate Debugging with git bisect

[email protected]              6  

Verify  the  Test  Catches  the  Bug  

•  Run  the  test  on  the  latest  buggy  code  and  watch  it  fail  (RED).  

•  Go  back  to  a  known  good  commit,  run  the  test  and  watch  it  pass  (GREEN).  

Page 7: Automate Debugging with git bisect

[email protected]              7  

$ rspec . –color F.

Failures:

1) Account depositing to account produces the correct balance when 9 dollars is deposited the balance is 10 dollars Failure/Error: @account.balance.should == 1000 expected: 1000 got: 999.9999 (using ==) # ./account_spec.rb:15:in `block (3 levels) in <top (required)>'

Finished in 0.00058 seconds 2 examples, 1 failure

Failed examples:

rspec ./account_spec.rb:12 # Account depositing to account produces the correct balance when 9 dollars is deposited the balance is 10 dollars $

Verifying  Failure  on    Known  Bad  Commit    

Page 8: Automate Debugging with git bisect

[email protected]              8  

$ rspec . –color ..

Finished in 0.00047 seconds 2 examples, 0 failures $

Verifying  Success  on  a  Known  Good  Commit    

Page 9: Automate Debugging with git bisect

[email protected]              9  

Running    git bisect  

•  Start  with  a  known  bad  git repository  –  $  git bisect start –  $  git bisect bad –  $  git bisect good <good_commit>  

•  Run  your  tests  •  If  the  test  passes  –  $  git bisect good

•  If  the  test  fails  – $ git bisect bad

•  Repeat  unNl  you  find  the  bad  commit

Use  either  tag    or  git  commit  #  

If  needed  checkout  a  bad  git  commit  #  

Page 10: Automate Debugging with git bisect

[email protected]              10  

""""" """

Determine  the  Bug  Commit  Range:  •     The  last  known  commit  without  the  bug  

•     The  first  commit  aeer  the  bug  observed  

StarNng  Good  Commit  

StarNng  Bad  

Commit  

Bug  Inserted  Within    These  8  Commits  

Page 11: Automate Debugging with git bisect

[email protected]              11  

git bisect does  a  binary  search  through  your  commit  range.  

""""" """

Good    Commit  

Bad    Commit  

bisect    StarNng      Commit  

bisect begins  with  the  commit  halfway  between  the  known  good  commit  and  the  known  bad  commit  

Page 12: Automate Debugging with git bisect

[email protected]              12  

Assume  the  1st  test  on  bisect failed.  

""""" """

Good    Commit  

Bad    Commit  

bisect    Next      

Commit  

 Then    bisect would  select  the  commit  between  the  known  good  commit  and  the  last  bad  bisect  

Bad    Commit  

Can  ignore  these  Commits  

Bug  inserted  Within    These  4  Commits  

Page 13: Automate Debugging with git bisect

[email protected]              13  

Assume  the  2nd  test  on  bisect passed.  

""" """

Good    Commit  

Bad    Commit  

 Then    bisect would  select  the  commit  between  the  last  known  good  commit  and  the  last  bad  bisect  

Bad    Commit  

Can  ignore  these  Commits  

Bug  inserted  Within    These  2  Commits  

Can  ignore  these  Commits  

Good    Commit  

bisect    Next      

Commit  

Page 14: Automate Debugging with git bisect

[email protected]              14  

If  the  3rd  test  on  bisect failed.  

""" """

Good    Commit  

Bad    Commit  

 Then  that  commit  is  where  the  bug  was  inserted.    

Bad    Commit  

Can  ignore  these  Commits  

Bug  inserted  Within    These  2  Commits  

Can  ignore  these  Commits  

Good    Commit  

Final  Commit      Failed  Test  

Page 15: Automate Debugging with git bisect

[email protected]              15  

If  the  3rd  test  on  bisect passed.  

"""""

Good    Commit  

Bad    Commit  

 Then  the  next  commit  is  where  the  bug  was  inserted.    

Bad    Commit  

Can  ignore  these  Commits  

Bug  inserted  Within    These  2  Commits  

Can  ignore  these  Commits  

Good    Commit  

Final  Commit      Passed  Test  

Page 16: Automate Debugging with git bisect

[email protected]              16  

Example  Test  require_relaNve  'account'  

describe  Account  do  

   before  do          @starNng_balance_in_pennies  =  100          @account  =  Account.new(@starNng_balance_in_pennies)              end  

   context  "deposiNng  to  account  produces  the  correct  balance"  do  

       it  "when  9  dollars  is  deposited  the  balance  is  10  dollars"  do                  deposit_amount_in_pennies  =  900              @account.deposit(deposit_amount_in_pennies)              @account.balance.should  ==  1000          end      end  

end  

Page 17: Automate Debugging with git bisect

[email protected]              17  

SomeNmes  the  Commit  Messages    from  git log Pinpoint  the  Bug  

$ git log --pretty="%h - %s" 561bb3a - added withdrawal and deposit messages 6ca7ee1 - added error c546d1f - added to_s 1974592 - added withdrawal 7a8c508 - Initial commit

But  usually  the  log  only  provides  a  range  

Known  Good  Commit  

Known  Bad  

Commit  

Page 18: Automate Debugging with git bisect

[email protected]              18  

StarNng  up  git bisect with  Test  on  the  Middle  git Commit  

$ git bisect start Already on 'master’ $ git bisect bad $ git bisect good 7a8c508 Bisecting: 1 revision left to test after this (roughly 1 step) [c546d1f89b5b0c14ab160e227fc83d62fb780e6f] added to_s $ rspec . --color ..

Finished in 0.00071 seconds 2 examples, 0 failures $ git bisect good Bisecting: 0 revisions left to test after this (roughly 0 steps) [6ca7ee1909bf0b3f7344feee25a5b44a97602e2c] added error

Known  Good  Commit  

Known  Bad  Commit  

If  the  tests  pass,    Tell    git bisect good

Otherwise  git bisect bad

C  O  M  M  I  T  

Page 19: Automate Debugging with git bisect

[email protected]              19  

Test  on  the  final  git commit  $ rspec . --color F.

Failures:

1) Account depositing to account produces the correct balance when 9 dollars is deposited the balance is 10 dollars Failure/Error: @account.balance.should == 1000 expected: 1000 got: 999.9999 (using ==) # ./account_spec.rb:15:in `block (3 levels) in <top (required)>'

Finished in 0.00053 seconds 2 examples, 1 failure

Failed examples:

rspec ./account_spec.rb:12 # Account depositing to account produces the correct balance when 9 dollars is deposited the balance is 10 dollars $

Page 20: Automate Debugging with git bisect

[email protected]              20  

$ git diff c546d1f 6ca7ee1 diff --git a/account.rb b/account.rb index a979e55..0a572ef 100644 --- a/account.rb +++ b/account.rb @@ -5,7 +5,7 @@ class Account end

def deposit(new_deposit)

- @balance += new_deposit + @balance += (new_deposit - 0.0001) end

def withdrawl(new_withdrawl) $

git diff Targets  the  Bug  Even  More  Good  Commit  Just  Before  Bug  

Commit  Where  Bug  First  Appeared  

Bug  inserted  in  one  or  

more  of  the  +  lines.  

Page 21: Automate Debugging with git bisect

[email protected]              21  

Thank You for Listening  

Camille  Bell  

Agile  Coach  /  Rails  Developer  

[email protected]  

Twi3er  @agilecamille  h6p://www.slideshare.net/Camille_Bell/