Python programming Testing



Similar documents
Intro to scientific programming (with Python) Pietro Berkes, Brandeis University

Python Testing with unittest, nose, pytest

Testing Python. Applying Unit Testing, TDD, BDD and Acceptance Testing

Survey of Unit-Testing Frameworks. by John Szakmeister and Tim Woods

CIS 192: Lecture 13 Scientific Computing and Unit Testing

CME 193: Introduction to Scientific Python Lecture 8: Unit testing, more modules, wrap up

Test Driven Development in Python

Software Testing. Theory and Practicalities

Advanced Topics: Biopython

Profiling, debugging and testing with Python. Jonathan Bollback, Georg Rieckh and Jose Guzman

Practical Programming, 2nd Edition

Python programming Debugging

Software Testing with Python

Assignment 4 CPSC 217 L02 Purpose. Important Note. Data visualization

6.170 Tutorial 3 - Ruby Basics

CS 1133, LAB 2: FUNCTIONS AND TESTING

New Tools for Testing Web Applications with Python

Transaction Inquiries

B&K Precision 1785B, 1786B, 1787B, 1788 Power supply Python Library

Introduction to Python

Assignment 2: Option Pricing and the Black-Scholes formula The University of British Columbia Science One CS Instructor: Michael Gelbart

DevKey Documentation. Release 0.1. Colm O Connor

requests_toolbelt Documentation

Chart of Accounts (COA) Validation Service. 6/11/2012 University at California, Berkeley IS&T, Application Services

ACCESS Importing and Exporting Data Files. Information Technology. MS Access 2007 Users Guide. IT Training & Development (818)

Code::Blocks Student Manual

Team Members: Christopher Copper Philip Eittreim Jeremiah Jekich Andrew Reisdorph. Client: Brian Krzys

Python programming GUI

Introduction to Python

FEEG Applied Programming 5 - Tutorial Session

Exercise 0. Although Python(x,y) comes already with a great variety of scientic Python packages, we might have to install additional dependencies:

CRABpy Documentation. Release Flanders Heritage Agency

Python Testing Cookbook

Scientific Programming in Python

Automated Testing with Python

ECE 341 Coding Standard

Abstract. For notes detailing the changes in each release, see the MySQL for Excel Release Notes. For legal information, see the Legal Notices.

Microsoft Access Rollup Procedure for Microsoft Office Click on Blank Database and name it something appropriate.

Course Title: Microsoft Access Basic Duration: 12 hours

How To Use Databook On A Microsoft Powerbook (Robert Birt) On A Pc Or Macbook 2 (For Macbook)

1 Using CWEB with Microsoft Visual C++ CWEB INTRODUCTION 1

Quality Assurance Plan

Self-review 9.3 What is PyUnit? PyUnit is the unit testing framework that comes as standard issue with the Python system.

PRI-(BASIC2) Preliminary Reference Information Mod date 3. Jun. 2015

Writing robust scientific code with testing (and Python) Pietro Berkes, Enthought UK

MAS 500 Intelligence Tips and Tricks Booklet Vol. 1

We will learn the Python programming language. Why? Because it is easy to learn and many people write programs in Python so we can share.

Financial Econometrics MFE MATLAB Introduction. Kevin Sheppard University of Oxford

Python for Test Automation i. Python for Test Automation

Analytics Canvas Tutorial: Cleaning Website Referral Traffic Data. N m o d a l S o l u t i o n s I n c. A l l R i g h t s R e s e r v e d

Web development... the server side (of the force)

CS 2112 Spring Instructions. Assignment 3 Data Structures and Web Filtering. 0.1 Grading. 0.2 Partners. 0.3 Restrictions

Python for Scientific Computing.

Netigate User Guide. Setup Introduction Questions Text box Text area Radio buttons Radio buttons Weighted...

NAND Flash Memories. Using Linux MTD compatible mode. on ELNEC Universal Device Programmers. (Quick Guide)

Advanced Web Development SCOPE OF WEB DEVELOPMENT INDUSTRY

Python. Python. 1 Python. M.Ulvrova, L.Pouilloux (ENS LYON) Informatique L3 Automne / 25

Windows Installation Guide

How To Program In Scheme (Prolog)

Unit testing using Python nose

G563 Quantitative Paleontology. SQL databases. An introduction. Department of Geological Sciences Indiana University. (c) 2012, P.

CRASH COURSE PYTHON. Het begint met een idee

Building A Web Database Using Contextual Mode

Flask-SSO Documentation

Full VM Tutorial. i2b2 Desktop Installation (Windows) Informatics for Integrating Biology and the Bedside

Siemens Applied Automation Page 1 11/26/03 9:57 PM. Maxum ODBC 3.11

Orientation Course - Lab Manual

QA Tools (QTP, QC/ALM), Selenium with Java, Mobile with Automation, Unix, SQL, SOAP UI

Nintex Workflow 2013 & InfoPath Form Design workshop

Static vs. Dynamic. Lecture 10: Static Semantics Overview 1. Typical Semantic Errors: Java, C++ Typical Tasks of the Semantic Analyzer

Form And List. SuperUsers. Configuring Moderation & Feedback Management Setti. Troubleshooting: Feedback Doesn't Send

Introduction to Python

Programming Cocoa with Ruby Create Compelling Mac Apps Using RubyCocoa

Errors That Can Occur When You re Running a Report From Tigerpaw s SQL-based System (Version 9 and Above) Modified 10/2/2008

Differences in Use between Calc and Excel

monoseq Documentation

Example for Using the PrestaShop Web Service : CRUD

Java Access to Oracle CRM On Demand. By: Joerg Wallmueller Melbourne, Australia

Enable Your Automated Web App Testing by WebDriver. Yugang Fan Intel

App Inventor Tutorial 11 QR Code Reader

APPROACHES TO SOFTWARE TESTING PROGRAM VERIFICATION AND VALIDATION

ClubWise Campaign Manager Cheat Sheet COPYRIGHT ALL RIGHTS RESERVED. Page 1

Ansur Test Executive. Users Manual

A Pythonic Approach to Continuous Delivery

Computer Training Centre University College Cork. Excel 2013 Pivot Tables

SpiraTest / SpiraTeam Automated Unit Testing Integration & User Guide Inflectra Corporation

Installing and Sending with DocuSign for NetSuite v2.2

Coding Rules. Encoding the type of a function into the name (so-called Hungarian notation) is forbidden - it only confuses the programmer.

National Fire Incident Reporting System (NFIRS 5.0) Configuration Tool User's Guide

Rapid Application Development with GNOME and Python

Excel Pivot Tables. Blue Pecan Computer Training Ltd - Onsite Training Provider :: :: info@bluepecan.co.

Agile Development and Testing in Python

Microsoft Expression Web Quickstart Guide

Multiprocess System for Virtual Instruments in Python

Web Development using PHP (WD_PHP) Duration 1.5 months

Transcription:

Python programming Testing Finn Årup Nielsen DTU Compute Technical University of Denmark September 8, 2014

Overview Testing frameworks: unittest, nose, py.test, doctest Coverage Testing of numerical computations GUI testing Web testing Test-driven development Finn Årup Nielsen 1 September 8, 2014

Testing frameworks unittest: In the Python Standard Library, xunit-style standard. nose: Not in the stdlib. Simpler tests than unittest py.test: Not in the Python Standard Library. Simpler tests than unittest. Better error messages than nose doctest: In the Python Standard Library. Test specified in the documentation (i.e., in the docstring). Show to the user how to use the class and function Finn Årup Nielsen 2 September 8, 2014

Testing with nose Using nose with mymodule.py containing def myfunction(x, y=2): return x+y def test_myfunction(): assert myfunction(1) == 3 assert myfunction(1,3) == 4 Run the program nosetests (Campbell et al., 2009, p. 61 67) $ nosetests mymodule.py that discovers the test functions. Or within Python: >>> import nose, mymodule >>> nose.run(mymodule) Finn Årup Nielsen 3 September 8, 2014

doctest = documentation + testing... mymodule.py with myfunction with Python code in the docstring: def myfunction(x, y=2): """ This function will add two numbers, e.g., >>> myfunction(1,7) 8 The second argument is optional >>> myfunction(2) 4 """ return x+y if name == " main ": import doctest doctest.testmod() Finn Årup Nielsen 4 September 8, 2014

... doctest $ python mymodule.py The body of the following conditional gets executed if the function is called as the main program ( main ), rather than imported as a module: if name == " main ": import doctest doctest.testmod() doctest.testmod() will extract the code and the execution result from the docstrings (indicated with >>>), execute the extracted code and compare its result to the extracted result: Literal testing! This scheme also works for errors and their messages. Finn Årup Nielsen 5 September 8, 2014

Autodiscovery Testing frameworks may have autodiscovery of testing functions. are found with the test_ prefix. This (Some have used test in function_name instead, see, e.g., (Martelli et al., 2005, section 8.8, Running Unit Tests Most Simply ), but this format is apparently not recognized by nose and py.test) Where to put the test? In the module with the implementation or in a separate module. There are conventions for the placement of testing code. Finn Årup Nielsen 6 September 8, 2014

Coverage Coverage = How much of the code has been executed When testing: Coverage = How much of the code has be tested There is a Python program for python code: coverage.py! Example with a module Etter2011Novo_nbc.py containing test_ functions and nose.runmodule(): $ python-coverage run Etter2011Novo_nbc.py $ python-coverage report egrep "(Etter Name)" Name Stmts Miss Cover Etter2011Novo_nbc 105 5 95% Conclussion: Much but not all code tested here. Finn Årup Nielsen 7 September 8, 2014

... Coverage Consider numerics.py file: def compute(x): """Add two to x.""" if x == 2: return 5 return x + 2 def test_compute(): assert compute(1) == 3 assert compute(-10.) == -8. test_compute() Then everything is ok ( collected 1 items ) with: $ py.test numerics.py Finn Årup Nielsen 8 September 8, 2014

... Coverage $ python-coverage run numerics.py $ python-coverage report grep numerics numerics 8 1 88% We haven t tested all the code! We haven t testing the conditional for x = 2. Finn Årup Nielsen 9 September 8, 2014

... Coverage Lets add a new test to handle the conditional reaching 100% coverage in the test. Finn Årup Nielsen 10 September 8, 2014

... Coverage def compute(x): """Add two to x, except for 2.""" if x == 2: return 5 return x + 2 def test_divide(): assert compute(1) == 3 assert compute(-10.) == -8. assert compute(2) == 5 # new test! test_divide() $ python-coverage run numerics.py $ python-coverage report grep numerics numerics 9 0 100% Finn Årup Nielsen 11 September 8, 2014

Testing of numerical code Consider a module numerics.py with: def compute(): return 1-1./3 def test_compute(): assert compute() == 2./3 Using py.test: $ py.test numerics.py Results in an error(!?): def test_compute(): > assert compute() == 2./3 E assert 0.6666666666666667 == (2.0 / 3) E + where 0.6666666666666667 = compute() Finn Årup Nielsen 12 September 8, 2014

Testing of numerical code The problem is numerical runoff: 0.6666666666666667 0.6666666666666666 New attempt: def compute(): return 1-1./3 def test_compute(): assert abs(compute() - 2./3) < 0.0000000000000002 The testing does not fail now! Finn Årup Nielsen 13 September 8, 2014

Testing of numerical code with Numpy Now with a Numpy 2D array (a 4-by-4 matrix): from numpy import * def compute(): return 1 - ones((4,4)) / 3 What now? Test all elements individually? def test_compute(): for row in compute(): for element in row: assert abs(element - 2./3) < 0.0000000000000002 Perhaps we should also test that the size is appropriate? Finn Årup Nielsen 14 September 8, 2014

Testing of numerical code with Numpy from numpy.testing import * def test_compute(): assert_allclose(compute(), 2 * ones((4,4)) / 3) assert allclose is just one of several functions in numpy.testing that can be used to numerical testing. Finn Årup Nielsen 15 September 8, 2014

Testing of numerical code with Numpy We can still make the test fail with: from numpy.testing import * def test_compute(): assert_equal(compute(), 2 * ones((4,4)) / 3) Here assert_equal rather than assert_close, and this is what we get:... > raise AssertionError(msg) E AssertionError: E Arrays are not equal E E (mismatch 100.0%) E x: array([[ 0.66666667, 0.66666667,... E [ 0.66666667, 0.66666667, 0.6...... Finn Årup Nielsen 16 September 8, 2014

Zero-one-some testing... Zero-one-some testing: If an instance (e.g., an input argument) can have multiple values then test with zero, one and multiple values. Here a test mean.py module: from numpy import mean, isnan def test_mean(): """Test the numpy.mean function.""" assert isnan(mean([])) assert mean([5]) == 5 assert mean([1, 0, 5, 4]) == 2.5 Fairly innocuous testing here. Mean of an empty list should/could be not-a-number. Mean of 5 should be 5 and mean of 1, 0, 5, 4 should be 2.5. Finn Årup Nielsen 17 September 8, 2014

... Zero-one-some testing Running the test. Oops: $ python >>> from test_mean import * >>> test_mean() /usr/local/lib/python2.7/dist-packages/numpy/core/_methods.py:57: RuntimeWarning: invalid value encountered in double_scalars ret = ret / float(rcount) >>> test_mean() >>> import numpy >>> numpy. version 1.7.1 mean([]) raise a warning (exceptions.runtimewarning) the first time you call it in Numpy 1.7 but not the second time!? numpy.nan is returned alright in both cases. Finn Årup Nielsen 18 September 8, 2014

Test for different types... from numpy import max, min def mean_diff(a): """Compute mean of difference between consequetive numbers. Parameters ---------- a : array_like """ return float((max(a) - min(a)) / (len(a) - 1)) def test_mean_diff(): assert mean_diff([1., 7., 3., 2., 5.]) == 1.5 assert mean_diff([7, 3, 2, 1, 5]) == 1.5 Finn Årup Nielsen 19 September 8, 2014

... Test for different types In this example there is a integer division problem (if we are in Python 2): Runing py.test on the module gives: def test_mean_diff(): assert mean_diff([1., 7., 3., 2., 5.]) == 1.5 > assert mean_diff([7, 3, 2, 1, 5]) == 1.5 E assert 1.0 == 1.5 E + where 1.0 = mean_diff([7, 3, 2, 1, 5]) typetesting.py:14: AssertionError Note there are problem when a is of length zero and one. Finn Årup Nielsen 20 September 8, 2014

GUI testing See, e.g., Unit Testing with wxpython, where the test function sets up the wx frame but never calls the mainloop instead making a direct call to the callback method associated with a button. Finn Årup Nielsen 21 September 8, 2014

Web testing Selenium documentation Modified from Getting started, testing one of my webservices: from selenium import webdriver from selenium.webdriver.common.keys import Keys driver = webdriver.firefox() driver.get("http://neuro.compute.dtu.dk/cgi-bin/brede_bib_pmid2bwpaper") assert "Brede" in driver.title elem = driver.find_element_by_name("pmid") # Find the pmid form field elem.clear() elem.send_keys("16154272") # Query to the webscript elem.send_keys(keys.return) # An author by the name of Tadafumi should be somewhere in the text assert driver.page_source.find("tadafumi")!= -1 Finn Årup Nielsen 22 September 8, 2014

httpbin http://httpbin.org/ is a web service for testing an HTTP library: >>> import requests >>> user_agent = "fnielsenbot 0.1, http://www.compute.dtu.dk/~faan/" >>> url = "http://httpbin.org/user-agent" >>> requests.get(url, headers={"useragent": user_agent}).json() {u user-agent : u python-requests/1.2.3 CPython/2.7.3 Linux/... # Ups, wrong header. # Trying with another: >>> requests.get(url, headers={"user-agent": user_agent}).json() {u user-agent : u fnielsenbot 0.1, http://www.compute.dtu.dk/~faan/ } Finn Årup Nielsen 23 September 8, 2014

Checking code style and quality Style checking in not testing per se but may help you catch errors and help you write beautiful code. Example: $ pylint a_python_module.py This use of pylint may result in: ************* Module a_python_module W: 14: Unnecessary semicolon C: 1: Missing docstring W: 5:formatresult: Redefining name res from outer scope (line 14) C: 14: Invalid name "res" (should match (([A-Z_][A-Z0-9_]*) (.* ))$) W: 17: No exception type(s) specified C: 16: More than one statement on a single line C: 17: More than one statement on a single line W: 3: Unused import math Finn Årup Nielsen 24 September 8, 2014

... Checking code style and quality There are other tools for style checking: pep8. Example: $ pep8 a_python_module.py a_python_module.py:3:12: E401 multiple imports on one line a_python_module.py:3:35: E262 inline comment should start with # a_python_module.py:5:1: E302 expected 2 blank lines, found 1 a_python_module.py:11:53: W291 trailing whitespace a_python_module.py:14:12: E702 multiple statements on one line (semicolon) a_python_module.py:16:12: E701 multiple statements on one line (colon) The tools are checking against Style Guide for Python Code, so-called PEP-8 Finn Årup Nielsen 25 September 8, 2014

Test-driven development 1. Write a small test for a basic functionality 2. Implement that functionality and no more 3. Run all tests 4. Write a small test that add an extra small functionality 5. Implement that functionality and no more 6. Run all tests 7. etc.... Finn Årup Nielsen 26 September 8, 2014

More information Style checking: A Beginner s Guide to Code Standards in Python - Pylint Tutorial Dive Into Python, Chapter 13. Unit Testing. This covers only the unittest module. Finn Årup Nielsen 27 September 8, 2014

Summary Test your code! Try using test-driven development. py.test might be an ok framework. Nose also good. Check your coverage. Ask why it is not 100%. If variables with multiple values should be tested: Zero-one-some testing Test for different variable types, e.g., it should work for both integers and floats. It does not harm to use doctest, but it is probably difficult to test all you code with doctest, so use py.test & co. Numpy has a separate testing framework. Good for Numpy computations. Finn Årup Nielsen 28 September 8, 2014

References References Campbell, J., Gries, P., Montojo, J., and Wilson, G. (2009). Practical Programming: An Introduction to Computer Science Using Python. The Pragmatic Bookshelf, Raleigh. Martelli, A., Ravenscroft, A. M., and Ascher, D., editors (2005). Python Cookbook. O Reilly, Sebastopol, California, 2nd edition. Finn Årup Nielsen 29 September 8, 2014