= Testing = "A bug is a test case you haven't written yet" [[BR]] "Unit Tests allow merciless [http://diveintopython.org/refactoring/refactoring.html refactoring]" This page defines what our current approach versus our [wiki:BluePrintTesting BluePrint for future options] Test-Driven Development is a programming styles which says that you 1st write your test cases (from the [BluePrints specs]) & then proceed to make them pass. Can pre-populate the database with random data using [http://groups.google.com/group/web2py/browse_thread/thread/4b2e5ed166220ba5# gluon.contrib.populate] * [wiki:InstallationGuidelinesDeveloperTesting] * TestCases - User Testing - List of things to test == Functional Tests == Building the Right Code We have integrated [http://seleniumhq.org/projects/core Selenium Core] into {{{/static/selenium}}} so that Functional Tests can be run (via 'Test' menu option visible to Admins). Additional functions (e.g. Random) are added to: {{{ /static/selenium/core/scripts/user-extensions.js }}} Check for unexpected global variables: * http://mankzblog.wordpress.com/2009/02/11/selenium-core-extension-for-finding-unexpected-global-variables/ !ToDo: create a {{{HandleResults.py}}} for storing results (to make visible to CI): * e.g. Convert this one from PHP: http://wiki.openqa.org/display/SEL/Integrating+Selenium+And+CruiseControl.Net * e.g. Extract from [http://jrandolph.com/selenium-plone/selenium-0.3rc2-plone.zip PloneTool]'s {{{FunctionalTestTool.py}}} Tests can be developed using [http://seleniumhq.org/projects/ide Selenium IDE], if desired. If desired they can be maintained in a Python format using [http://joker.linuxstuff.pl/documentation/make_selenium make_selenium.py]. HTML tests run by !TestRunner are in {{{/static/selenium/tests}}}. Python format tests are in {{{/static/selenium/src}}}. Convert between these using: {{{ python make_selenium.py src tests python make_selenium.py -p tests src }}} Hints on improving the stability of Selenium tests: * http://googletesting.blogspot.com/2009/06/my-selenium-tests-arent-stable.html Systers' approach: * http://systers.org/systers-dev/doku.php/automated_functional_testing Alternative Options: * http://zesty.ca/scrape/ * [http://pycon.blip.tv/file/3261277 Lightning Talk] (2.30) == Unit Tests == Building the Code Right [http://seleniumhq.org/projects/remote-control Selenium RC] is great due to ability to handle !JavaScript & also due to having an [http://seleniumhq.org/projects/ide IDE] for generating them (export as Python).[[BR]] The IDE output needs to be [http://groups.google.com/group/web2py/msg/d8c9fd6008029f6b modified] to work with Web2Py.[[BR]] NB Custom functions (e.g. for Random) cannot be shared with the Functional Tests (custom=JS) but the rest of the tests can be.[[BR]] These tests are stored in {{{/tests}}}.[[BR]] !ToDo: Port the storeRandom function from JS to Python: {{{ import random print "test_%i@xxxxxxxx" % random.randint(1, 10000) }}} !ToDo: Investigate how we can test multiple browsers. * [http://web2py.com/AlterEgo/default/show/260 AltereEgo entry] on testing in Web2Py * [http://stackoverflow.com/questions/2762294/unit-testing-in-web2py StackOverflow discussion] * [http://web2pyslices.com/main/slices/take_slice/67 Web2Py Slice] on Unit Testing [http://cherrypy.org CherryPy]'s [http://cherrypy.org/browser/trunk/cherrypy/test/webtest.py WebTest] is good for in-process testing & can be run from a browser-less server(easier for CI-integration).[[BR]] These tests are stored in {{{/tests/webtest}}}.[[BR]] NB These are a work-in-progress...need to enable access to Web2Py environment (db, etc) using: {{{ from gluon.shell import exec_environment env=exec_environment('the_model_file.py') }}} Or could write as a 'Controller' & call from CLI: {{{ python web2py.py -S appname -M -R yourscript.py }}} Another similar option could be [http://pylonshq.com/docs/en/0.9.7/thirdparty/webtest/ Pylon's WebTest] == Doc Tests == Agile documentation which can be run using Web2Py's Admin UI. * http://www.python.org/doc/2.6/library/doctest.html * e.g. http://127.0.0.1:8000/admin/default/test/sahana/default.py To extend these to web applications, we have a module which uses [http://code.google.com/p/wsgi-intercept wsgi_intercept] & [http://cherrypy.org CherryPy]'s [http://cherrypy.org/browser/trunk/cherrypy/test/webtest.py WebTest]: {{{modules/s3_test.py}}} [[BR]] This can be used from Controllers like: {{{ def login(): """ Login >>> from applications.sahana.modules.s3_test import WSGI_Test >>> test=WSGI_Test(db) >>> '200 OK' in test.getPage('/sahana/%s/login' % module) True >>> test.assertHeader("Content-Type", "text/html") >>> test.assertInBody('Login') """ }}} This works fine,although if an assert fails then the UI gets stuck :/ [[BR]] The 'db' access part isn't yet working. Note that Web2Py uses a big doctest at the end of each file: {{{def test_all()}}} == Continuous Integration == We are starting to use the Trac-integrated [http://bitten.edgewall.org Bitten] to monitor code quality. * Other options: http://stackoverflow.com/questions/225598/pretty-continuous-integration-for-python !ToDo: Write a step to parse/store the results of Selenium's {{{HandleResults.py}}} {{{ }}} !ToDo: Amend so that it can find the {{{gluon}}} module (or configure to not follow this dependency):[[BR]] {{{ImportError: Unable to find module for modules/validators.py in /tmp/bittenA787wC/build_Trunk_1}}}[[BR]] !ToDo: Fix Windows path (NB plain 'bzr' fails too, even if we're in the folder up from that): {{{F: 1: No module named /var/www/trac/sahana3/bzr}}} We need to write a {{{build/test-results.xml}}} for this one (& it also wants a {{{setup.py}}}?): {{{ }}} This one is pointless for us as we don't build anything using a {{{setup.py}}}: {{{ }}} ---- DeveloperGuidelines