diff --git a/product/ERP5OOo/tests/testOOoImport.py b/product/ERP5OOo/tests/testOOoImport.py
index 8d6d0993e0a217430c697e7effa1b0e2831a0691..21a7a71fd601bb351876bff89bf2aeed6ba7adf8 100644
--- a/product/ERP5OOo/tests/testOOoImport.py
+++ b/product/ERP5OOo/tests/testOOoImport.py
@@ -30,18 +30,14 @@
 import unittest
 import os
 
-from Testing import ZopeTestCase
 from AccessControl.SecurityManagement import newSecurityManager
 from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
-from Products.ERP5Type.tests.ERP5TypeTestCase import install_product_quiet
 from Products.ERP5Type.tests.ERP5TypeTestCase import _getConversionServerDict
 from Products.ERP5Type.tests.Sequence import SequenceList
 from Products.ERP5OOo.OOoUtils import OOoParser
 from Products.ERP5Form.PreferenceTool import Priority
 from DateTime import DateTime
 
-ZopeTestCase.installProduct('Sessions', quiet=install_product_quiet)
-
 class FileUploadTest(file):
 
   __allow_access_to_unprotected_subobjects__=1
diff --git a/product/ERP5Type/patches/noZopeHelp.py b/product/ERP5Type/patches/noZopeHelp.py
new file mode 100644
index 0000000000000000000000000000000000000000..0d558c1c321b325ad8c3667cf076709072ef40d8
--- /dev/null
+++ b/product/ERP5Type/patches/noZopeHelp.py
@@ -0,0 +1,25 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Foundation and Contributors.
+# Copyright (c) 2013 Nexedi SARL and Contributors. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+# copied & pasted from Testing.ZopeTestCase.ZopeLite
+import App.ProductContext
+
+if 1:
+    # Avoid expensive help registration
+    def null_register_topic(self,id,topic): pass
+    App.ProductContext.ProductContext.registerHelpTopic = null_register_topic
+    def null_register_title(self,title): pass
+    App.ProductContext.ProductContext.registerHelpTitle = null_register_title
+    def null_register_help(self,directory='',clear=1,title_re=None): pass
+    App.ProductContext.ProductContext.registerHelp = null_register_help
diff --git a/product/ERP5Type/tests/ERP5TypeTestCase.py b/product/ERP5Type/tests/ERP5TypeTestCase.py
index 4f3b214af309eecf78f6b4234f2f1ec53e36a4dd..6484fd9b96317e00fb3f886db02b72c0129750b3 100644
--- a/product/ERP5Type/tests/ERP5TypeTestCase.py
+++ b/product/ERP5Type/tests/ERP5TypeTestCase.py
@@ -65,8 +65,6 @@ from zLOG import LOG, DEBUG
 from Products.ERP5Type.tests.backportUnittest import SetupSiteError
 from Products.ERP5Type.tests.utils import DummyMailHostMixin, parseListeningAddress
 
-# Quiet messages when installing products
-install_product_quiet = 1
 # Quiet messages when installing business templates
 install_bt5_quiet = 0
 
@@ -79,37 +77,11 @@ if getattr(config, 'product_config', None) is None:
   config.product_config = {}
 config.product_config['deadlockdebugger'] = {'dump_url':'/manage_debug_threads'}
 
-import OFS.Application
-OFS.Application.import_products()
-
-# Std Zope Products
-ZopeTestCase.installProduct('Photo', quiet=install_product_quiet)
-ZopeTestCase.installProduct('Formulator', quiet=install_product_quiet)
-ZopeTestCase.installProduct('FCKeditor', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ZSQLMethods', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ZMySQLDA', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ZSQLCatalog', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ZMailIn', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ZGDChart', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ZCTextIndex', quiet=install_product_quiet)
-ZopeTestCase.installProduct('MailHost', quiet=install_product_quiet)
-ZopeTestCase.installProduct('PageTemplates', quiet=install_product_quiet)
-ZopeTestCase.installProduct('PythonScripts', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ExternalMethod', quiet=install_product_quiet)
-ZopeTestCase.installProduct('Sessions', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ZODBMountPoint', quiet=install_product_quiet)
-
 from Testing.ZopeTestCase.layer import onsetup
-# installProduct() is a delayed call, so imports that depend on products being
-# "initialize"d should only be called "on setup". The decorator above delays
-# calls to the decorated function until after Product initialization.
-# Also, we need Five to wire all our CMF dependencies.
-ZopeTestCase.installProduct('Five', quiet=install_product_quiet)
 
 try:
   # Workaround iHotFix patch that doesn't work with
   # ZopeTestCase REQUESTs
-  ZopeTestCase.installProduct('iHotfix', quiet=install_product_quiet)
   from Products import iHotfix
   from types import UnicodeType
   # revert monkey patchs from iHotfix
@@ -126,7 +98,6 @@ try:
   iHotfix.iHotfixStringIO = UnicodeSafeStringIO
 except ImportError:
   pass
-ZopeTestCase.installProduct('Localizer', quiet=install_product_quiet)
 try:
   # Workaround Localizer >= 1.2 patch that doesn't work with
   # ZopeTestCase REQUESTs (it's the same as iHotFix
@@ -137,75 +108,10 @@ try:
 except ImportError:
   pass
 
-try:
-  from Products.Localizer import patches
-  # originalStringIO has been removed from recent Localizer versions
-  from Products.Localizer.patches import originalStringIO
-  class UnicodeSafeStringIO(patches.originalStringIO):
-    """StringIO like class which never fails with unicode."""
-    def write(self, s):
-      if isinstance(s, unicode):
-        s = s.encode('utf8', 'repr')
-      patches.originalStringIO.write(self, s)
-  # Localizer will patch PageTemplate StringIO with
-  patches.LocalizerStringIO = UnicodeSafeStringIO
-except ImportError:
-  pass
-
 from Products.ERP5Type.tests.ProcessingNodeTestCase import \
   ProcessingNodeTestCase, patchActivityTool
 onsetup(patchActivityTool)()
 
-ZopeTestCase.installProduct('TimerService', quiet=install_product_quiet)
-
-# CMF
-ZopeTestCase.installProduct('CMFCore', quiet=install_product_quiet)
-ZopeTestCase.installProduct('CMFDefault', quiet=install_product_quiet)
-ZopeTestCase.installProduct('CMFTopic', quiet=install_product_quiet)
-ZopeTestCase.installProduct('DCWorkflow', quiet=install_product_quiet)
-ZopeTestCase.installProduct('CMFCalendar', quiet=install_product_quiet)
-
-# Based on CMF
-ZopeTestCase.installProduct('CMFPhoto', quiet=install_product_quiet)
-ZopeTestCase.installProduct('BTreeFolder2', quiet=install_product_quiet)
-ZopeTestCase.installProduct('CMFReportTool', quiet=install_product_quiet) # Not required by ERP5Type but required by ERP5Form
-ZopeTestCase.installProduct('TranslationService', quiet=install_product_quiet)
-ZopeTestCase.installProduct('PortalTransforms', quiet=install_product_quiet)
-ZopeTestCase.installProduct('MimetypesRegistry', quiet=install_product_quiet)
-
-# Security Stuff
-ZopeTestCase.installProduct('PluggableAuthService', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ERP5Security', quiet=install_product_quiet)
-
-# Debugging
-ZopeTestCase.installProduct('VerboseSecurity', quiet=install_product_quiet)
-ZopeTestCase.installProduct('Zelenium', quiet=install_product_quiet)
-
-# ERP5 - ERP5Type product is installed last so that
-#        initializeProductDocumentRegistry is only called
-#        after all products which need to register their Document 
-#        classes can register them by invoking updateGlobals in __init__
-ZopeTestCase.installProduct('CMFActivity', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ERP5Catalog', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ERP5Form', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ERP5', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ERP5SyncML', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ERP5Type', quiet=install_product_quiet)
-ZopeTestCase.installProduct('CMFCategory', quiet=install_product_quiet)
-ZopeTestCase.installProduct('ZMySQLDDA', quiet=install_product_quiet)
-
-ZopeTestCase.installProduct('ParsedXML', quiet=install_product_quiet)
-
-# Install everything else which looks like related to ERP5
-from OFS.Application import get_products
-for priority, product_name, index, product_dir in get_products():
-  # XXX very heuristic
-  if os.path.isdir(os.path.join(product_dir, product_name, 'Document')) \
-     or os.path.isdir(os.path.join(product_dir, product_name, 'PropertySheet')) \
-     or os.path.isdir(os.path.join(product_dir, product_name, 'Constraint')) \
-     or os.path.isdir(os.path.join(product_dir, product_name, 'Tool')):
-    ZopeTestCase.installProduct(product_name, quiet=install_product_quiet)
-
 from AccessControl.SecurityManagement import newSecurityManager, noSecurityManager
 
 from Acquisition import aq_base
diff --git a/product/ERP5Type/tests/ProcessingNodeTestCase.py b/product/ERP5Type/tests/ProcessingNodeTestCase.py
index e76caad0b44b901af4331492c474d8ad2cab4410..0c19982fb69947e88ede87f8e43cc4117f56635c 100644
--- a/product/ERP5Type/tests/ProcessingNodeTestCase.py
+++ b/product/ERP5Type/tests/ProcessingNodeTestCase.py
@@ -101,6 +101,9 @@ def Application_resolveConflict(self, old_state, saved_state, new_state):
   new_state = new_state.copy()
   old, saved, new = [set(state.pop('test_processing_nodes', {}).items())
                      for state in old_state, saved_state, new_state]
+  # The value of these attributes don't have proper __eq__ implementation.
+  for attr in '__before_traverse__', '__before_publishing_traverse__':
+    del old_state[attr], saved_state[attr]
   if sorted(old_state.items()) != sorted(saved_state.items()):
     raise ConflictError
   new |= saved - old
diff --git a/product/ERP5Type/tests/runUnitTest.py b/product/ERP5Type/tests/runUnitTest.py
index 215049c92bbd194c4243f5f04424862f0332e6af..4c2843681abcead6018e7b7e20e07f934d3df3ad 100755
--- a/product/ERP5Type/tests/runUnitTest.py
+++ b/product/ERP5Type/tests/runUnitTest.py
@@ -322,7 +322,8 @@ class ERP5TypeTestLoader(unittest.TestLoader):
       return filtered_name_list
     return name_list
 
-unittest.TestLoader = ERP5TypeTestLoader
+# BBB: Python < 2.7
+getattr(unittest, 'loader', unittest).TestLoader = ERP5TypeTestLoader
 
 class DebugTestResult:
   """Wrap an unittest.TestResult, invoking pdb on errors / failures
@@ -393,8 +394,9 @@ def runUnitTestList(test_list, verbosity=1, debug=0, run_only=None):
   else:
     products_home = os.path.join(instance_home, 'Products')
 
-  import OFS.Application
-  from Testing import ZopeTestCase
+  from Testing.ZopeTestCase import layer, PortalTestCase
+  _apply_patches = layer._deferred_setup.pop(0)[0]
+  assert _apply_patches.__name__ == '_apply_patches'
 
   from ZConfig.components.logger import handlers, logger, loghandler
   import logging
@@ -448,12 +450,12 @@ def runUnitTestList(test_list, verbosity=1, debug=0, run_only=None):
   # change current directory to the test home, to create zLOG.log in this dir.
   os.chdir(tests_home)
 
+  from Products.ERP5Type.patches import noZopeHelp
   # import ERP5TypeTestCase before calling layer.ZopeLite.setUp
   # XXX What if the unit test itself uses 'onsetup' ? We should be able to call
   #     remaining 'onsetup' hooks just before executing the test suite.
   from Products.ERP5Type.tests.ERP5TypeTestCase import \
       ProcessingNodeTestCase, ZEOServerTestCase, dummy_setUp, dummy_tearDown
-  from Testing.ZopeTestCase import layer
 
   # Since we're not using the zope.testing testrunner, we need to set up
   # the layer ourselves
@@ -510,8 +512,8 @@ def runUnitTestList(test_list, verbosity=1, debug=0, run_only=None):
         # Skip all tests and monkeypatch PortalTestCase to skip
         # afterSetUp/beforeTearDown.
         ERP5TypeTestLoader._testMethodPrefix = 'dummy_test'
-        ZopeTestCase.PortalTestCase.setUp = dummy_setUp
-        ZopeTestCase.PortalTestCase.tearDown = dummy_tearDown
+        PortalTestCase.setUp = dummy_setUp
+        PortalTestCase.tearDown = dummy_tearDown
       elif debug:
         # Hack the profiler to run only specified test methods,
         # and wrap results when running in debug mode.