Python MIT OCW Lec7 : Testing, Debugging, Exceptions, Assertions

김재만·2023년 9월 20일
0

Python MIT OCW

목록 보기
7/9

배울 내용

  1. Testing
  2. Debugging
  3. Exceptions
  4. Assertions

1. Good Programming

  • Defensive Programming
    : Write specifications for functions
    : Modularize
    : Check conditions for inputs/outputs

  • Testing / Validation
    : Compare input / output

  • Debugging
    : Study events leading up to an error

2. Testing

Set yourself up for easy testing and debugging

  • 처음부터 디버깅이 쉽게 코드를 짜라
  • Modularize
  • Document constraints on modules
    : what do you expect the input to be?
    : what do you expect the output to be?
  • Document assumptions behind code design

Classes of tests

  1. Unit testing
    : validate each piece of program
    : testing each function separately

  2. Regression testing
    : add test for bugs
    : catch reintroduced errors -> return to step 1

  3. Integration testing
    : does overall program work?
    : catch error -> return to step 1

Testing Approaches

  • Black box testing
    : explore paths through specification

  • Glass box testing
    : explore paths through code

Black Box Testing

  • Designed without looking at the code

  • Paths through specification
    : build test cases in different natural space partitions
    : also consider boundary conditions (empty lists, singleton list, large numbers, small numbers)

  • Input을 넣었을 때 Output이 어떻게 되는가?

Glass Box Testing

  • Use code directly to guide design of test cases
  • Called path-complete if every potential path through code is tested at least once
  1. Branches
    : exercise all parts of a conditional

  2. For loops
    : loop not entered
    : body of loop executed exactly once
    : body of loop executed more than once

  3. While loops
    : same as for loops, cases that catch all ways to exit loop

  • example
def abs(x) : 
  """
  Assumes x is an int
  Returns x if x >= 0 and -x otherwise
  """

  if x < -1 :
    return -x
  
  else : 
    return x

: a path-complete test suite coud miss a bug
: path-complete test suite : 2 and -2
: but abs(-1) incorrectly returns -1 -> should still test boundary cases

3. Debugging

  • Steep learning curve
  • Tools
    : built-in to IDLE and Anaconda
    : Python Tutor
    : print statement (특히 함수 내에서) -> good way to test hypothesis, 매우 중요하다

Don't and Do

  • Don't
    : Write / Test / Debug entire program
    : Change code -> Remember where bug was -> Test code -> Forget where bug was or what change you made -> panic
  • Do
    : Write / Test / Debug a function
    : Backup code -> change code -> write down potential bug in a comment -> Test code -> Compare new version with old version

4. Exceptions

Exceptions

  • IndexError
    : Trying to access beyond list limits

    	test = [1, 7, 4]
    	test[4]
  • TypeError
    : Trying to convert an inappropriate type

    	int(test)
  • NameError
    : Referencing a non-existing variable

  • TypeError
    : Mixing data types without coercion (강제)

  • SyntaxError
    : Python can't parse program

  • AttributionError
    : attribute reference fails

  • ValueError
    : operand type okay, but value is illegal

  • IOError
    : IO system reports malfunction (e.g. file not found)

Dealing with exceptions

  • See this code
try : 
  a = int(input("Tell me one number:"))
  b = int(input("Tell me another number:"))
  print(a/b)
except : 
  print("Bug in user input.")
  • Exceptions raised by any statement in body of try are handled by the except statement and execution continues with the body of the except statement

  • 예를 들어 a와 b 모두 정수를 입력해주면 print(a/b) 가 정상적으로 실행되고, a나 b에 float number를 넣어주면 (ValueError) except : 이후의 코드를 실행한다.

Handling Specific Exceptions

  • Exception Type에 따라 다른 코드를 실행하도록 할 수 있다.
try : 
  a = int(input("Tell me one number:"))
  b = int(input("Tell me another number:"))
  print("a/b = ", a/b)
  print("a+b = ", a+b)
except ValueError :
  print("Could not convert to a number")
except ZeroDivisionError : 
  print("Can't divide by zero")
except : 
  print("Something went very wrong.")
  • 코드를 실행해 보면, float number를 넣으면 ValueError에 해당하는 코드가, b에 0을 넣으면 ZeroDvisionError에 해당하는 코드가 실행되는 것을 볼 수 있다.

Other Exceptions

  • else
    : when try body completes with no exceptions
  • finally
    : always executed after try, else, and except clauses, even if they raised another error or executed a break, continue or return

Exceptions As Control Flow

  • Raise an exception when unable to produce a result consistent with function's specification
raise <exceptionname> (<arguments>
// exceptionname : value of error you want to raise
// arguments : optional, but typically a string with a message
// example

raise ValueError("something is wrong")
  • Example
def get_ratios(L1, L2) : 
  """
  Assumes : L1 and L2 are lists of equal length of numbers
  Returns : a list containing L1[i]/L2[i]
  """

  ratios = []
  for index in range(len[L1]) : 
    try : 
      ratios.append(L1[index] / L2[index])
    except ZeroDivisionError : 
      ratios.append(float('nan')) # nan = not a number
    except : 
      raise ValueError('get_ratios called with bad arg')
    
    return ratios

5. Assertions

  • Want to be sure that assumptions on state of computation are as expected
    : Use an assert statement to raise an AssertonError exception if assumptions not met

  • An example of good defensive programming

  • Format :

def avg(grades) : 
  assert len(grades) != 0, 'no grades data'
  return sum(grades) / len(grades)
  • Raises an AssertionError if it is given an empty list for grades, otherwise runs ok
  • assert 'condition' 에서 condition에 원하는 assumptions이 들어가야한다.

Assertions as Defensive Programming

  • Assertions don't allow a programmer to control response to unexpected conditions

  • Ensure that execution halts whenever an expected condition is not met

  • Typically used to check inputs to functions, but can be used anywhere

  • Can be used to check outputs of a function to avoid propagating bad values

  • Can make it easier to locate a source of a bug

Where to use Assertions?

  • Goal is to spot bugs as soon as introduced and make clear where they happened
  • Use as a supplement to testing
    : Raise exceptions if user supplies bad data input
  • Use assertions to
    : check types of arguments or values
    : check that invariants on data structures are met
    : check constraints on return values
    : check for violations of constraints on procedure
profile
Hardware Engineer가 되자

0개의 댓글