71
Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution Lice See http://software-carpentry.org/license.html for more informati Testing

Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Embed Size (px)

Citation preview

Page 1: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Introduction

Copyright © Software Carpentry 2010

This work is licensed under the Creative Commons Attribution License

See http://software-carpentry.org/license.html for more information.

Testing

Page 2: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Nobody enjoys testing

Page 3: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Nobody enjoys testing

So you can skip this lecture if

Page 4: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Nobody enjoys testing

So you can skip this lecture if

– your programs always work correctly, or

Page 5: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Nobody enjoys testing

So you can skip this lecture if

– your programs always work correctly, or

– you don't care if they're correct or not, so long

as their output looks plausible, and

Page 6: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Nobody enjoys testing

So you can skip this lecture if

– your programs always work correctly, or

– you don't care if they're correct or not, so long

as their output looks plausible, and

– you like being inefficient

Page 7: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Nobody enjoys testing

So you can skip this lecture if

– your programs always work correctly, or

– you don't care if they're correct or not, so long

as their output looks plausible, and

– you like being inefficient

The more you invest in quality, the less total time

it takes to build working software

Page 8: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Testing tells you:

Page 9: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Testing tells you:

– if the program is doing what it's supposed to

Page 10: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Testing tells you:

– if the program is doing what it's supposed to

– what the program actually is supposed to do

Page 11: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Testing tells you:

– if the program is doing what it's supposed to

– what the program actually is supposed to do

Tests are runnable specifications

Page 12: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Testing tells you:

– if the program is doing what it's supposed to

– what the program actually is supposed to do

Tests are runnable specifications

– Less likely to fall out of sync with the program

than documentation

Page 13: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Quality is not just testing

Page 14: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Quality is not just testing

Trying to improve the quality of software by

doing more testing is like trying to lose weight

by weighing yourself more often.

– Steve McConnell

Page 15: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Quality is not just testing

Trying to improve the quality of software by

doing more testing is like trying to lose weight

by weighing yourself more often.

– Steve McConnell

Good tests localize problems to speed up debugging

Page 16: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Testing comparison of 7-digit phone numbers

Page 17: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Testing comparison of 7-digit phone numbers

107 possible numbers

Page 18: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Testing comparison of 7-digit phone numbers

107 possible numbers

(107)2 possible pairs of numbers

Page 19: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Testing comparison of 7-digit phone numbers

107 possible numbers

(107)2 possible pairs of numbers

At 106 million tests/sec, that's 155 days

Page 20: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Testing comparison of 7-digit phone numbers

107 possible numbers

(107)2 possible pairs of numbers

At 106 million tests/sec, that's 155 days

...and then you start testing the next function

Page 21: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

How do you know that your tests are correct?

Page 22: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

"All" testing can do is show that

there might be a problem

Page 23: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

"It might work in practice,

but it'll never work in theory."

Page 24: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

If testing isn't easy, people won't do it

Page 25: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

If testing isn't easy, people won't do it

Must be easy to:

Page 26: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

If testing isn't easy, people won't do it

Must be easy to:

– add or change tests

Page 27: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

If testing isn't easy, people won't do it

Must be easy to:

– add or change tests

– understand existing tests

Page 28: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

If testing isn't easy, people won't do it

Must be easy to:

– add or change tests

– understand existing tests

– run tests

Page 29: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

If testing isn't easy, people won't do it

Must be easy to:

– add or change tests

– understand existing tests

– run tests

– understand test results

Page 30: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

If testing isn't easy, people won't do it

Must be easy to:

– add or change tests

– understand existing tests

– run tests

– understand test results

And test results must be reliable

Page 31: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

If testing isn't easy, people won't do it

Must be easy to:

– add or change tests

– understand existing tests

– run tests

– understand test results

And test results must be reliable

– No false positives or false negatives

Page 32: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

A unit test tests one component in a program

Page 33: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

fixture

A unit test tests one component in a program

Page 34: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

fixture

A unit test tests one component in a program

What the test

is run on

Page 35: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

fixture

action

A unit test tests one component in a program

Page 36: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

fixture

action

A unit test tests one component in a program

What's done to

the fixture

Page 37: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

fixture

action

A unit test tests one component in a program

expected result

Page 38: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

fixture

action

A unit test tests one component in a program

expected resultWhat should

happen

Page 39: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

fixture

action

A unit test tests one component in a program

expected result

actual result

Page 40: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

fixture

action

A unit test tests one component in a program

expected result

actual resultWhat actually

happened

Page 41: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

fixture

action

A unit test tests one component in a program

expected result

actual result

report

Page 42: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

fixture

action

A unit test tests one component in a program

expected result

actual result

report Summary

Page 43: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Test dna_starts_with

Page 44: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Test dna_starts_with

True if second argument is a prefix of the first

Page 45: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Test dna_starts_with

True if second argument is a prefix of the first

False otherwise

Page 46: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Test dna_starts_with

True if second argument is a prefix of the first

False otherwise

dna_starts_with('actggt', 'act') => True

Page 47: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Test dna_starts_with

True if second argument is a prefix of the first

False otherwise

dna_starts_with('actggt', 'act') => True

dna_starts_with('actggt', 'ctg') => False

Page 48: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Test dna_starts_with

True if second argument is a prefix of the first

False otherwise

dna_starts_with('actggt', 'act') => True

dna_starts_with('actggt', 'agt') => False

Do this one from scratch to show ideas

Page 49: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Test dna_starts_with

True if second argument is a prefix of the first

False otherwise

dna_starts_with('actggt', 'act') => True

dna_starts_with('actggt', 'agt') => False

Do this one from scratch to show ideas

Then introduce a library that can take care of

the repetitive bits

Page 50: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

# Test directly

assert dna_starts_with('a', 'a')

assert dna_starts_with('at', 'a')

assert dna_starts_with('at', 'at')

assert not dna_starts_with('at', 't')

Page 51: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

# Test directly

assert dna_starts_with('a', 'a')

assert dna_starts_with('at', 'a')

assert dna_starts_with('at', 'at')

assert not dna_starts_with('at', 't')

This works...

Page 52: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

This works...

...but there's a lot of repeated code...

# Test directly

assert dna_starts_with('a', 'a')

assert dna_starts_with('at', 'a')

assert dna_starts_with('at', 'at')

assert not dna_starts_with('at', 't')

Page 53: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

This works...

...but there's a lot of repeated code...

...and it's easy to overlook that not...

# Test directly

assert dna_starts_with('a', 'a')

assert dna_starts_with('at', 'a')

assert dna_starts_with('at', 'at')

assert not dna_starts_with('at', 't')

Page 54: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

This works...

...but there's a lot of repeated code...

...and it's easy to overlook that not...

...and it only tests up to the first failure

# Test directly

assert dna_starts_with('a', 'a')

assert dna_starts_with('at', 'a')

assert dna_starts_with('at', 'at')

assert not dna_starts_with('at', 't')

Page 55: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

# Tests in table

# Sequence Prefix Expected

Tests = [

['a', 'a', True],

['at', 'a', True],

['at', 'at', True],

['at, 't', False]

]

Page 56: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Easy to read

# Tests in table

# Sequence Prefix Expected

Tests = [

['a', 'a', True],

['at', 'a', True],

['at', 'at', True],

['at, 't', False]

]

Page 57: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Easy to read

Easy to add new tests

# Tests in table

# Sequence Prefix Expected

Tests = [

['a', 'a', True],

['at', 'a', True],

['at', 'at', True],

['at, 't', False]

]

Page 58: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

# Run and report

passes = 0

for (seq, prefix, expected) in Tests:

if dna_starts_with(seq, prefix) == expected:

passes += 1

print '%d/%d tests passed' % (passes, len(Tests))

Page 59: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

No runnable code is copied when adding tests

# Run and report

passes = 0

for (seq, prefix, expected) in Tests:

if dna_starts_with(seq, prefix) == expected:

passes += 1

print '%d/%d tests passed' % (passes, len(Tests))

Page 60: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

No runnable code is copied when adding tests

But when tests fail, we don't know which ones

# Run and report

passes = 0

for (seq, prefix, expected) in Tests:

if dna_starts_with(seq, prefix) == expected:

passes += 1

print '%d/%d tests passed' % (passes, len(Tests))

Page 61: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

# Run and report

passes = 0

for (i, (seq, prefix, expected)) in enumerate(Tests):

if dna_starts_with(seq, prefix) == expected:

passes += 1

else:

print 'test %d failed' % i

print '%d/%d tests passed' % (passes, len(Tests))

Page 62: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Produces (index, element)

for each element of list

# Run and report

passes = 0

for (i, (seq, prefix, expected)) in enumerate(Tests):

if dna_starts_with(seq, prefix) == expected:

passes += 1

else:

print 'test %d failed' % i

print '%d/%d tests passed' % (passes, len(Tests))

Page 63: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Decompose into variables

by matching structure

# Run and report

passes = 0

for (i, (seq, prefix, expected)) in enumerate(Tests):

if dna_starts_with(seq, prefix) == expected:

passes += 1

else:

print 'test %d failed' % i

print '%d/%d tests passed' % (passes, len(Tests))

Page 64: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Test passes as before

# Run and report

passes = 0

for (i, (seq, prefix, expected)) in enumerate(Tests):

if dna_starts_with(seq, prefix) == expected:

passes += 1

else:

print 'test %d failed' % i

print '%d/%d tests passed' % (passes, len(Tests))

Page 65: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Summarize results that

don't need attention

# Run and report

passes = 0

for (i, (seq, prefix, expected)) in enumerate(Tests):

if dna_starts_with(seq, prefix) == expected:

passes += 1

else:

print 'test %d failed' % i

print '%d/%d tests passed' % (passes, len(Tests))

Page 66: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

Report each result that

needs attention separately

# Run and report

passes = 0

for (i, (seq, prefix, expected)) in enumerate(Tests):

if dna_starts_with(seq, prefix) == expected:

passes += 1

else:

print 'test %d failed' % i

print '%d/%d tests passed' % (passes, len(Tests))

Page 67: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

This pattern is used for testing over and over

Page 68: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

This pattern is used for testing over and over

Many libraries to support it in many languages

Page 69: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

This pattern is used for testing over and over

Many libraries to support it in many languages

We'll look at one that comes with Python

Page 70: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

Testing Introduction

This pattern is used for testing over and over

Many libraries to support it in many languages

We'll look at one that comes with Python

But first, we'll look at how to handle errors

in programs systematically

Page 71: Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See

July 2010

created by

Greg Wilson

Copyright © Software Carpentry 2010

This work is licensed under the Creative Commons Attribution License

See http://software-carpentry.org/license.html for more information.