Attached (assuming google groups accepts it) is my unit testing controller that i run on GAE development SDK.

also note that my db connection is defined as:

db = DAL('google:datastore')              # connect to Google BigTable
if request.test_db or request.function == "_TEST":
    db = DAL('google:datastore://app_test')    # set to test namespace

that allows me to run tests in a clean namespace in the GAE DB.


On 5/13/12 23:40 , Kimmo wrote:
I'd be interested in seeing this controller. Especially the part about
running the unittests.



On Wednesday, 9 May 2012 00:19:07 UTC+3, howesc wrote:

while i would not call anything i have great tests or a wonderful example
of testing, i have used doctests in controllers successfully.  those are
nice as the web2py environment is auto-setup for you.

i'm working on using the unittest module to test my modules - those don't
always need all the web2py stuff setup.

i'm running mainly on GAE and have modified the magic tests links from the
admin interface that run doctests and unittests to launch them from a
controller on my GAE dev environment.  i think i have posted that
controller before, but lemme know if you are interested in my re-posting it.

On Tuesday, May 8, 2012 2:12:13 AM UTC-7, Kimmo wrote:

I'm also trying to get unit tests working on web2py by following the
slices, but so far I've not been able to make them run properly. I'd like
to see some clear examples and maybe some real projects with unit tests on
web2py, to see how it's done in practice.


On Sunday, 6 May 2012 20:40:10 UTC+3, Rod Watkins wrote:

Hi everyone,

I am fairly new to web2py and python programming, but have had some
rather wonderful success in the month or so I've been learning it.

I am now preparing to start a real project and want to have unit tests
as I go.  I've read a bit (will be doing more) about python unit testing
(doctests, unittest, nose, coverage, selenium), but I want to get some
expert advise before I fully dive in, if I may. So a few questions:

1. Do you use unit tests?
2. What tools do you use (doctests, unittest, nose, coverage, selenium,
mocker, or others)?
3. Do you use any of the test runners from the community? (
http://packages.python.org/web2py_utils/test_runner.html,<http://packages.python.org/web2py_utils/test_runner.html>http://www.web2pyslices.com/slices/take_slice/142,<http://www.web2pyslices.com/slices/take_slice/142>http://web2py.com/AlterEgo/default/show/260)
Which, if any, would you suggest using?

I'm mainly looking for some guidance about how to proceed, what to study
and the best manner you've found to do unit tests.  For example, it is
worth doing anything more than doctests in controllers? If so, what beyond
them should I learn to use, etc.

Thanks everyone.
Rod


"""
This controller has methods to run the doctests in web2py.  app.yaml should
be configured so that only google app engine administrators have access to
these methods
"""
import sys

def die(msg):
    print >> sys.stderr, msg
    sys.exit(1)

@auth.requires_membership('admin-general')
def controllers():
    """
    a method to test doctests

    >>> #no doctests since that will ruin the tests
    >>> assert(True==True)
    """
    from gluon.fileutils import listdir
    from gluon.admin import apath
    app = request.application

    if len(request.args) > 0:
        file = request.args[0]
    else:
        file = '.*\.py'

    if request.vars.reset:
        #set to test namespace
        from google.appengine.api import namespace_manager
        namespace_manager.set_namespace('app_test')

        for table in db.tables:
            db(db[table].id>0).delete()
        create_test_data()
        

    controllers = listdir(apath('%s/controllers/' % app, r=request), file + '$')

    return dict(app=app, controllers=controllers)

@auth.requires_membership('admin-general')
def modules():
    """
    Run doctests in web2py environment. runs the tests in the modules

    >>> #no doctests since that will ruin the tests
    >>> assert(True==True)
    """
    from gluon.shell import parse_path_info, env
    import glob
    import types
    import sys
    import cStringIO
    import doctest
    import os
    
    verbose=request.vars.verbose or False

    testpath=request.application
    import_models=True

    #get a list of the modules to test
    cdir = os.path.join('applications', testpath, 'modules')
    if not os.path.isdir(cdir):
        die("modules is not a directory")
    files = glob.glob(os.path.join(cdir, '*.py'))

    #save stdout so we can capture data and reset it.
    stdout = sys.stdout
    html = ''
    
    for testfile in files:
        html += '<h2>Testing module "%s.py" ... done.</h2><br/>\n' % testfile

        globs = env(testpath, import_models)
        ignores = globs.keys()
        execfile(testfile, globs)

        def doctest_object(name, obj, html, new_env):
            """doctest obj and enclosed methods and classes."""

            if type(obj) in (types.FunctionType, types.TypeType,
                             types.ClassType, types.MethodType,
                             types.UnboundMethodType):

                # Reload environment before each test.
                globs = env(testpath, c='default', f='test_modules',
                            import_models=import_models,
                            extra_request={'env':new_env, 'test_db':True})
                execfile(testfile, globs)
                number_doctests = sum([len(ds.examples) for ds in doctest.DocTestFinder().find(obj)])
                if number_doctests>0:
                    sys.stdout = cStringIO.StringIO()
                    doctest.run_docstring_examples(obj, globs=globs,
                        name='%s: %s' % (os.path.basename(testfile),
                        name), verbose=verbose)
                    report = sys.stdout.getvalue().strip()
                    if report:
                        pf = 'failed'
                    else:
                        pf = 'passed'
                    html += '<h3 class="%s">Function %s [%s]</h3>\n' \
                            % (pf, name, pf)
                    if report:
                        html += CODE(report, language='web2py', \
                                     link='/examples/global/vars/').xml()
                    html += '<br/>\n'
                else:
                    html += \
                         '<h3 class="nodoctests">Function %s [no doctests]</h3><br/>\n' \
                         % (name)
                    
                
                #I don't think that the following is needed for modules.
                #if we find that tests are not being executed, maybe turn
                #this back on.
                if type(obj) in (types.TypeType, types.ClassType):
                    for attr_name in dir(obj):
                        # Execute . operator so decorators are executed.
                        try:
                            o = eval('%s.%s' % (name, attr_name), globs)
                        except:
                            #that method does not exist, skip over it.
                            pass
                        else:
                            doctest_object(attr_name, o, html, new_env)
            return html

        for (name, obj) in globs.items():
            if name not in ignores:                
                html = doctest_object(name, obj, html, Storage(globs))
    sys.stdout = stdout
    return dict(html=XML(html))            
    
def unittests():
    """
    run the unittests

    >>> #no doctests since that will ruin the tests
    >>> assert(True==True)
    """
    import os
    import sys
    import glob
    import cStringIO

    from gluon.shell import env

    #save stdout so we can capture data and reset it.
    stdout = sys.stdout
    stderr = sys.stderr

    #get a list of the modules to test
    cdir = os.path.join('applications', request.application, 'tests')
    if not os.path.isdir(cdir):
        die("applications/%s/tests is not a directory"%request.application)
    files = glob.glob(os.path.join(cdir, '*.py'))


    html = ''
    test_count = 0
    pass_count = 0
    fail_count = 0
    for testfile in files:
        test_count += 1
        html += '<h2>Running Test "%s.py" ... done.</h2><br/>\n' % testfile
        # Reload environment before each test.
        globs = env(request.application, c='default', f='index',
                    import_models=True, extra_request={'test_db':True})

        sys.stdout = cStringIO.StringIO()
        execfile(testfile, globs)
        report = sys.stdout.getvalue().strip()
        if report.find('FAIL') >= 0:
            fail_count += 1
            html += '<h3 class="failed">FAILED</h3>\n'
            html += CODE(report, language='web2py', \
                         link='/examples/global/vars/').xml()
        else:
            pass_count += 1
            html += '<h3 class="passed">PASSED</h3>\n'

                    
    sys.stdout = stdout

    return dict(html=XML(html),
                test_count = test_count,
                pass_count = pass_count,
                fail_count = fail_count)

Reply via email to