Program Design Invasion Percolation: Testing

Slides:



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

Interfaces Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Def f(n): if (n == 0): return else: print(“*”) return f(n-1) f(3)
Slicing Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Control Flow Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
1 Advanced Material The following slides contain advanced material and are optional.
CS 635 Advanced Object-Oriented Design & Programming Spring Semester, 2006 Doc 2 Terms & Testing Jan 24, 2006 Copyright ©, All rights reserved SDSU.
Lists in Python.
Steganography Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
CSC1018F: Object Orientation, Exceptions and File Handling Diving into Python Ch. 5&6 Think Like a Comp. Scientist Ch
Functions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Program Design CMSC 201. Motivation We’ve talked a lot about certain ‘good habits’ we’d like you guys to get in while writing code. There are two main.
Fixtures Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Lecture 06 – Reading and Writing Text Files.  At the end of this lecture, students should be able to:  Read text files  Write text files  Example.
COMPSCI 101 Principles of Programming Lecture 25 – Nested loops, passing mutable objects as parameters.
By for Testing Tools: Test Automation and supporting tools Jariro Pava, Robert Vanderwall 1 WISTPC-14.
Invasion Percolation: Assembly Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Improving the Quality of Existing Code Svetlin Nakov Telerik Corporation
Hey, Ferb, I know what we’re gonna do today! Aims: Use formatted printing. Use the “while” loop. Understand functions. Objectives: All: Understand and.
Pipes and Filters Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Chapter 8 More On Functions. "The Practice of Computing Using Python", Punch & Enbody, Copyright © 2013 Pearson Education, Inc. First cut, scope.
Libraries Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Sylnovie Merchant, Ph.D. MIS 161 Spring 2005 MIS 161 Systems Development Life Cycle II Lecture 5: Testing User Documentation.
Introduction Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
More Tools Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Interface and Implementation Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
…and how to do stuff with them Copyright © The University of Southampton 2011 This work is licensed under the Creative Commons Attribution License See.
Inheritance Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Introduction Copyright © Software Carpentry This work is licensed under the Creative Commons Attribution License See
First-Class Functions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Basic Flow Control Copyright © Software Carpentry 2011 This work is licensed under the Creative Commons Attribution License See
Lists Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Rollback Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Finding Things Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
SEG 4110 – Advanced Software Design and Reengineering Topic T Introduction to Refactoring.
Operators Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Invasion Percolation: Randomness Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Exceptions Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Dictionaries Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
Head First Python: Ch 3. Files and Exceptions: Dealing with Errors Aug 26, 2013 Kyung-Bin Lim.
Today… Strings: –String Methods Demo. Raising Exceptions. os Module Winter 2016CISC101 - Prof. McLeod1.
Patterns Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See
OOAD Using the UML - Use-Case Analysis, v 4.2 Copyright  Rational Software, all rights reserved 1 Use Case Analysis – Part 4 Analysis Mechanisms.
Unit testing Why test your code when your code can test it for you?
Tutorial 2 Exam Revision. Notices Assignment + project Recap string formatting Revision.
Python Aliasing Copyright © Software Carpentry 2010
Topic: Recursion – Part 2
Program Design Invasion Percolation: Aliasing
Sets and Dictionaries Examples Copyright © Software Carpentry 2010
Program Design Invasion Percolation: Resolving Ties
Program Design Invasion Percolation: Neighbors
From Templates to Folds
Engineering Computing
Python 17 Mr. Husch.
Introduction to Python
Software Engineering Lecture #12.
CS 1111 Introduction to Programming Fall 2018
Version Control Basic Operation Copyright © Software Carpentry 2010
Programming Errors Key Revision Points.
MATLAB Programming Indexing Copyright © Software Carpentry 2011
Python 17 Mr. Husch.
Python programming exercise
Version Control Introduction Copyright © Software Carpentry 2010
Program Design Invasion Percolation: Bugs
Debugging “Why you were up till 2AM”
Greenfoot November 8, 2009.
Version Control Conflict Copyright © Software Carpentry 2010
Program Design Invasion Percolation: The Grid
Browsing Directories Using walk
Java Coding 6 David Davenport Computer Eng. Dept.,
Presentation transcript:

Program Design Invasion Percolation: Testing Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See http://software-carpentry.org/license.html for more information.

Program Design Invasion Percolation: Testing Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See http://software-carpentry.org/license.html for more information. 2

We found one bug 3

How many others haven't we found? We found one bug How many others haven't we found? 4

How many others haven't we found? We found one bug How many others haven't we found? How do we validate and verify this program? 5

How many others haven't we found? We found one bug How many others haven't we found? How do we verify and validate this program? - Verification: is our program free of bugs? 6

How many others haven't we found? We found one bug How many others haven't we found? How do we verify and validate this program? - Verification: is our program free of bugs? - Validation: are we using a good model? 7

How many others haven't we found? We found one bug How many others haven't we found? How do we verify and validate this program? - Verification: is our program free of bugs? - Validation: are we using a good model? The second question is a question for scientists... 8

How many others haven't we found? We found one bug How many others haven't we found? How do we verify and validate this program? - Verification: is our program free of bugs? - Validation: are we using a good model? The second question is a question for scientists... ...so we'll concentrate on testing our program 9

How many others haven't we found? We found one bug How many others haven't we found? How do we verify and validate this program? - Verification: is our program free of bugs? - Validation: are we using a good model? The second question is a question for scientists... ...so we'll concentrate on testing our program making our program testable 10

This grid... 2 1 11

This grid... 2 1 12

...should fill in like this This grid... 2 1 ...should fill in like this 2 -1 13

...should fill in like this If it doesn't, it should be This grid... 2 1 ...should fill in like this If it doesn't, it should be easy to figure out why not 2 -1 14

Overall program structure '''doc string''' def fail(...): ... def create_random_grid(N, Z): ... def mark_filled(grid, x, y): ... def is_candidate(grid, x, y): ... def find_candidates(grid): ... def fill_grid(grid): ... if __name__ == '__main__': ...

Overall program structure '''doc string''' def fail(...): ... def create_random_grid(N, Z): ... def mark_filled(grid, x, y): ... def is_candidate(grid, x, y): ... def find_candidates(grid): ... def fill_grid(grid): ... if __name__ == '__main__': ... This is what we want to test

Overall program structure '''doc string''' def fail(...): ... def create_random_grid(N, Z): ... def mark_filled(grid, x, y): ... def is_candidate(grid, x, y): ... def find_candidates(grid): ... def fill_grid(grid): ... if __name__ == '__main__': ... This is what we want to test Let's reorganize the code so that it's easy to create specific grids

Old structure ... def create_random_grid(N, Z): ... if __name__ == '__main__': grid = create_random_grid(grid_size, value_range)

New structure ... def create_grid(N): ... def fill_grid_random(grid, Z): ... if __name__ == '__main__': grid = create_grid(grid_size) fill_grid_random(grid, value_range)

New structure Create an N×N grid of zeroes ... def create_grid(N): ... def fill_grid_random(grid, Z): ... if __name__ == '__main__': grid = create_grid(grid_size) fill_grid_random(grid, value_range)

New structure Create an N×N grid of zeroes Overwrite cells with random values in 1..Z ... def create_grid(N): ... def fill_grid_random(grid, Z): ... if __name__ == '__main__': grid = create_grid(grid_size) fill_grid_random(grid, value_range)

New structure Create an N×N grid of zeroes Overwrite cells with random values in 1..Z We'll call something else when testing ... def create_grid(N): ... def fill_grid_random(grid, Z): ... if __name__ == '__main__': grid = create_grid(grid_size) fill_grid_random(grid, value_range)

Old structure ... if __name__ == '__main__': # Get parameters from command line. arguments = sys.argv[1:] try: grid_size = int(arguments[0]) value_range = int(arguments[1]) rand_seed = int(arguments[2]) except ...:

New structure ... if __name__ == '__main__': grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[1:])

Newer structure ... if __name__ == '__main__': scenario = sys.argv[1] grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) if scenario == 'random':

Newer structure ... if __name__ == '__main__': scenario = sys.argv[1] grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) if scenario == 'random': else: fail('Unknown scenario %s' % scenario)

We aren't going to need random numbers when we fill the grid manually for testing 27

We aren't going to need random numbers when we fill the grid manually for testing We're also not going to need the value range 28

We aren't going to need random numbers in cases where we fill the grid manually for testing We're also not going to need the value range Or the grid size 29

We aren't going to need random numbers in cases where we fill the grid manually for testing We're also not going to need the value range Or the grid size So move argument handling and RNG seeding into the random scenario 30

The revised structure ... if __name__ == '__main__': scenario = sys.argv[1] if scenario == 'random': grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) random.seed(rand_seed) else: fail('Unknown scenario %s' % scenario)

The revised structure ... if __name__ == '__main__': scenario = sys.argv[1] if scenario == 'random': grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) random.seed(rand_seed) else: fail('Unknown scenario %s' % scenario)

The revised structure ... if __name__ == '__main__': scenario = sys.argv[1] if scenario == 'random': grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) random.seed(rand_seed) else: fail('Unknown scenario %s' % scenario)

The revised structure ... if __name__ == '__main__': scenario = sys.argv[1] if scenario == 'random': grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) random.seed(rand_seed) else: fail('Unknown scenario %s' % scenario)

The revised structure ... if __name__ == '__main__': scenario = sys.argv[1] if scenario == 'random': grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) random.seed(rand_seed) else: fail('Unknown scenario %s' % scenario)

A closer look if scenario == 'random': grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) random.seed(rand_seed) grid = create_grid(grid_size) fill_grid_random(grid, value_range) mark_filled(grid, grid_size/2, grid_size/2) num_filled_cells = fill_grid(grid) + 1 print '%d cells filled' % num_filled_cells

A closer look if scenario == 'random': grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) random.seed(rand_seed) grid = create_grid(grid_size) fill_grid_random(grid, value_range) mark_filled(grid, grid_size/2, grid_size/2) num_filled_cells = fill_grid(grid) + 1 print '%d cells filled' % num_filled_cells

A closer look if scenario == 'random': grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) random.seed(rand_seed) grid = create_grid(grid_size) fill_grid_random(grid, value_range) mark_filled(grid, grid_size/2, grid_size/2) num_filled_cells = fill_grid(grid) + 1 print '%d cells filled' % num_filled_cells

A closer look if scenario == 'random': grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) random.seed(rand_seed) grid = create_grid(grid_size) fill_grid_random(grid, value_range) mark_filled(grid, grid_size/2, grid_size/2) num_filled_cells = fill_grid(grid) + 1 print '%d cells filled' % num_filled_cells

A closer look if scenario == 'random': grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) random.seed(rand_seed) grid = create_grid(grid_size) fill_grid_random(grid, value_range) mark_filled(grid, grid_size/2, grid_size/2) num_filled_cells = fill_grid(grid) + 1 print '%d cells filled' % num_filled_cells

A closer look if scenario == 'random': grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) random.seed(rand_seed) grid = create_grid(grid_size) fill_grid_random(grid, value_range) mark_filled(grid, grid_size/2, grid_size/2) num_filled_cells = fill_grid(grid) + 1 print '%d cells filled' % num_filled_cells

A closer look if scenario == 'random': grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) random.seed(rand_seed) grid = create_grid(grid_size) fill_grid_random(grid, value_range) mark_filled(grid, grid_size/2, grid_size/2) num_filled_cells = fill_grid(grid) + 1 print '%d cells filled' % num_filled_cells

A closer look if scenario == 'random': grid_size, value_range, rand_seed = \ parse_arguments(sys.argv[2:]) random.seed(rand_seed) grid = create_grid(grid_size) fill_grid_random(grid, value_range) mark_filled(grid, grid_size/2, grid_size/2) num_filled_cells = fill_grid(grid) + 1 print '%d cells filled' % num_filled_cells

These function names are too similar if scenario == 'random': ...get arguments... random.seed(rand_seed) grid = create_grid(grid_size) fill_grid_random(grid, value_range) mark_filled(grid, grid_size/2, grid_size/2) num_filled_cells = fill_grid(grid) + 1 print '%d cells filled' % num_filled_cells

So rename if scenario == 'random': ...get arguments... random.seed(rand_seed) grid = create_grid(grid_size) init_grid_random(grid, value_range) mark_filled(grid, grid_size/2, grid_size/2) num_filled_cells = fill_grid(grid) + 1 print '%d cells filled' % num_filled_cells

And since we do this in all scenarios... if scenario == 'random': ...get arguments... random.seed(rand_seed) grid = create_grid(grid_size) init_grid_random(grid, value_range) mark_filled(grid, grid_size/2, grid_size/2) num_filled_cells = fill_grid(grid) + 1 print '%d cells filled' % num_filled_cells And since we do this in all scenarios...

...move it into fill_grid if scenario == 'random': ...get arguments... random.seed(rand_seed) grid = create_grid(grid_size) init_grid_random(grid, value_range) num_filled_cells = fill_grid(grid) print '%d cells filled' % num_filled_cells ...move it into fill_grid

Reminder of revised program structure '''doc string''' def fail(...): ... def create_grid(N): ... def init_grid_random(grid, Z): ... def mark_filled(grid, x, y): ... def is_candidate(grid, x, y): ... def find_candidates(grid): ... def fill_grid(grid): ... def parse_arguments(arguments): ... if __name__ == '__main__': ...

Created by splitting a function that was doing two things '''doc string''' def fail(...): ... def create_grid(N): ... def init_grid_random(grid, Z): ... def mark_filled(grid, x, y): ... def is_candidate(grid, x, y): ... def find_candidates(grid): ... def fill_grid(grid): ... def parse_arguments(arguments): ... if __name__ == '__main__': ... Created by splitting a function that was doing two things

Fills middle cell at the start, and returns count of all filled cells '''doc string''' def fail(...): ... def create_grid(N): ... def init_grid_random(grid, Z): ... def mark_filled(grid, x, y): ... def is_candidate(grid, x, y): ... def find_candidates(grid): ... def fill_grid(grid): ... def parse_arguments(arguments): ... if __name__ == '__main__': ... Fills middle cell at the start, and returns count of all filled cells

Handle arguments '''doc string''' def fail(...): ... def create_grid(N): ... def init_grid_random(grid, Z): ... def mark_filled(grid, x, y): ... def is_candidate(grid, x, y): ... def find_candidates(grid): ... def fill_grid(grid): ... def parse_arguments(arguments): ... if __name__ == '__main__': ... Handle arguments

Handle arguments for random case '''doc string''' def fail(...): ... def create_grid(N): ... def init_grid_random(grid, Z): ... def mark_filled(grid, x, y): ... def is_candidate(grid, x, y): ... def find_candidates(grid): ... def fill_grid(grid): ... def parse_arguments(arguments): ... if __name__ == '__main__': ... Handle arguments for random case

Handle arguments for random case We should rename it to make that '''doc string''' def fail(...): ... def create_grid(N): ... def init_grid_random(grid, Z): ... def mark_filled(grid, x, y): ... def is_candidate(grid, x, y): ... def find_candidates(grid): ... def fill_grid(grid): ... def parse_arguments(arguments): ... if __name__ == '__main__': ... Handle arguments for random case We should rename it to make that clear...

'''doc string''' def fail(...): ... def create_grid(N): ... def init_grid_random(grid, Z): ... def mark_filled(grid, x, y): ... def is_candidate(grid, x, y): ... def find_candidates(grid): ... def fill_grid(grid): ... def parse_arguments_random(arguments): ... if __name__ == '__main__': ...

We set out to test our program...

We set out to test our program... ...but found we had to reorganize it first

We set out to test our program... ...but found we had to reorganize it first refactor

We set out to test our program... ...but found we had to reorganize it first refactor Refactoring: changing a program's structure without modifying its behavior or functionality in order to improve its quality

There are whole books about how to do this systematically

There are whole books about how to do this systematically The original

There are whole books about how to do this systematically The original Mostly a catalog of refactorings for object-oriented programs

There are whole books about how to do this systematically The original Mostly a catalog of refactorings for object-oriented programs How to refactor legacy programs to make them more testable

There are whole books about how to do this systematically The original Mostly a catalog of refactorings for object-oriented programs How to refactor legacy programs to make them more testable Examples drawn from many languages

And now we can start testing our program 64

Greg Wilson created by May 2010 Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See http://software-carpentry.org/license.html for more information.