2011-05-01 4 views
2

En Python 2.5 (Jython réellement), pour la classe UnitTest TestCase - il n'y a pas de méthode SetUpClass, et __init__ n'est pas vraiment acceptable (pas de refférence à soi-même). Lorsque je tente de changer docstring à l'intérieur du TestCase:Comment changer la docstring de la classe TestCase en Python?

import os 
fileName = os.path.split(__file__)[1] 
testCaseName = os.path.splitext(fileName)[0] 
setattr(__name__, '__doc__', testCaseName) 

Je reçois:

setattr(__name__, '__doc__', testCaseName) 
TypeError: readonly attribute 

J'ai essayé de changer le docstring par instancier dans un objet (où self.__doc__ est éditable).

UPDATED: but I want to avoid additional coding in the sub-class (i.e. inheriting super-class function to set docstring of sub-class), for example:

DynamicTestCase.py Fichier comprend:

class DynamicTestCase(unittest.TestCase): 
    def setDocstring(self, testCaseDocstring=None): 
     if not testCaseDocstring: 
      fileName = os.path.split(__file__)[1] 
      testCaseDocstring = os.path.splitext(fileName)[0] 
     setattr(self, '__doc__', testCaseDocstring) 

MyTestCase.py Fichier comprend:

class MyTestCase(DynamicTestCase): 
    def test_print_docstring(self): 
     self.setDocstring() 
     print 'MyTestCase Docstring = ', self.__doc__ 

Mais encore, le résultat de l'exécution unittest est:

MyTestCase Docstring = DynamicTestCase 

Lorsque je me attendais MyTestCase docstring = MyTestCase

Répondre

1

Mise à jour-__file__ est le chemin à partir duquel le module en cours a été chargé, alors naturellement à l'aide __file__ à l'intérieur DynamicTestCase.py entraînera le chemin DynamicTestCase. py. Cependant, vous pouvez tout simplement passer le chemin dans setDocstring() de sous-classes comme ceci:

DynamicTestCase.py:

class DynamicTestCase(unittest.TestCase): 
    def setDocstring(self, docstring=None): 
     if docstring is None: 
      docstring = __file__ 
     if os.path.exists(docstring): 
      name = os.path.split(docstring)[1] 
      docstring = os.path.splitext(name)[0] 
     setattr(self, '__doc__', docstring) 

MyTestCase.py:

class MyTestCase(DynamicTestCase): 
    def __init__(self, *args, **kwargs): 
     DynamicTestCase.__init__(self, *args, **kwargs) 
     self.setDocstring(__file__) 

    def test_print_docstring(self): 
     print 'MyTestCase Docstring = ', self.__doc__ 

    def test_new_docstring(self): 
     self.setDocstring('hello') 
     print 'MyTestCase Docstring = ', self.__doc__ 

Sortie:

MyTestCase Docstring = MyTestCase 
MyTestCase Docstring = hello 

Reste réponse

Dans votre code d'origine ci-dessus __name__ est une chaîne, pas une classe. Jython rejette à juste titre la modification de l'attribut __doc__ sur le type str.

Pourriez-vous expliquer un peu à propos de pourquoi vous voulez changer la docstring de TestCase? Par exemple, vous pouvez sous-classe TestCase et de donner votre propre docstring:

class MyTestCase(unittest.TestCase): 
    "Docstring of MyTestCase" 

Je ne sais pas si vous avez encore essayé, mais le unittest2 package's TestCase a setUpClass, tearDownClass méthodes de classe. C'est un backport des améliorations de Python 2.7 pour travailler avec Python 2.6 et avant.Jython vous permet de définir __doc__ de classes de style nouveau, mais pas CPython. Pour cette raison, vous voudrez peut-être trouver un autre moyen pour atteindre votre objectif si vous voulez être portable votre code:

Jython 2.2.1 on java1.6.0_24 
>>> unittest.TestCase.__doc__ = 'foo bar' 
>>> unittest.TestCase.__doc__ 
'foo bar' 

Python 2.6.6 (r266:84292, Feb 12 2011, 01:07:21) 
>>> unittest.TestCase.__doc__ = 'foo bar' 
AttributeError: attribute '__doc__' of 'type' objects is not writable 
+0

samplebias Merci, j'ai essayé en premier lieu de changer le docstring TestCase, avant d'ajouter son module au testLoader: 'recueil HSC (unittest.defaultTestLoader .loadTestsFromName (testCase)) –

+0

Mais comme TestCase __doc__ n'est pas accessible en écriture, j'essaie maintenant de le faire comme vous l'avez suggéré - sous la sous-classe: 'def setDocstring (self): fileName = os.path.split (__file __) [1] testCaseDocstring = os.path.splitext (nomfichier) [0] setattr (self, '__doc__', testCaseDocstring) 'Cependant, cette fonction ne fonctionne pas non plus, car lors de son utilisation, la sous-classe docstring toujours obtient le nom de fichier de super-classe, au lieu du nom de fichier de sous-classe actuel. –

+0

Je vais mettre à jour la réponse avec ce que je voulais dire par "changez-le dans la sous-classe de TestCase". Pouvez-vous donner un exemple du problème que vous essayez de résoudre en changeant la docstring de la classe? – samplebias

0

Vous saisissant le nom du fichier DynamicTestCase, pas le fichier qui appelle la fonction. Afin d'obtenir que vous devez aller dans c'est cadre de support:

import inspect 

    class DynamicTestCase(unittest.TestCase): 
    def setDocstring(self, testCaseDocstring=None): 
     if not testCaseDocstring: 
      fileName = 'unknown.py' 

      # Go up one stack frame and grab the file name 
      stack = inspect.stack() 
      try: 
       frame = stack[1][0] 
       fileName = frame.f_code.co_filename   
      finally: 
       del stack 

      testCaseDocstring = os.path.splitext(fileName)[0] 
Questions connexes