![Page 1: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/1.jpg)
Pruebas en
Conceptos básicos y ejemplos
![Page 2: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/2.jpg)
![Page 3: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/3.jpg)
![Page 4: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/4.jpg)
Unit testing will make you more attractive to the opposite sex. Martin Aspeli
![Page 5: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/5.jpg)
pruebas unitarias
pruebas de integración
pruebas funcionales
pruebas de sistema
![Page 6: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/6.jpg)
![Page 7: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/7.jpg)
![Page 8: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/8.jpg)
base.pyfrom Testing import ZopeTestCase
ZopeTestCase.installProduct('My Product')
from Products.PloneTestCase.PloneTestCase import PloneTestCasefrom Products.PloneTestCase.PloneTestCase import FunctionalTestCasefrom Products.PloneTestCase.PloneTestCase import setupPloneSite
setupPloneSite(products=['My Product'])
class MyProductTestCase(PloneTestCase): """We use this base class for all the tests in this package. If necessary, we can put common utility or setup code in here. This applies to unit test cases. """
class MyProductFunctionalTestCase(FunctionalTestCase): """We use this class for functional integration tests that use doctest syntax. Again, we can put basic common utility or setup code in here. """
![Page 9: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/9.jpg)
my_test.pyimport os, sys
if __name__ == '__main__': execfile(os.path.join(sys.path[0], 'framework.py'))
from base import MyProductTestCase
class TestClass(MyProductTestCase): """Tests for this and that...""" ...
def test_suite(): from unittest import TestSuite, makeSuite suite = TestSuite() ... suite.addTest(makeSuite(TestClass)) ... return suite
if __name__ == '__main__': framework()
![Page 10: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/10.jpg)
Instalación de skins y recursosclass TestInstallation(MyProductTestCase): """Ensure product is properly installed"""
def afterSetUp(self): ... self.skins = self.portal.portal_skins self.csstool = self.portal.portal_css self.jstool = self.portal.portal_javascripts ...
def testSkinLayersInstalled(self): """Verifies the skin layer was registered""" self.failUnless('my_product_skin' in self.skins.objectIds())
def testCssInstalled(self): """Verifies the associated CSS file was registered""" stylesheetids = self.csstool.getResourceIds() self.failUnless('my_css_id' in stylesheetids)
def testJavascriptsInstalled(self): """Verifies the associated JavaScript file was registered""" javascriptids = self.jstool.getResourceIds() self.failUnless('my_js_id' in javascriptids)
![Page 11: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/11.jpg)
Instalación de tipos de contenido
class TestInstallation(MyProductTestCase): """Ensure product is properly installed"""
def afterSetUp(self): ... self.types = self.portal.portal_types self.factory = self.portal.portal_factory ...
def testTypesInstalled(self): """Verifies the content type was installed""" self.failUnless('My Type' in self.types.objectIds())
def testPortalFactorySetup(self): """Verifies the content type was registered in the portal factory. The portal factory ensures that new objects are created in a well-behaved fashion. """ self.failUnless('My Type' in self.factory.getFactoryTypes())
![Page 12: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/12.jpg)
Instalación de tools y configletsclass TestInstallation(MyProductTestCase): """Ensure product is properly installed"""
def afterSetUp(self): ... self.config = self.portal.portal_controlpanel ...
def testToolInstalled(self): """Verifies a tool was installed""" self.failUnless(getattr(self.portal, 'my_tool', None) is not None)
def testConfigletInstalled(self): """Verifies a configlet was installed""" configlets = list(self.config.listActions()) self.failUnless('my_configlet_id' in configlets)
![Page 13: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/13.jpg)
Verificando recursos de Kupuclass TestInstallation(MyProductTestCase): """Ensure product is properly installed"""
def afterSetUp(self): ... self.kupu = self.portal.kupu_library_tool ...
def testKupuResourcesSetup(self): """Verifies the content type can be linked inside Kupu""" linkable = self.kupu.getPortalTypesForResourceType('linkable') self.failUnless('My Type' in linkable)
![Page 14: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/14.jpg)
Verificando otras propiedadesclass TestInstallation(MyProductTestCase): """Ensure product is properly installed"""
def afterSetUp(self): ... self.props = self.portal.portal_properties ...
def testDefaultPageTypes(self): """Verifies the content type can be used as the default page in a container object like a folder. """ self.failUnless('My Type' in \ self.props.site_properties.getProperty('default_page_types'))
![Page 15: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/15.jpg)
Desinstalación del productoclass TestUninstall(MyProductTestCase): """Ensure product is properly uninstalled"""
def afterSetUp(self): ... self.qitool = self.portal.portal_quickinstaller self.qitool.uninstallProducts(products=['My Product']) ...
def testProductUninstalled(self): """Verifies the product was uninstalled""" self.failIf(self.qitool.isProductInstalled('My Product'))
![Page 16: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/16.jpg)
Implementaciónfrom Interface.Verify import verifyObjectfrom Products.ATContentTypes.interface import IATContentTypefrom Products.MyProduct.interfaces import IMyProduct
class TestContentType(MyProductTestCase): """Ensure content type implementation"""
def afterSetUp(self): self.folder.invokeFactory('My Type', 'mytype1') self.mytype1 = getattr(self.folder, 'mytype1')
def testImplementsATContentType(self): """Verifies the object implements the base Archetypes interface""" iface = IATContentType self.failUnless(iface.providedBy(self.mytype1)) self.failUnless(verifyObject(iface, self.mytype1))
def testImplementsMyType(self): """Verifies the object implements the content type interface""" iface = IMyType self.failUnless(iface.providedBy(self.mytype1)) self.failUnless(verifyObject(iface, self.mytype1))
![Page 17: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/17.jpg)
Creación y edición de contenidoclass TestContentCreation(MyProductTestCase): """Ensure content type can be created and edited"""
def afterSetUp(self): self.folder.invokeFactory('My Type', 'mytype1') self.mytype1 = getattr(self.folder, 'mytype1')
def testCreateMyType(self): """Verifies the object has been created""" self.failUnless('mytype1' in self.folder.objectIds())
def testEditMyType(self): """Verifies the object can be properly edited""" self.mytype1.setTitle('A title') self.mytype1.setDescription('A description') ...
self.assertEqual(self.mytype1.Title(), 'A title') self.assertEqual(self.mytype1.Description(), 'A description') ...
![Page 18: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/18.jpg)
![Page 19: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/19.jpg)
![Page 20: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/20.jpg)
Es elegante y fácil de usar, pero no soporta JavaScript
Permite grabar las pruebas en formato zope.testbrowser o Selenium
![Page 21: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/21.jpg)
Selenium IDE
Selenium Remote Control
Selenium Grid
![Page 22: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/22.jpg)
Más información
• Unit testing frameworkhttp://www.python.org/doc/lib/module-unittest.html
• Test interactive Python exampleshttp://www.python.org/doc/lib/module-doctest.html
• Dive into Python de Mark Pilgrimhttp://diveintopython.org/unit_testing/
• Testing in Plone de Martin Aspelihttp://plone.org/documentation/tutorial/testing
• Selenium web application testing systemhttp://selenium.seleniumhq.org/
![Page 23: Pruebas en Plone: conceptos básicos y ejemplos](https://reader036.vdocuments.pub/reader036/viewer/2022081413/548c9d11b47959f60c8b62cc/html5/thumbnails/23.jpg)