Ho avuto l'occasione di provare il nuovo prodotto plone.app.testing e devo dire che sono rimasto positivamente impressionato. L'attenzione verso i test è sempre stata alta all'interno della comunità Plone ed anche questo strumento, che organizza e semplifica l'impostazione dei test, è all'altezza delle aspettative.
Cosa cambia con plone.app.testing?
La principale differenza, rispetto al precedente approccio ai test, è che plone.app.testing ci obbliga ad organizzare i nostri test secondo una serie di layer che si occupano di creare una serie di configurazioni ad hoc per i nostri test.
Ogni layer è quindi 'indipendente' dagli altri e deve contenere solamente le configurazioni necessarie per una specifica serie di test.
Sarà il sistema, durante l'esecuzione dei test, ad occuparsi dell'organizzazione e dell'ordinamento degli stessi in base ai layer. In questo modo i test appartenenti al medesimo layer vengono eseguiti insieme risparmiando tempo nella loro esecuzione.
All'interno di plone.app.testing sono già definiti alcuni layer preconfigurati che semplificano ulteriormente il lavoro: avremo quindi layer specifici per gli unittest, per i test di integrazione, fuzionali ecc.
Come districarsi nella foresta
Iniziamo dalla configurazione di una specifica sezione del buildout
...
[tests] recipe = zc.recipe.testrunner eggs = egg.da.testare [test]
...
In questo modo, grazie a zc.recipe.testrunner, abbiamo definito una specifica sezione ed incluso il nostro pacchetto tra gli egg da testare.
Specificando l'opzione [test] indichiamo inoltre che per il nostro pacchetto dovranno essere prese in considerazione delle specifiche dipendenze definite all'interno del nostro prodotto nel seguente modo:
# setup.py
...
extras_require = {
'test': [
'plone.app.testing',
...
]
},
...
ora possiamo creare il nostro primo layer che sarà basato su PLONE_FIXITURE, un layer predefinito in plone.app.testing:
from plone.app.testing import PloneSandboxLayer
from plone.app.testing import PLONE_FIXTURE
class MyLayer(PloneSandboxLayer):
defaultBases = (PLONE_FIXTURE, )
def setUpZope(self, app, configurationContext):
"""Qui configuro l'istanza Zope importando,
per esempio, le direttive zcml del mio prodotto
"""
import my.package
self.loadZCML(package=my.package)
def setUpPloneSite(self, portal):
"""Qui posso gestire alcune impostazioni di base di Plone.
Per esempio installo il prodotto da testare
"""
self.applyProfile(portal, 'my.package:default')
def tearDownZope(self, app):
"""Qui posso inserire tutto quello che dev'essere
eseguito alla fine del test
"""
a questo punto possiamo istanziare una serie di variabili per gestire test:
MYPACKAGE_FIXTURE = MyLayer()
from plone.app.testing import IntegrationTesting
MYPACKAGE_INTEGRATION_TESTING = IntegrationTesting(
bases=(MYPACKAGE_FIXTURE, ),
name="MyPackage:Integration")
from plone.app.testing import FunctionalTesting
MYPACKAGE_FUNCIONAL_TESTING = FunctionalTesting(
bases=(MYPACKAGE_FIXTURE, ),
name="MyPackage:Functional")
ed utilizzarle in un test:
import unittest
class MyIntegrationTestClass(unittest.TestCase):
layer = MYPACKAGE_INTEGRATION_TESTING
def test_dummy(self):
"""Un utile test!!"""
self.assertEquals(2+2, 4)
Considerazioni
Penso che questo strumento sia eccezionale per la realizzazione dei test in Plone e consente di migliorare il processo di definizione degli stessi.
Occorre però abituarsi ad alcune piccole cose dovute al meccanismo dei layer. I layer di default si occupano infatti di configurare lo stretto necessario e quindi dobbiamo essere noi stessi a definire al loro interno tutto quello di cui abbiamo bisogno.
Ecco alcune cose da ricordare:
- se abbiamo un prodotto Zope2 che utilizza il metodo initialize. Ovvero un classico prodotto per Archetypes dobbiamo ricordarci di installarlo manualmente all'interno del layer.
- il plugin zc.autoinclude non funziona all'interno dei layer quindi dobbiamo ricordarci di includere tutti i file zcml necessari
- portal adesso è impostato come chiave di self.layer in questo modo: self.layer['portal']
- per eseguire operazioni con un ruolo Plone particolare possiamo usare: plone.app.testing.setRoles
Altre informazioni
- Archive
- 2009 2010 2011