Unit Testing.

Slides:



Advertisements
Similar presentations
1 Design by Contract Building Reliable Software. 2 Software Correctness Correctness is a relative notion  A program is correct with respect to its specification.
Advertisements

CS 106 Introduction to Computer Science I 11 / 09 / 2007 Instructor: Michael Eckmann.
Chapter 5: Loops and Files.
Computer Science 1620 Programming & Problem Solving.
CMSC 104, Version 8/061L18Functions1.ppt Functions, Part 1 of 4 Topics Using Predefined Functions Programmer-Defined Functions Using Input Parameters Function.
Testing Michael Ernst CSE 140 University of Washington.
Contract based programming Using pre- and post-conditions, and object invariants Contract based programming1.
Oct 15, 2007Sprenkle - CS1111 Objectives Creating your own functions.
What does C store? >>A = [1 2 3] >>B = [1 1] >>[C,D]=meshgrid(A,B) c) a) d) b)
CSC 110 Using Python [Reading: chapter 1] CSC 110 B 1.
Lecture 26: Reusable Methods: Enviable Sloth. Creating Function M-files User defined functions are stored as M- files To use them, they must be in the.
Loops and Files. 5.1 The Increment and Decrement Operators.
11. EXCEPTION HANDLING Rocky K. C. Chang October 18, 2015 (Adapted from John Zelle’s slides)
Python Let’s get started!.
Repetition Statements (Loops). 2 Introduction to Loops We all know that much of the work a computer does is repeated many times. When a program repeats.
Random Test Generation of Unit Tests: Randoop Experience
Google C++ Testing Framework Part 2: Assertion. Concepts A test case contains one or many tests. ◦ You should group your tests into test cases that reflect.
Course A201: Introduction to Programming 09/09/2010.
CMSC 104, Section 301, Fall Lecture 18, 11/11/02 Functions, Part 1 of 3 Topics Using Predefined Functions Programmer-Defined Functions Using Input.
Today… Modularity, or Writing Functions. Winter 2016CISC101 - Prof. McLeod1.
FUNCTIONS (C) KHAERONI, M.SI. OBJECTIVE After this topic, students will be able to understand basic concept of user defined function in C++ to declare.
CS 115 Lecture 5 Math library; building a project Taken from notes by Dr. Neil Moore.
CSC 1010 Programming for All Lecture 5 Functions Some material based on material from Marty Stepp, Instructor, University of Washington.
Introduction to Computing Science and Programming I
User-Written Functions
Introducing Instructions
Python Let’s get started!.
Introduction to Python
Introduction To Repetition The for loop
Matlab Training Session 4: Control, Flow and Functions
Chapter 8 – Software Testing
The Pseudocode Programming Process
The Selection Structure
Variables, Expressions, and IO
Functions CIS 40 – Introduction to Programming in Python
Algorithm and Ambiguity
Sentinel logic, flags, break Taken from notes by Dr. Neil Moore
Methods The real power of an object-oriented programming language takes place when you start to manipulate objects. A method defines an action that allows.
Design by Contract Fall 2016 Version.
Subroutines Idea: useful code can be saved and re-used, with different data values Example: Our function to find the largest element of an array might.
IPC144 Introduction to Programming Using C Week 1 – Lesson 2
Chapter 4 LOOPS © Bobby Hoggard, Department of Computer Science, East Carolina University / These slides may not be used or duplicated without permission.
Software Construction
Higher-Order Procedures
Sentinel logic, flags, break Taken from notes by Dr. Neil Moore
Alternate Version of STARTING OUT WITH C++ 4th Edition
Scratch: selection / branching/ if / If…else / compound conditionals / error trapping by Mr. Clausen.
Escape sequences: Practice using the escape sequences on the code below to see what happens. Try this next code to help you understand the last two sequences.
CISC101 Reminders Assn 3 due tomorrow, 7pm.
1) C program development 2) Selection structure
Coding Concepts (Basics)
Chapter 6: Repetition Statements
Python programming exercise
CISC101 Reminders All assignments are now posted.
CISC101 Reminders Assignment 3 due next Friday. Winter 2019
Introduction to Computer Science
COMPUTER PROGRAMMING SKILLS
CSE 1020:Software Development
Data Types Every variable has a given data type. The most common data types are: String - Text made up of numbers, letters and characters. Integer - Whole.
What is a Function? Takes one or more arguments, or perhaps none at all Performs an operation Returns one or more values, or perhaps none at all Similar.
CISC101 Reminders Assignment 3 due today.
The while Looping Structure
Functions Taken from notes by Dr. Neil Moore & Dr. Debby Keen
Software Construction
 A function is a named sequence of statement(s) that performs a computation. It contains  line of code(s) that are executed sequentially from top.
Intro to Programming (in JavaScript)
Chapter 1: Creating a Program.
Data Types and Expressions
Defining Functions.
Functions and Abstraction
Presentation transcript:

Unit Testing

Today's Goal Functions are the basic building block of programs. Today, you'll learn to test functions, and how to design testable functions.

Testing Functions Amy is writing a program. She adds functionality by defining a new function, and adding a function call to the new function in the main program somewhere. Now she needs to test the new code. Two basic approaches to testing the new code: Run the entire program The function is tested when it is invoked during the program execution Test the function by itself, somehow Which do you think will be more efficient?

Manual Unit Test A unit test is a program that tests a function to determine if it works properly A manual unit test Gets test input from the user Invokes the function on the test input Displays the result of the function How would you use a unit test to determine that roundIt() works correctly? How does the test - debug cycle go? def roundIt(num: float) -> int: return int(num + .5) # ---- manual unit test ---- x = float(input('Enter a number:')) result = roundIt(x) print('Result: ', result)

Automated Unit Test An automated unit test Advantages? Disadvantages? Invokes the function on predetermined test input Checks that the function produced the expected result Displays a pass / fail message Advantages? Disadvantages? def roundIt(num: float) -> int: return int(num + .5) # ---- automated unit test ---- result = roundIt(9.7) if result == 10: print("Test 1: PASS") else: print("Test 1: FAIL") result = roundIt(8.2) if result == 8: print("Test 2: PASS") print("Test 2: FAIL")

Automated Unit Test with assert The assert statement Performs a comparison If the comparison is True, does nothing If the comparison is False, displays an error and stops the program assert statements help us write concise, automated unit tests Demo: Run the test def roundIt(num: float) -> int: return int(num + .5) # ---- automated unit test ---- result = roundIt(9.7) assert result == 10 result = roundIt(8.2) assert result == 8 print("All tests passed!")

A Shorter Test This is Nice. Two issues: To test the function, we have to copy it between the "real program" and this unit test Assertion failure messages could be more helpful To solve these, we'll use pytest, a unit test framework def roundIt(num: float) -> int: return int(num + .5) # ---- automated unit test ---- assert roundIt(9.7) == 10 assert roundIt(8.2) == 8 print("All tests passed!")

A pytest Unit Test To create a pytest Unit Test: Define a unit test function named test_something Place one or more assertions inside These tests can be located in the same file as the "real program," as long as you put the real program inside a special if statement, as shown To run a pytest Unit Test from command prompt: pytest program.py Note: pytest must first be installed using: pip install pytest def roundIt(num: float) -> int: return int(num + .5) def test_roundIt(): assert roundIt(9.7) == 10 assert roundIt(8.2) == 8 if __name__ == "__main__": # --- "real program" here ---

What's with this if statement? if __name__ == "__main__": # --- "real program" here --- This if condition above is true when the program is executed using the python command: python myprog.py The if condition is false when the program is executed using pytest pytest myprog.py We don't want pytest to execute the main program...

pytest Unit Tests A pytest Unit Test can have more than one test method It's good practice to have a separate test method for each type of test That way, when a test fails, you can debug the issue more easily def roundIt(num: float) -> int: return int(num + .5) # ---- automated unit test ---- def test_roundIt_rounds_up(): assert roundIt(9.7) == 10 def test_roundIt_rounds_down(): assert roundIt(8.2) == 8

Understanding pytest Test Failures A buggy roundIt function Diagnose pytest failure: ===== FAILURES ====== def test_roundIt_rounds_up(): > assert roundIt(9.7) == 10 E assert 9 == 10 E + where 9 = roundIt(9.7) def roundIt(num: float) -> int: return int(num + .1) def test_roundIt_rounds_up(): assert roundIt(9.7) == 10 Expected value Actual value

Designing Testable Functions Some functions can't be tested with an automated unit test. A testable function Gets input from parameters Returns a result Does no input / output # This function is not testable def roundIt(num: float) -> int: print(int(num + .5))

Design By Contract

Function Specifications In order to test a function, we must have a clear specification for it. The specification must state What parameter values are acceptable What the function produces

Design by Contract Design By Contract is an approach to specifying function behavior in terms of preconditions and postconditions. Preconditions state restrictions on legal parameter values Postconditions state what the function promises to do if the preconditions are met The preconditions and postconditions form a contract between the function and its clients def sumNums(lo: int, hi: int) -> int: sum = 0 for i in range(lo, hi+1): sum += i return sum "I, function sumNums, promise to compute the sum of the numbers [lo..hi] if you will give me integers lo <= hi."

Documenting Function Contract We use a triple-quoted string at the beginning of a function to document its contract. def sumNums(lo: int, hi: int) -> int: """Computes sum of sequence Preconditions: `lo` <= `hi` Postconditions: returns sum of numbers in range [`lo` .. `hi`] """ sum = 0 for i in range(lo, hi+1): sum += i return sum

Specification Based Testing The function contract helps us design the unit tests. Unit tests should respect preconditions. Unit tests should verify postconditions. Which of these are valid unit tests? assert sumNums(1, 3) == 6 assert sumNums(1, 1) == 1 assert sumNums(1, 0) == 0 assert sumNums(-2, -1) == -3 def sumNums(lo: int, hi: int) -> int: """Computes sum of sequence Preconditions: `lo` <= `hi` Postconditions: returns sum of numbers in range [`lo` .. `hi`] """ sum = 0 for i in range(lo, hi+1): sum += i return sum

Let's Practice Write the contract for getFirstWord def getFirstWord(text: str) -> str: """Extracts first word from `text` Preconditions: ________________ Postconditions: _________________ """ spaceLoc = text.find(' ') if spaceLoc == -1: return text else: return text[:spaceLoc]

Let's Practice Write assertions for a unit test for getFirstWord. def getFirstWord(text: str) -> str: """Extracts first word from `text` Preconditions: `text` contains one or more words separated by spaces Postconditions: returns first word in `text` """ spaceLoc = text.find(' ') if spaceLoc == -1: return text else: return text[:spaceLoc]

Test First Development

When Do We Write Tests? Traditionally, programmers worked like this: Write a function Write a unit test for the function One day, someone decided to try it the other way around: Write the function That's the simple version, anyway... Which way is better?

Test First Development Here's how it really works: Write the function interface and contract. Write a unit test. Run the test and watch it fail. Implement enough of the function to pass the unit test. Run the unit test. Debug until it passes. Repeat steps 2-4 until function is complete.

Let's Practice Begin by designing function interface and specification def addNums(num: str) -> int: """Adds up all digits in `num` Preconditions: ____________________ Postconditions: ____________________ """ …

Let's Practice Write a simple return statement for function body Write a test Run the test Implement the function def addNums(num: str) -> int: """Adds up all digits in `num` Preconditions: `num` contains only digits Postconditions: returns sum of digits in `num` """ return 0