RuPy'07

Agile documentation in Python projects

Author:Tarek Ziadé <tarek@ziade.org>
Date:$Date: 2007-02-21$
License:CC-By-SA 2 license

How am I ?

What are the goals of this presentation ?

The main goal is to understand how Agile documentation works in Python, through:

What are the goals of this presentation ?

My secret goal is to come to RuPy to see how Ruby works...

The plan

A few definitions

What kind of documentation are we talking about ?

A few definitions

Technical documentation that helps to understand how a codebase works and how it can be used. This can be:

[1](1, 2) Python folders and files

A few definitions

What Agile means ?

A few definitions

A lightweight process to stay reactive to frequent changes

[2]The website looks a bit like some sect site but it's a good sect

A few definitions

Agile principles can be applied to any repeating process:

The plan

Part 1

Doing TDD in Python

This part is composed of:

TDD Principles

TDD Principles

Example:

>>> def division(a, b):
...     return a / b

Let's test it !

>>> def test_division():
...     if division(4, 2) == 2:
...         return 'OK'
...     else:
...         return 'SHUT DOWN THE COMPUTER NOW !'
>>> test_division()
'OK'

TDD Principles

Each use case tests one aspect of the code

Let's try this one:

>>> def test_division2():
...     if division(4, 0) == 0:
...         return 'OK'
...     else:
...         return 'I WANT ZERO'
>>> test_division2()
Traceback (most recent call last):
...
ZeroDivisionError: integer division or modulo by zero

TDD Principles

The function fails, let's change it:

>>> def division(a, b):
...     if b == 0:
...         return 0
...     return a / b

and rerun the test:

>>> test_division2()
'OK'

TDD Principles

TDD Principles

Let's write the tests before the code:

>>> def test_average():
...     if average(1, 2, 3) == 2:
...         return 'OK'
...     else:
...         return 'Houston we have a problem'
>>> test_average()
Traceback (most recent call last):
...
NameError: global name 'average' is not defined

TDD Principles

Now let's code average:

>>> def average(*args):
...     return sum(args) / len(args)

And run the test again:

>>> test_average()
'OK'

TDD Principles

TDD brings:

TDD Principles

Jean-Charles says:

"Tests are a waste of time, just a toy for interpreted languages"

Bruce Eckel says:

"If it's not tested, it's broken"

Bruce's the one who's right:

Part 1

Doing TDD in Python

How to write tests in Python

Python is battery included. The standard library provides:

important There are many other test framework projects out there

How to write tests in Python

unittest provides helpers to write tests:

How to write tests in Python

TestCase provides two things:

How to write tests in Python

Writing a test case == deriving from TestCase:

>>> import unittest
>>> class DivisionTestCase(unittest.TestCase):
...
...     def test_one(self):
...         self.assertEquals(division(4, 2) , 2)
...
...     def test_two(self):
...         self.assert_(division(4, 0) == 0)
...

Each test is a method with a test prefix.

How to write tests in Python

The test can be:

How to write tests in Python

Example of test module:

import unittest
from division import division

class DivisionTestCase(unittest.TestCase):

     def test_one(self):
         self.assertEquals(division(4, 2) , 2)

     def test_two(self):
         self.assert_(division(4, 0) == 0)

def test_suite():
    suite = unittest.TestSuite()
    suite.addTests(unittest.makeSuite(DivisionTestCase))
    return suite

if __name__ == '__main__':
    unittest.main(defaultTest='test_suite')

How to write tests in Python

Running the tests with the Python interpreter:

dabox:~ tarek$ python test_division.py
..
------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

How to write tests in Python

Running the tests with the Python interpreter, with a failure:

dabox:~ tarek$ python test_division.py
F.
==================================================================
FAIL: test_one (__main__.DivisionTestCase)
------------------------------------------------------------------
Traceback (most recent call last):
File "test_division.py", line 7, in test_one
self.assertEquals(division(4, 2) , 3)
AssertionError: 2 != 3

------------------------------------------------------------------
Ran 2 tests in 0.000s

FAILED (failures=1)

How to write tests in Python

"TDD with Python rocks" -- Magnum

"Doing TDD with Python is so cool !" -- Magnum

Part 1

Doing TDD in Python

How to organise tests in a Python project

By the way, how Python code is organized ?

Each package comes with

Following the TDD principles:

How to organise tests in a Python project

Our division package will look like this:

division
   |
   |-- division.py
   |
   |-- tests
   |     |
   |     |-- test_division.py
   |
   |--  doc
         |
         |-- division.txt <-- some cool doc

Part 1

Doing TDD in Python

Part 1

Mettre une photo de matrix

"I now TDD in Python now" -- Neo, The Matrix

The plan

Part 2

Writing documents in reST

What is reST ?

reSTructuredText (say reSt to be hype) is:

What is reST ?

Example:

==================
I am the reST file
==================

I am the first section
======================

I am the content of the first section.
I have things to say.

I am the second section
=======================

I am, what I am, what I aammmm...

What is reST ?

Several remarks:

Part 2

Writing documents in reST

reST syntax overview

XXX

Part 2

Writing documents in reST

reST tools

XXX

Part 2

Writing documents in reST

reST can be:

Python developers love reST

The plan