Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lightweight unit testing in python

Tags:

python

racket

I'm considering using Python to teach introductory programming, and I'm looking for a lightweight unit testing framework. I've taken a look at unittest, and--as far as I can tell--it looks insanely non-lightweight.

For example, here's what I'd like to be able to write:

import unittest

def f(x):
  return x+2

checkEqual(f(3),5)

... and nothing else. To show you where I'm coming from, this is what I'd write in Racket's beginning student language:

(define (f x)
  (+ x 2))

(check-expect (f 3) 5)

... and that's it. Surely someone's written this tool, and I'm just not finding it?

(Apologies in advance for any appearance of flame-baiting. This is a serious question.)

SELF-EDIT:

Before anyone points this out: yes, I could write def checkEqual(a,b): print(a==b) ; I'm looking for something with a bit more: it should be able to check numbers with tolerances, it should have support for printing only failed test cases, it should be able to tell you how many test cases failed. Again, I'm confident that this code can be written; I'm just trying to avoid re-inventing the wheel.

like image 801
John Clements Avatar asked Dec 16 '22 00:12

John Clements


2 Answers

I would recommend Doctest.

Your example would look like:

def f(x):
    """
    >>> f(3)
    5
    """
    return x + 2

Why?:

  1. It's super simple: "when I run this thing I should get this answer back"
  2. It works on the function level - which might allow you to introduce testing even before classes
  3. Mirrors the interactive Python experience.
like image 175
RyanWilcox Avatar answered Jan 02 '23 01:01

RyanWilcox


Doctests are a wonderful suggestion, but if you want to get close to your example code I would suggest py.test (pytest.org). Your example would be written something like:

def f(x):
    return x+2

def test_equal():       # py.test looks for functions that start with test_
    assert f(3) == 5

if I put that in a file called tt.py and run it with py.test, it looks like this:

w:\tmp>py.test tt.py
============================= test session starts =============================
platform win32 -- Python 2.6.6 -- pytest-2.2.3
collected 1 items

tt.py .

========================== 1 passed in 0.01 seconds ===========================

if I change the assert to f(3) == 6, and run it again I get:

w:\tmp>py.test tt.py
============================= test session starts =============================
platform win32 -- Python 2.6.6 -- pytest-2.2.3
collected 1 items

tt.py F

================================== FAILURES ===================================
_________________________________ test_equal __________________________________

    def test_equal():       # py.test looks for functions that start with test_
>       assert f(3) == 6
E       assert 5 == 6
E        +  where 5 = f(3)

tt.py:5: AssertionError
========================== 1 failed in 0.01 seconds ===========================

py.test also scales up, and you can have it run coverage, distribute tests over multiple CPUs etc. It also finds and runs unittest test and can also run doctests.

like image 39
thebjorn Avatar answered Jan 02 '23 02:01

thebjorn