90
another pair of eyes: reviewing code well adam dangoor twitter: adamdangoor github: adamtheturtle

Another pair of eyes

Embed Size (px)

Citation preview

Page 1: Another pair of eyes

another pair of eyes: reviewing code well

adam dangoor

twitter: adamdangoorgithub: adamtheturtle

Page 2: Another pair of eyes

why?

Page 3: Another pair of eyes

why?

• great reviews have helped

“Yourcodesucks,andIhateyou”-biogpostbyjml

Page 4: Another pair of eyes

why?

• great reviews have helped

• bad reviews have harmed

Page 5: Another pair of eyes

why?

• great reviews have helped

• bad reviews have harmed

• hardly talked about

Page 6: Another pair of eyes

why?

• great reviews have helped

• bad reviews have harmed

• hardly talked about

Page 7: Another pair of eyes

why?

• great reviews have helped

• bad reviews have harmed

• hardly talked about

• little to no training

Page 8: Another pair of eyes

the plan

• what code review is

• how I review code

• some common pitfalls

• tools which can help

• becoming a better programmer

Page 9: Another pair of eyes

what is code review?

Page 10: Another pair of eyes

what is code review?

• catch bugs early - prevention is cheaper than cure

Page 11: Another pair of eyes

what is code review?

• catch bugs early - prevention is cheaper than cure

Page 12: Another pair of eyes

what is code review?

• catch bugs early - prevention is cheaper than cure

• find other defects early

Page 13: Another pair of eyes

what is code review?

• catch bugs early - prevention is cheaper than cure

• find other defects early

• share knowledge

Page 14: Another pair of eyes

what is code review?

• catch bugs early - prevention is cheaper than cure

• find other defects early

• share knowledge

Page 15: Another pair of eyes

the project’s other goals

Page 16: Another pair of eyes

setting the scene

Page 17: Another pair of eyes

setting the scene: the issue

Page 18: Another pair of eyes

setting the scene: the branch

eleanor~>gitcheckout-bshow-employer-2866

Page 19: Another pair of eyes

setting the scene: the code

defget_user_profile(user):“””Getadictrepresentingauser’sprofile.“””user_profile={}user_profile['Age']=user.get_age(unit='years')user_profile['TwitterHandle']=user.twitter_handlereturnuser_profile

Page 20: Another pair of eyes

setting the scene: the code

eleanor~> git diffdiff --git a/api/profiles.py b/api/profiles.pyindex 776e5e0..7fff02c 100644--- a/api/profiles.py+++ b/api/profiles.py@@ -2,7 +2,7 @@ user_profile['Age'] = user.get_age(unit='years') user_profile['Twitter Handle'] = user.twitter_handle + user_profile['Latest employer'] = \ + user.get_employers()[0].name return user_profile

Page 21: Another pair of eyes

setting the scene: the manual test

Page 22: Another pair of eyes

do we need a review?

Page 23: Another pair of eyes

do we need a review? (yes)

Page 24: Another pair of eyes

do we need a review for trivial changes?

Page 25: Another pair of eyes

do we need a review for urgent work?

Page 26: Another pair of eyes

stage fright

Page 27: Another pair of eyes

who should do the review?

Page 28: Another pair of eyes

who should do the review?

• someone with authorisation (technical or social)

Page 29: Another pair of eyes

who should do the review?

• someone with authorisation (technical or social)

• not an author

Page 30: Another pair of eyes

who should do the review?

• someone with authorisation (technical or social)

• not an author

• someone who has written nearby code

Page 31: Another pair of eyes

who should do the review?

• someone with authorisation (technical or social)

• not an author

• someone who has written nearby code

• or someone who has reviewed nearby code

Page 32: Another pair of eyes

but what about knowledge sharing?

Page 33: Another pair of eyes

code review as a new starter

Page 34: Another pair of eyes

code review as a new starter

Page 35: Another pair of eyes

how i do a review

Page 36: Another pair of eyes

read the spec

Page 37: Another pair of eyes

check ci

Page 38: Another pair of eyes

is the spec implemented?

Page 39: Another pair of eyes

have we interpreted the spec the same?

Page 40: Another pair of eyes

does the implementation look functionally correct?

Page 41: Another pair of eyes

has existing functionality been broken?

Page 42: Another pair of eyes

is it going to be easy to maintain?

Page 43: Another pair of eyes

is it going to be easy to maintain?

Page 44: Another pair of eyes

is everything documented?

Page 45: Another pair of eyes

learning

Page 46: Another pair of eyes

initiating a discussion

Page 47: Another pair of eyes

concluding a review

• Great, this looks good to me, I’ll merge it

• Please make the requested changes and then merge

• Please make the requested changes and then resubmit

• I’m not qualified to know whether this is a suitable change, let’s find someone else to have a look

Page 48: Another pair of eyes

getting better

Page 49: Another pair of eyes

ask for feedback

Page 50: Another pair of eyes

reviewing eleanor’s change

user_profile['Age'] = user.get_age(unit='years') user_profile['Twitter Handle'] = user.twitter_handle + user_profile['Latest employer'] = \ + user.get_employers()[0].name return user_profile

Page 51: Another pair of eyes

reviewing eleanor’s change

Page 52: Another pair of eyes

eleanor’s next steps

Page 53: Another pair of eyes

eleanor’s next steps

eleanor~> ag --ignore-case "latest employer”

~/Documents/bilbao_inc/api/profile.pyuser_profile['Latest employer'] = \

~/Documents/bilbao_inc/api/details_email.py "Latest employer: {latest_employer}".format(

Page 54: Another pair of eyes

being nice to people

Page 55: Another pair of eyes

always say one nice thing[1]

beingnicetopeople

[1] Divmod via jml

Page 56: Another pair of eyes

address the patch, not the person

beingnicetopeople

Page 57: Another pair of eyes

what else could be better?

Page 58: Another pair of eyes

what else could be better?

clearnextsteps

Page 59: Another pair of eyes

what else could be better?

thereviewstoppedtoosoon

user_profile['Twitter Handle'] = user.twitter_handle + user_profile['Latest employer'] = \ + user.get_employers()[0].name return user_profile

Page 60: Another pair of eyes

what else could be better?

whentostop

Page 61: Another pair of eyes

the next roundeleanor~> git diffdiff --git a/api/profiles.py b/api/profiles.pyindex 776e5e0..7fff02c 100644--- a/api/profiles.py+++ b/api/profiles.py@@ -2,7 +2,7 @@ user_profile['Age'] = user.get_age(unit='years') user_profile['Twitter Handle'] = user.twitter_handle + try: + user_profile['Latest employer'] = \ + user.get_employers()[0].name + except: + user_profile['Latest employer'] = \ + “This user does not have any employment history in the system yet.” return user_profile

Page 62: Another pair of eyes

the next round

• performance issue

Page 63: Another pair of eyes

the next round

• performance issue

• pep 8 violation

Page 64: Another pair of eyes

the next round

• performance issue

• pep 8 violation

• properties vs getters

Page 65: Another pair of eyes
Page 66: Another pair of eyes

priorities and context

Page 67: Another pair of eyes

style guide vs style rules

Page 68: Another pair of eyes

automate the boring stuff

flake8

Page 69: Another pair of eyes

automate the boring stuff

coverage.py&coveralls

Page 70: Another pair of eyes

requires.io

Page 71: Another pair of eyes

automate the boring stuff

landscape.io

Page 72: Another pair of eyes

automate the boring stuff

docstools

Page 73: Another pair of eyes

trade-offs

Page 74: Another pair of eyes

ignoring suggestions

#pylintthinksthatthisistoolongforafunctionname.#Ignorethaterror.defupdate_current_search_index():#pylint:disable-msg=C0103

Page 75: Another pair of eyes

configuring suggestions

[flake8]ignore=D203exclude=.git,__pycache__,docs/source/conf.py,old,build,distmax-complexity=10

Page 76: Another pair of eyes

github integration

Page 77: Another pair of eyes

reviewable.io

Page 78: Another pair of eyes

unrelated changes

Page 79: Another pair of eyes

unrelated changes

Page 80: Another pair of eyes

reviewable changes

Page 81: Another pair of eyes

reviewable changes are short

Magnetic platform guide: ~200 line changes max

Twisted: ~200 line changes max

Page 82: Another pair of eyes

reviewable changes include one logical unit of

change

Page 83: Another pair of eyes

writing reviewable code

Page 84: Another pair of eyes

silicon valley comma

Page 85: Another pair of eyes

silicon valley comma

landmarks = [ guggenheim, fine_arts_museum, basilica,+ euskalduna, ]

vs landmarks = [ guggenheim, fine_arts_museum,- basilica + basilica, + euskalduna, ]

Page 86: Another pair of eyes

semantic linefeeds

by brandon rhodes

adam~> git diffdiff --git a/api/example.txt b/api/example.txtindex 776e5e0..7fff02c 100644--- a/api/example.txt+++ b/api/example.txt@@ -2,7 +2,7 @@- The beauteous scheme is that now, + The beauty of this scheme is that now, if you change your mind about what a paragraph should look like,

Page 87: Another pair of eyes

tips vs requirements

Page 88: Another pair of eyes

learning by reviewing

Page 89: Another pair of eyes
Page 90: Another pair of eyes

cheers

adam dangoor

twitter: adamdangoorgithub: adamtheturtlestuffadammakes.com