Capitolo 8. Programmazione orientata ai dati

8.1. Immergersi

Nel capitolo relativo al Test delle unità di codice, ne abbiamo discusso la filosofia e ne abbiamo vista l'implementazione in Python. Questo capitolo si dedicherà a tecniche specifiche di Python, più avanzate, basate sul modulo unittest. Se non avete letto il capitolo Test delle unità di codice, vi perderete a metà lettura. Siete stati avvertiti.

Quello che segue è un programma Python completo che si comporta come una semplice e grossolano infrastruttura di test di regressione. Prende i test per le unità che avete scritto per i singoli moduli, li riunisce tutti in un grande insieme di test e li esegue tutti insieme. Io uso questo script come parte del processo di creazione di questo libro; ho test di unità di codice per numerosi programmi di esempio (non solo il modulo roman.py contenuto nel capitolo Test delle unità di codice) e la prima cosa che i miei script per creare il libro fanno è di eseguire questo programma per assicurarsi che tutti gli esempi lavorino ancora. Se questo test di regressione fallisce, la creazione si blocca immediatamente. Non voglio rilasciare esempi non funzionanti più di quanto vogliate scaricarli e spremervi le meningi urlando contro il vostro monitor domandandovi perché non funzionano.

Esempio 8.1. regression.py

Se non lo avete ancora fatto, potete scaricare questo ed altri esempi usati in questo libro.

"""Regression testing framework

This module will search for scripts in the same directory named
XYZtest.py.  Each such script should be a test suite that tests a
module through PyUnit.  (As of Python 2.1, PyUnit is included in
the standard library as "unittest".)  This script will aggregate all
found test suites into one big test suite and run them all at once.
"""

import sys, os, re, unittest

def regressionTest():
    path = os.path.abspath(os.path.dirname(sys.argv[0]))   
    files = os.listdir(path)                               
    test = re.compile("test\.py$", re.IGNORECASE)          
    files = filter(test.search, files)                     
    filenameToModuleName = lambda f: os.path.splitext(f)[0]
    moduleNames = map(filenameToModuleName, files)         
    modules = map(__import__, moduleNames)                 
    load = unittest.defaultTestLoader.loadTestsFromModule  
    return unittest.TestSuite(map(load, modules))          

if __name__ == "__main__":
    unittest.main(defaultTest="regressionTest")

Questo script, se eseguito nella stessa directory degli altri script di esempio forniti con questo libro, troverà tutti i test di unità, chiamati modulotest.py, li eseguirà come un test singolo e li farà superare o fallire tutti assieme.

Esempio 8.2. Semplice output di regression.py

[f8dy@oliver py]$ python regression.py -v
help should fail with no object ... ok                             1
help should return known result for apihelper ... ok
help should honor collapse argument ... ok
help should honor spacing argument ... ok
buildConnectionString should fail with list input ... ok           2
buildConnectionString should fail with string input ... ok
buildConnectionString should fail with tuple input ... ok
buildConnectionString handles empty dictionary ... ok
buildConnectionString returns known result with known input ... ok
fromRoman should only accept uppercase input ... ok                3
toRoman should always return uppercase ... ok
fromRoman should fail with blank string ... ok
fromRoman should fail with malformed antecedents ... ok
fromRoman should fail with repeated pairs of numerals ... ok
fromRoman should fail with too many repeated numerals ... ok
fromRoman should give known result with known input ... ok
toRoman should give known result with known input ... ok
fromRoman(toRoman(n))==n for all n ... ok
toRoman should fail with non-integer input ... ok
toRoman should fail with negative input ... ok
toRoman should fail with large input ... ok
toRoman should fail with 0 input ... ok
kgp a ref test ... ok
kgp b ref test ... ok
kgp c ref test ... ok
kgp d ref test ... ok
kgp e ref test ... ok
kgp f ref test ... ok
kgp g ref test ... ok

----------------------------------------------------------------------
Ran 29 tests in 2.799s

OK
1 I primi cinque test sono contenuti in apihelpertest.py, che esegue i test sugli script di esempio provenienti dal capitolo La potenza dell'introspezione.
2 I cinque test successivi provengono da odbchelpertest.py, che esegue i test sugli script visti nel capitolo Conoscere Python.
3 I test rimanenti provengono da romantest.py e sono esaminati approfonditamente nel capitolo Test delle unità di codice.