Je préfère avoir des fonctions de sortie explicitement accepter un fichier handle (ou fichier-comme objet), plutôt que d'accepter un fichier nom et l'ouverture du fichier eux-mêmes. De cette façon, je peux passer un StringIO.StringIO
(ou plus généralement un cStringIO.StringIO
) de l'objet à la fonction de sortie dans mon unité de test, .read()
le contenu retour, StringIO
objet (après un .seek(0)
appel) et de la comparer avec ma sortie attendue.
Par exemple:
##File:lamb.py
import sys
def write_lamb(filename):
outfile = open(filename, 'w')
outfile.write("Mary had a little lamb.\n")
outfile.close()
if __name__ == '__main__':
write_lamb(sys.argv[1])
##File test_lamb.py
import unittest
import tempfile
import lamb
class LambTests(unittest.TestCase):
def test_lamb_output(self):
tempfile_path = tempfile.mkstemp()[1]
lamb.write_lamb(tempfile_path)
expected = "Mary had a little lamb.\n"
result = open(tempfile_path).read()
try:
# NOTE: You could replace this with a string-comparison
# method like assertMultiLineEqual
self.assertEqual(result, expected)
finally:
# NOTE: To retain the tempfile if the test fails, remove
# the try-finally clause.
os.remove(tempfile_path)
Va à ce
##File:lamb2.py
import sys
def write_lamb(outfileh):
outfileh.write("Mary had a little lamb.\n")
if __name__ == '__main__':
outfile = open(sys.argv[1])
write_lamb(outfile)
outfile.close()
##File test_lamb2.py
import unittest
#import tempfile
import cStringIO
import lamb2
class LambTests(unittest.TestCase):
def test_lamb_output(self):
tempfile = cStringIO.StringIO()
# NOTE: Alternatively, for Python 2.6+, you can use
# tempfile.SpooledTemporaryFile, e.g.,
#tempfile = tempfile.SpooledTemporaryFile(10 ** 9)
lamb.write_lamb(tempfile)
expected = "Mary had a little lamb.\n"
tempfile.seek(0)
result = tempfile.read()
self.assertEqual(result, expected)
Cette approche a l'avantage de faire de votre fonction de sortie plus souple si, par exemple, vous décidez que vous ne voulez pas écrire dans un fichier, mais certains autres tampon, puisqu'il accepte tous les fichiers comme des objets.
Notez que l'utilisation de StringIO
suppose que le contenu de la sortie du test peut s'intégrer dans la mémoire principale. Pour les très grosses sorties, utiliser un fichier temporaire (par exemple, tempfile.SpooledTemporaryFile).