view MoinMoin/ @ 4027:0d6724b87856

Refactored TestConfig creation for py.test based unit tests. The method used before had multiple problems: config creation did not use inheritance (as it does when used the wiki in production). It also didn't do the post processing done in __init__ of Config class. Also, it first created the request with some default config, then created the TestConfig (but some stuff in request was not initialized correctly)... The new method now uses config inheritance in the same way as a production wiki does. The TestConfig instance is created in RequestBase __init__, it does not use sys.path any more to import the test wikiconfig, but does an absolute import from MoinMoin._tests.wikiconfig. TODO: * fix the failing test_pysupport.TestImportExisting.testExisting * auth tests are currently skipped because they need more work * find a better way than staticmethod(TestConfig)
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sun, 24 Aug 2008 02:01:34 +0200
parents a86a245db9cb
children 5c78ac77c98f
line wrap: on
line source
# -*- coding: iso-8859-1 -*-
MoinMoin Testing Framework

All test modules must be named test_modulename to be included in the
test suite. If you are testing a package, name the test module

Tests that need the current request, for example to create a page
instance, can refer to self.request. It is injected into all test case
classes by the framework.

Tests that require a certain configuration, like section_numbers = 1, must
use a TestConfig to create the required configuration before the test.
Deleting the TestConfig instance will restore the previous configuration.

@copyright: 2005 Nir Soffer, 2007 Alexander Schremmer
@license: GNU GPL, see COPYING for details.

import atexit
from sys import modules
import sys

import py

rootdir = py.magic.autopath().dirpath()
moindir = rootdir.join("..")

sys.path.insert(0, str(moindir))
from MoinMoin._tests import maketestwiki, compat, wikiconfig
modules["unittest"] = compat # evil hack

from import set

coverage_modules = set()

    This code adds support for (see
    It prints a coverage report for the modules specified in all
    module globals (of the test modules) named "coverage_modules".

    import coverage

    def report_coverage():
        module_list = [modules[mod] for mod in coverage_modules]

    def callback(option, opt_str, value, parser):

    py.test.config.addoptions('MoinMoin options', py.test.config.Option('-C',
        '--coverage', action='callback', callback=callback,
        help='Output information about code coverage (slow!)'))

except ImportError:
    coverage = None

def init_test_request(given_config=None, static_state=[False]):
    from MoinMoin.request import request_cli
    from MoinMoin.user import User
    from MoinMoin.formatter.text_html import Formatter as HtmlFormatter
    if not static_state[0]:
        static_state[0] = True
    request = request_cli.Request(given_config=given_config)
    request.form = request.args = request.setup_args()
    request.user = User(request)
    request.html_formatter = HtmlFormatter(request)
    request.formatter = request.html_formatter
    return request

# py.test customization starts here

class MoinTestFunction(py.test.collect.Function):
    def execute(self, target, *args):
        request = self.parent.request
        co = target.func_code
        if 'request' in co.co_varnames[:co.co_argcount]:
            target(request, *args)

class MoinClassCollector(py.test.collect.Class):
    Function = MoinTestFunction

    def setup(self):
        cls = self.obj
        if hasattr(cls, 'TestConfig'):
            cls.request = init_test_request(given_config=cls.TestConfig)
            cls.request = self.parent.request
        super(MoinClassCollector, self).setup()

class Module(py.test.collect.Module):
    Class = MoinClassCollector
    Function = MoinTestFunction

    def __init__(self, *args, **kwargs):
        self.request = init_test_request(given_config=wikiconfig.Config)
        super(Module, self).__init__(*args, **kwargs)

    def run(self, *args, **kwargs):
        if coverage is not None:
            coverage_modules.update(getattr(self.obj, 'coverage_modules', []))
        return super(Module, self).run(*args, **kwargs)