12
votes

Tester les scripts Python

Comment tester la sortie STDOUT d'un script Python avec un cadre de test telle que doctest, unitest, nez, etc.? Par exemple, dirigez-vous en exécutant mon script "toDo.py -List" devrait renvoyer "Slip the Garbage".

J'ai lu quelqu'un qui sépare la partie d'impression STDOUT du script de la pièce qui génère la sortie à imprimer. Je suis habitué à saupoudrer des déclarations d'impression tout autour de mes scripts shell. Est-ce simplement une habitude hostile de TDD, je devrais casser ou existe un moyen de tester facilement la sortie d'impression correcte?


2 commentaires

Doctest sait déjà comment gérer la production ...


D'abord. Recherche: Stackoverflow.com/questions/3481561/ ... . Seconde. Recherche: La documentation Doctest ( docs.python.org/ Bibliothèque / ... ) dit "La sortie to stdout est capturée, mais pas sortie à stardr".


5 Réponses :


1
votes

Voici quelque chose que j'ai écrit une soirée qui teste le script fonctionne. Notez que le test couvre les cas de base, mais il n'est pas suffisamment approfondi d'être un pas d'autre. Considérez-le un premier projet.

#!/usr/bin/env python

# zs - some example Python code to demonstrate to Z??s
#      interviewers that the writer really does know Python

import sys
from itertools import *

usage = '''
   Usage: zs <string> <pattern> <n>"
          print top n matches of pattern in substring"
'''

if sys.hexversion > 0x03000000:
   print "This script is only intended to run on Python version 2"
   sys.exit(2)

if len(sys.argv) != 4:
   print usage
   sys.exit(1)

A = sys.argv[1] # string to be searched
B = sys.argv[2] # pattern being searched for
N = sys.argv[3] # number of matches to report

if not N.isdigit():
   print "<n> must be a number"
   print usage
   sys.exit(3)

def matchscore(s1, s2):
   ''' a helper function to calculate the match score
   '''
   matches = 0
   for i in xrange(len(s1)):
      if s1[i] == s2[i]:
         matches += 1
   return (matches + 0.0) / len(s1)  # added 0.0 to force floating point div

def slices(s, n):
   ''' this is a generator that returns the sequence of slices of
       the input string s that are n characters long '''
   slen = len(s)
   for i in xrange(slen - n + 1):
      yield s[i:i+n]

matchlen = len(B)
allscores = ((matchscore(x,B),x,i) for i,x in enumerate(slices(A,matchlen)))
nonzeros = [ y for y in allscores if y[0] != 0 ]

for elem in sorted(nonzeros,key=lambda e: e[0],reverse=True):
   nprinted = 0 # We will count them; in case num elements > N
   print elem[1], str(round(elem[0],4)), elem[2]
   nprinted += 1
   if nprinted >= N:
      break


0 commentaires

10
votes

Je vois de deux manières:

  1. Rediriger stdout lors de l'intention: XXX

  2. Utilisez un enregistreur pour vos sorties et écoutez-la dans votre test.


0 commentaires

3
votes

Lorsque vous utilisez Py.Test pour vos tests. Vous pouvez utiliser les arguments de la fonction de test "capsys" ou "capfd" pour exécuter des affirmations contre STDOUT et STDIN

def test_myoutput(capsys): # or use "capfd" for fd-level
    print ("hello")
    sys.stderr.write("world\n")
    out, err = capsys.readouterr()
    assert out == "hello\n"
    assert err == "world\n"
    print "next"
    out, err = capsys.readouterr()
    assert out == "next\n"


0 commentaires

0
votes

Je souhaiterai peut-être aussi regarder le TextTest Cadre de test. Il se concentre davantage sur les tests fonctionnels / acceptés (de sorte que les tests unitaires) et repose fortement sur la sortie textuelle d'un programme. De cette façon, votre habitude devient une bonne: -).


0 commentaires

8
votes

La propre suite de test de Python le fait beaucoup, et nous utilisons deux techniques principales:

  1. Redirection de stdout (comme d'autres ont suggéré). Nous utilisons un gestionnaire de contexte pour cela: XXX

  2. Utilisation du module sous-processus . Nous utilisons cela lorsque nous souhaitons spécifiquement tester la gestion des arguments de ligne de commande. Voir http://hg.python.org/cpython/file/ Par défaut / LIB / TEST / TEST_CMD_LINE_Script.py Pour plusieurs exemples.