There WILL be bugs! Google --

There WILL be bugs! ! http://www.aleax.it/bayp14_twbb.pdf! ©2014 Google -- [email protected] 1 "Will there be bugs"? YES!!! with probability abo...
2 downloads 0 Views 8MB Size
There WILL be bugs! !

http://www.aleax.it/bayp14_twbb.pdf!

©2014 Google -- [email protected]

1

"Will there be bugs"? YES!!!

with probability above 0.9999...

Murphy's Law fully applies (& then some:-)

2 2

"When will there be bugs"? when you're pushing the envelope

new or new-to-you algorithms, fields, libraries, frameworks, ...

...there are new traps waiting for you

when you're doing humdrum, routine development or maintenance...

...what you've done 1,000 times before...

...your attention level's likely not 100%!

...and, in all cases in-between:-)

3 3

The 1 exception in my life

my very first program: 1 run, bug-free

1974: Fortran, conditional probabilities of suits in bridge, mainframe

3 HW majors, bridge enthusiasts (key!), no programming courses (NP), humble (!)

punched cards,"big brain" mystique (helped!)

"invented" code-reviewing, pair-prog x 1.5

had PCs been easily around (a bit later)...

...bugs would have abounded (later did!-)

...never ever happened again in my life! 4 4

Fast Forward 40 years... downside: we only got 1 run so couldn't possibly have run tests

not that we'd ever heard of testing!-)

nowadays, tests must be at the heart of bug avoidance, discovery, and fixing

...as they should have been in the '70s!-)

Knuth, 1977: "Beware of bugs in the above code; I have only proved it correct, not tested it"...!-)

but code reviews & pairing still help! 5 5

Where do bugs like to hide? Well, anywhere, actually!-)

6 6

Common bug-hiding places "advanced" stuff, or where you're "clever"

key fix: *simplify* (+, unit-test!)

where you did not fully understand the problem, architecture, platform

ditto +: acceptance tests, code reviews

boilerplate/duplicate code

Don't Repeat Yourself (DRY)

rarely executed code (error handling, ...)

key fix: unit-test w/mocking for errors

previously-buggy code ("regressions")

a special case of TDD 7 7

Simplify, simplify, simplify Kernighan: "Debugging is twice as hard as writing a program in the first place. If you're as clever as you can be when you write it, how will you ever debug it?"

break up long, complicated expressions (intermediate results -> local variables)

beware complex decision chains

and nested loops / recursion, esp. with many conditional break/continue stmts

regular expressions MUST be tested a LOT ( also see: regex101.com ) 8 8

Don't Repeat Yourself (DRY) Hunt and Thomas (1999): "Every piece of knowledge must have a single, unambiguous, authoritative representation in a system".

AKA Once and Only Once (focus on code)

copy-and-paste coding is a main antipattern breaking DRY / OaOO

duplicate code is the worst code smell

everything's changing all the time: with duplicates, you'll miss some needed change

abstract what varies, merge what doesn't

9 9

Before DRY, it's WET...: if foo(bar, baz):! return bar! else:! return baz! !

...! !

if foo(zip, zap):! return zip! else:! return zap + 1 10 10

...let's DRY it up! def picker(a, b, c=None):! if foo(a, b):! return a! else:! return b if c is None else b + c! ...! return picker(foo, bar)! ...! return picker(zip, zap, 1)!

11 11

Rarely executed code handling weird errors, corner cases

unittest.mock (3.3+; backports aplenty)

with mock.patch(...) as x:!

to locally replace ... with a Mock obj x

set return_value, side_effect, ...

after, may assert about x's calls &c

BEWARE:

all attributes and methods auto-appear

-> high danger of typoes!

use auto_spec to reduce the danger 12 12

A mock.patch example def foo():! try: never.fails()! except OopsItDid as e:! logging.warm('Failed: %s', e)! raise! ...! with mock.patch('never.fails'‡) as nf:! nf.side_effect = OopsItDid! with self.assertRaises(OopsItDid):! module_i_am_testing.foo()! ‡: add autospec=True &c 13 13

Why do bugs happen? Your brain tricks you!

Perception: See what you expect to see

Attention lapses

Overconfidence

Confirmation bias

You've written it: it's YOUR code, it's YOUR baby, you're really proud of it

bugs love to hide there, as `you won't see them` -- you're "too close" to see clearly

14 14

Remedies for your “tricksy brain” egoless programming

more eyeballs

open source

pair programming

code reviews

testing

`lint` and similar static-analysis tools

15 15

Egoless Programming Jerry Weinberg, "The Psychology of Computer Programming", 1971

1.Understand and accept that you will make mistakes; find them early!

2. You are not your code; reviews are to find problems, and find them they will -don't take it personally!

...

10. Critique code instead of people – be kind to the coder, not to the code 16 16

Eyeballs: open source Eric Raymond's "Linus Law" (1997): "given enough eyeballs, all bugs are shallow"

"Given a large enough beta-tester and co-developer base, almost every problem will be characterized quickly and the fix will be obvious to someone."

Glass "Facts and Fallacies about Software Engineering" (2003): "it's a fallacy"

"the rate at which additional bugs are uncovered does not scale linearly with the number of reviewers"

`goto fail`, `heartbleed`; see Mike Bland's http://martinfowler.com/articles/testingculture.html 17 17

Eyeballs: pair programming the "driver" codes, focuses on "tactical" aspects of completing the current task

the "observer" reviews-as-it-goes, ponders "strategic" issues, plays "safety net"

frequent role switches; talking through it

many empirical studies and meta-research confirm: higher quality, faster time, but larger effort, compared with `solo` progr.

effort estimation here is biased-high

e.g: P.P produces a higher `bus number` w/o extra study/analysis effort! 18 18

Eyeballs: code reviews traditional "high ceremony" `Fagan Inspections` -- multiple meetings, printed code, thorough line-by-line critique, ...

high cost, very slow, high efficacy

may "fail to see the forest for the trees", "bikeshedding" also a risk

lightweight, informal walkthroughs and critiques - much faster, also effective

especially with the right tool!

complementary, not alternative, to pair programming and testing 19 19

Testing

Jacob Kaplan-Moss: "code without tests is broken by design":-)

informal "just run it and see if it breaks"

quite ineffective, esp. by original author

automated light-weight "unit tests"

must run fast so you can and will keep re-testing even on minor changes

great at avoiding unit-specific issues

automated middle-weight "integration tests"

complementary, not alternative, to u-t's

focus on interaction between subsystems

formal heavy-weight "acceptance tests"/QA 20 20

Testing vs Eyeballs Testing: objectively shows bugs' presence

can never conclusively show absence:-)

automated -> re-run all the time

Eyeballs: complementary, not alternative

pick up issues testing can never reveal

lack of clarity, bad naming, complexity

not automated -> consume human time

A third leg for the anti-bug "stool": lint

automated, fast

uniform style -> more productive eyeballs 21 21

Anti-bug tools most important is source code control (svn, hg, git, ...) -- trace what changed and when

beware subtle merges, cherrypicks, ...

next, a testing framework (unittest &c)

a bug tracker (ideally integrating w/SCC)

a code review tool (ditto)

22 22

“What about debuggers?” only mild importance for fighting bugs

if the code's so complicated that you have to follow step by step, simplify it

can help as "learning device"

unfamiliar code, library, framework

23 23

Beware tool-itis!

a geek's natural attitude: "if I have the right tools, all bugs will flee in terror"

they won't flee: bugs are courageous!-)

tools, at best, help: they don't solve bugs

tools can in fact hurt, by distracting you

hours spent in front of a cool debugger

...yak-shaving (tracing just-fine code)...

MUCH more important than tools' details:

attitude, skill, care, focus on team&user

and esp: good practice (light process) 24 24

And yet, tools are cool:-)

...but, excessive power can hurt the unwise

debugger to interactively examine values: log them instead! (w/logging.debug)

then code a script to sanity-checks logs

big difference: it's automated!

SCC allows fancy integrates, merges, cherrypicks, and generally funky graphs

very high risk of introducing bugs!

keep SCC graphs clean and simple!

key idea: good enough IS good enough 25 25

Testing frameworks stdlib unittest: a good starting point

+ many extensions: nose & plugins, &c

coverage's important (figleaf's ok too:-)

use doctest only for examples in docs!

it's designed for that & does it well

automated test runners / CI

nosy, nosier, nosyd, PyZen; buildbot

mocks, fakes, stubs, spies, dummies, ...

unittest.mock, but use with care!-)

specialized: web, fuzzing, GUI, acceptance... 26 26

Web testing either: simulate a browser

simple, fast -- but, no Javascript, CSS &c!

best for unit-tests

or: automate a real browser

most powerful, realistic, but, slower

best for integration & acceptance tests

specific web frameworks may further help

from google.appengine.ext import testbed!

from django import test!

...

27 27

Good enough... pick one from each group

the standard-er, the better

28 28

Example: web testing either: simulate a browser

simple, fast -- but, no Javascript, CSS &c!

best for unit-tests

or: automate a real browser

most powerful, realistic, but, slower

best for integration & acceptance tests

specific web frameworks may further help

from google.appengine.ext import testbed!

from django import test!

...

29 29

Linting &c Logilab's pylint

very powerful, configurable

unused/unassigned variables

too-long modules/functions

style violations in naming, wspace, ...

pyflakes, pep8: limited, but fast

Clone Digger

finds some "clones" (duplicate code)

... 30 30

When to use a bug tracker Always!-)

"bug tracker" (BT) is a misnomer...:

track both bugs AND features

Integration w/SCC: any changeset must identify which BT entry it regards

ideally only 1: keep CSs small!

Integration w/code review tool: code reviewer can follow the BT entry to find out WHY the CS under review exists

BT entry points back to CSs fixing it 31 31

The worst kind of bug

race conditions (& their evil cousins: deadlock, starvation, ...)

alas, test don't help much (!); code reviews may if super-duper-hyper careful/thorough

prevention is by far the best cure here

avoid shared-RW-memory concurrency

message passing, shared-RO-mem OK

if you really can't, rigorously sequence lock acquisitions, a la Dijkstra

maybe a dedicated global-memorychanging thread w/Queue of changes 32 32

Test-Driven Development Again: Jerry Weinberg, "The Psychology of Computer Programming", 1971

`In program testing, the programmer who gets early "success" with his program is likely to stop testing too soon. One way to guard against this mistake is to prepare the tests in advance of testing and, if possible in advance of coding.`

write the tests; see them fail; fix code to pass each test; check they succeed; refactor and check they still succeed. 33 33

TDD: worth using? (1) (personal opinion here, but, based on substantial experience...)

for adding features...: hmmm...

what exactly do you unit-test?

proper test targets for most features, "user stories", are more suitable for acceptance/integration than unit tests

Behavior driven development (BDD): TDD variant based exactly on user stories

ideally written by users/PMs/&c

great if you get such users/PMs/&c:-) 34 34

TDD: worth using? (2) for fixing bugs...: absolutely YES!

you know exactly what to unit-test for:

the very bug you're fixing!

first, you write the new tests

...and make sure all the new tests fail

"reproduces the bug" in a known state

then, you fix the bug

...and make sure all the tests pass

the new tests stay in the test-suite

insurance against future regressions! 35 35

TDD: worth using? (3) for refactoring...: just *NOT APPLICABLE*!

you can NEVER safely refactor code not already well covered by good tests

ensuring such coverage is not "the start of the refactoring",

it's a *PRE-REQUISITE* of it!

Michael Feathers, "Working Effectively with Legacy Code", 2002 -- http:// www.objectmentor.com/resources/articles/ WorkingEffectivelyWithLegacyCode.pdf 36 36

Q&A http://www.aleax.it/bayp14_twbb.pdf!

?

! 37 37

Suggest Documents