Significant updates are to the preamble (Python-Version field), the sections "Use new-style classes throughout", "Module attributes", and a new Rationale section "Removal of ``assert*`` names".
:PEP: XXX :Title: Consolidating names and classes in the `unittest` module :Version: 0.0 :Last-Modified: 2008-07-15 :Author: Ben Finney <[EMAIL PROTECTED]> :Status: Draft :Type: Standards Track :Content-Type: test/x-rst :Created: 2008-07-14 :Python-Version: 2.7, 3.1 :Post-History: .. contents:: Abstract ======== This PEP proposes to consolidate the names and classes that constitute the API of the standard library `unittest` module, with the goal of removing redundant names, conforming with PEP 8, and eliminating classic classes. Motivation ========== The normal use case for the `unittest` module is to subclass its classes, overriding and re-using its functios and methods. This draws constant attention to the fact that the existing implementation fails several current Python standards: * It does not use new-style classes, preventing e.g. straightforward use of ``super`` for calling the fixture set-up and tear-down methods. * It does not conform to PEP 8, requiring users to write their own non-PEP-8 conformant names when overriding methods, and encouraging extensions to further depart from PEP 8. * It has many synonyms in its API, which goes against the Zen of Python (specifically, that "there should be one, and preferably only one, obvious way to do it"). Specification ============= Use new-style classes throughout -------------------------------- The following classes are currently implemented as classic ("old-style") classes, with no metaclass. * ``TestResult`` * ``TestCase`` * ``TestSuite`` * ``TestLoader`` * ``_WritelnDecorator`` * ``TextTestRunner`` * ``TestProgram`` The `unittest` module will gain the following attribute, to set the default metaclass for classes in the module and thus make all classes in the module part of the new-style type hierarchy:: __metaclass__ = type Remove obsolete names --------------------- The following module attributes are not documented as part of the API and are marked as obsolete in the implementation. They will be removed. * ``_makeLoader`` * ``getTestCaseNames`` * ``makeSuite`` * ``findTestCases`` Remove redundant names ---------------------- The following attribute names exist only as synonyms for other names. They are to be removed, leaving only one name for each attribute in the API. ``TestCase`` attributes ~~~~~~~~~~~~~~~~~~~~~~~ * ``assertEqual`` * ``assertEquals`` * ``assertNotEqual`` * ``assertNotEquals`` * ``assertAlmostEqual`` * ``assertAlmostEquals`` * ``assertNotAlmostEqual`` * ``assertNotAlmostEquals`` * ``assertRaises`` * ``assert_`` * ``assertTrue`` * ``assertFalse`` Conform API with PEP 8 ---------------------- The following names are to be introduced, each replacing an existing name, to make all names in the module conform with PEP 8. Each name is shown with the existing name that it replaces. Where function parameters are to be renamed also, they are shown. Where function parameters are not to be renamed, they are elided with the ellipse ("…") symbol. Module attributes ~~~~~~~~~~~~~~~~~ ``default_test_loader`` Replaces ``defaultTestLoader`` ``TestResult`` attributes ~~~~~~~~~~~~~~~~~~~~~~~~~ ``add_error(…)`` Replaces ``addError(…)`` ``add_result(…)`` Replaces ``addResult(…)`` ``add_success(…)`` Replaces ``addSuccess(…)`` ``should_stop`` Replaces ``shouldStop`` ``start_test(…)`` Replaces ``startTest(…)`` ``stop_test(…)`` Replaces ``stopTest(…)`` ``tests_run`` Replaces ``testsRun`` ``was_successful(…)`` Replaces ``wasSuccessful(…)`` ``TestCase`` attributes ~~~~~~~~~~~~~~~~~~~~~~~ ``__init__(self, method_name='run_test')`` Replaces ``__init__(self, methodName='runTest')`` ``_test_method_doc`` Replaces ``_testMethodDoc`` ``_test_method_name`` Replaces ``_testMethodName`` ``failure_exception`` Replaces ``failureException`` ``count_test_cases(…)`` Replaces ``countTestCases(…)`` ``default_test_result(…)`` Replaces ``defaultTestResult(…)`` ``fail_if(…)`` Replaces ``failIf(…)`` ``fail_if_almost_equal(…)`` Replaces ``failIfAlmostEqual(…)`` ``fail_if_equal(…)`` Replaces ``failIfEqual(…)`` ``fail_unless(…)`` Replaces ``failUnless(…)`` ``fail_unless_almost_equal(…)`` Replaces ``failUnlessAlmostEqual(…)`` ``fail_unless_equal(…)`` Replaces ``failUnlessEqual(…)`` ``fail_unless_raises(exc_class, callable_obj, *args, **kwargs)`` Replaces ``failUnlessRaises(excClass, callableObj, *args, **kwargs)`` ``run_test(…)`` Replaces ``runTest(…)`` ``set_up(…)`` Replaces ``setUp(…)`` ``short_description(…)`` Replaces ``shortDescription(…)`` ``tear_down(…)`` Replaces ``tearDown(…)`` ``FunctionTestCase`` attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``__init__(self, test_func, set_up, tear_down, description)`` Replaces ``__init__(self, testFunc, setUp, tearDown, description)`` ``run_test(…)`` Replaces ``runTest(…)`` ``set_up(…)`` Replaces ``setUp(…)`` ``short_description(…)`` Replaces ``shortDescription(…)`` ``tear_down(…)`` Replaces ``tearDown(…)`` ``TestSuite`` attributes ~~~~~~~~~~~~~~~~~~~~~~~~ ``add_test(…)`` Replaces ``addTest(…)`` ``add_tests(…)`` Replaces ``addTests(…)`` ``count_test_cases(…)`` Replaces ``countTestCases(…)`` ``TestLoader`` attributes ~~~~~~~~~~~~~~~~~~~~~~~~~ ``sort_test_methods_using`` Replaces ``sortTestMethodsUsing`` ``suite_class`` Replaces ``suiteClass`` ``test_method_prefix`` Replaces ``testMethodPrefix`` ``get_test_case_names(self, test_case_class)`` Replaces ``getTestCaseNames(self, testCaseClass)`` ``load_tests_from_module(…)`` Replaces ``loadTestsFromModule(…)`` ``load_tests_from_name(…)`` Replaces ``loadTestsFromName(…)`` ``load_tests_from_names(…)`` Replaces ``loadTestsFromNames(…)`` ``load_tests_from_test_case(self, test_case_class)`` Replaces ``loadTestsFromTestCase(self, testCaseClass)`` ``_TextTestResult`` attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``show_all`` Replaces ``showAll`` ``add_error(…)`` Replaces ``addError(…)`` ``add_failure(…)`` Replaces ``addFailure(…)`` ``add_success(…)`` Replaces ``addSuccess(…)`` ``get_description(…)`` Replaces ``getDescription(…)`` ``print_error_list(…)`` Replaces ``printErrorList(…)`` ``print_errors(…)`` Replaces ``printErrors(…)`` ``start_test(…)`` Replaces ``startTest(…)`` ``TextTestRunner`` attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``_make_result(…)`` Replaces ``_makeResult(…)`` ``TestProgram`` attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~ ``__init__(self, module, default_test, argv, test_runner, test_loader)`` Replaces ``__init__(self, module, defaultTest, argv, testRunner, testLoader)`` ``create_tests(…)`` Replaces ``createTests(…)`` ``parse_args(…)`` Replaces ``parseArgs(…)`` ``run_tests(…)`` Replaces ``runTests(…)`` ``usage_exit(…)`` Replaces ``usageExit(…)`` Rationale ========= New-style classes ----------------- As a standard library module, `unittest` should not define any classic classes. Redundant names --------------- The current API, with two or in some cases three different names referencing exactly the same function, leads to an overbroad and redundant API that violates PEP 20 ("there should be one, and preferably only one, obvious way to do it"). Removal of ``assert*`` names ---------------------------- There is no overwhelming consensus on whether to remove the ``assert*`` names or the ``fail*`` names; both are in common use. This proposal argues the ``fail*`` names are slightly superior, for the following reasons: * Explicit is better than implicit: The ``fail*`` names state *what the function will do* explicitly: fail the test. With the ``assert*`` names, the action to be taken is only implicit. * Avoid false implication: The test methods do not have any necessary connection with the built-in ``assert`` statement. Even the exception raised, while it defaults to ``AssertionException``, is explicitly customisable via the documented ``failure_exception`` attribute. Choosing the ``fail*`` names avoids the false association with either of these. PEP 8 names ----------- Although `unittest` (and its predecessor `PyUnit`) are intended to be familiar to users of other xUnit interfaces, there is no attempt at direct API compatibility since the only code that Python's `unittest` interfaces with is other Python code. The module is in the standard library and its names should all conform with PEP 8. Backwards Compatibility ======================= The names to be obsoleted should be deprecated and removed according to the schedule for modules in PEP 4. While deprecated, use of the deprecated attributes should raise a ``DeprecationWarning``, with a message stating which replacement name should be used. Reference Implementation ======================== None yet. Copyright ========= This document is hereby placed in the public domain by its author. .. Local Variables: mode: rst coding: utf-8 End: vim: filetype=rst : _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com