[PYTHON] N'hésitez pas à rédiger un test avec nez (dans le cas de + gevent)

Il existe différents frameworks de test pour python, mais j'aime personnellement le framework appelé nose, alors j'aimerais le présenter.

installation du nez

$ pip install nose

Vous pouvez avoir besoin de sudo en fonction de votre environnement.

écrire un cas de test de nez

Supposons que vous ayez la fonction sum et la fonction is_even suivantes dans un module appelé hoge.

hoge.py


def sum(a, b):
	return a + b

def is_even(n):
	return (n % 2 == 0)

Créez le fichier test_hoge.py suivant qui hérite de unittest.TestCase. Ici, ʻeq_ pour vérifier si la valeur est la même que la ** valeur attendue ** et ʻok_ pour vérifier si la valeur est ** true ** sont importés de nose.tools et utilisés. Je vais. En tant que mécanisme commun dans le cadre de test, «setUp» et «tearDown» sont fournis pour un traitement tel que l'initialisation / la libération des ressources avant et après le test, alors essayez d'insérer une instruction d'impression.

test_hoge.py


from unittest import TestCase
from nose.tools import ok_, eq_
from hoge import sum, is_even

class HogeTestCase(TestCase):
	def setUp(self):
		print 'before test'
	def tearDown(self):
		print 'after test'
	
	def test_sum(self):
		eq_(sum(1, 2), 3)
		eq_(sum(5, 11), 16)
		eq_(sum(0, 0), 0)

	def test_is_even(self):
		ok_(is_even(2))
		ok_(not is_even(3))

Exécutez le cas de test

nose est livré avec une commande de test runner appelée nosetests. (Le nez d'installation du pip l'installera) Si vous exécutez nos tests ici, ce sera comme suit.

$ nosetests
..
----------------------------------------------------------------------
Ran 2 tests in 0.003s

OK

Lorsque nosetests est exécuté, il recherchera des fichiers de type test (y compris test dans le nom du fichier) dans le répertoire courant, et collectera et exécutera les classes qui héritent de ʻunittest.TestCase. Je n'ai pas reçu le message que j'aurais dû imprimer avec l'instruction d'impression, car par défaut, le nez capture la sortie vers la sortie standard. Vous pouvez voir la sortie telle quelle avec l'option -s`.

$ nosetests -s

Ajoutez l'option -v pour afficher le nom du cas de test en cours d'exécution par le nom de la méthode ainsi que par le point.

$ nosetests -v

Quand j'ai essayé de l'exécuter ensemble, c'est devenu comme suit.

$ nosetests -s -v
test_is_even (test_hoge.HogeTestCase) ... before test
after test
ok
test_sum (test_hoge.HogeTestCase) ... before test
after test
ok

----------------------------------------------------------------------
Ran 2 tests in 0.002s

OK

Vous pouvez également spécifier un nom de fichier pour que la commande nosetests exécute uniquement des tests sur des fichiers spécifiques. Ce serait pratique si le développement progressait et les tests augmentés.

$ nosetests ./test_hoge.py

Autres outils

Voici quelques autres outils de test pour ʻok_ et ʻeq_. Voir la page des outils de test de nose (http://nose.readthedocs.org/en/latest/testing_tools.html) pour plus d'informations.

raises

Utilisez raises comme décorateur pour les tests susceptibles de provoquer des exceptions. Testez la fonction suivante div où une exception est susceptible de se produire.

fuga.py


def div(n, m):
	return n / m

Le cas de test est ci-dessous.

fuga_hoge.py


from unittest import TestCase
from nose.tools import eq_, raises
from fuga import div
class FugaTestCase(TestCase):
	def test_div(self):
		eq_(div(10, 5), 2)
		eq_(div(10, 10), 1)
		eq_(div(9, 3), 3)

	@raises(ZeroDivisionError)
	def test_div_zerodiv(self):
		div(10, 0)

	

Vous pouvez maintenant vérifier si le scénario de test test_div_zerodiv lance correctement l'exception ZeroDivisionError.

timed

timed est un décorateur qui vérifie si un cas de test se termine dans un laps de temps spécifié (spécifié en secondes). Prenons un test qui vérifie qu'une fonction do_something, dont le traitement prend environ 0,1 seconde, se termine en 0,2 seconde, comme ce qui suit.

moge.py


import time
def do_something():
	time.sleep(0.1)

Le cas de test ressemble à ceci:

test_moge.py


from unittest import TestCase
from nose.tools import timed
from moge import do_something

class MogeTestCase(TestCase):
    @timed(0.2)
    def test_do_something(self):
        do_something()

Ecrire un test d'un programme en utilisant gevent

Pour les programmes qui utilisent gevent, il est recommandé d'utiliser les décorateurs suivants.

décorateur gtest


import gevent
def gtest(func):
	def _gtest(*args, **kwargs):
		gevent.spawn(func, *args, **kwargs).join()
	_gtest.__name__ = func.__name__
	return _gtest

Testons un programme comme celui ci-dessous. _tick et _tacik se déplacent alternativement, envoyant des chaînes de caractères numérotées telles que tick1, tack1, tick2, tack2 alternativement dans la file d'attente, et enfin aspirer tout le contenu de la file d'attente et le renvoyer sous forme de tableau Te donnera.

g.py


import gevent
import gevent.queue

def ticktack(n):
    q = gevent.queue.Queue()

    def _tick(_q, _n):
        for i in range(_n):
            _q.put('tick%d' % (i + 1))
            gevent.sleep()

    def _tack(_q, _n):
        for i in range(_n):
            _q.put('tack%d' % (i + 1))
            gevent.sleep()

    _tick_thread = gevent.spawn(_tick, q, n)
    _tack_thread = gevent.spawn(_tack, q, n)

    result = []
    while len(result) < n * 2:
        result.append(q.get())

    return result

Puisque gevent effectue un changement décisif de greenlet lorsque gevent.sleep () est appelé, le _tick généré en premier et le _tack généré plus tard sont toujours appelés.

Testons cela avec le décorateur ci-dessus.

test_g.py


from unittest import TestCase
from nose.tools import eq_
import gevent

from g import ticktack

import gevent
def gtest(func):
    def _gtest(*args, **kwargs):
        gevent.spawn(func, *args, **kwargs).join()
    _gtest.__name__ = func.__name__
    return _gtest

class GTestCase(TestCase):
    @gtest
    def test_ticktack(self):
        r1 = ticktack(1)
        eq_(r1, ['tick1', 'tack1'])
        r2 = ticktack(2)
        eq_(r2, ['tick1', 'tack1', 'tick2', 'tack2'])

Vous vous sentiez bien?

Résumé

--nose facilite et simplifie l'écriture de cas de test --nosetests a différentes options et peut être exécuté de manière flexible

J'espère que cela aide.

Recommended Posts

N'hésitez pas à rédiger un test avec nez (dans le cas de + gevent)
Ecrire le test dans la docstring python
N'hésitez pas à changer l'étiquette de légende avec Seaborn en python
Pour générer une valeur au milieu d'une cellule avec Jupyter Notebook
Comment obtenir une liste de fichiers dans le même répertoire avec python
Je veux écrire en Python! (2) Écrivons un test
Comment identifier l'élément avec le plus petit nombre de caractères dans une liste Python?
Notez ce que vous voulez faire à l'avenir avec Razpai
Obtenez de manière récursive la liste Excel dans un dossier spécifique avec python et écrivez-la dans Excel.
J'ai écrit un doctest dans "J'ai essayé de simuler la probabilité d'un jeu de bingo avec Python"
Ecrire un test piloté par table en C
N'hésitez pas à crypter le disque
Traitez le contenu du fichier dans l'ordre avec un script shell
Comment déterminer l'existence d'un élément sélénium en Python
Comment vérifier la taille de la mémoire d'une variable en Python
[Introduction à StyleGAN] J'ai joué avec "The Life of a Man" ♬
Exportez le contenu de ~ .xlsx dans le dossier en HTML avec Python
J'ai écrit le code pour écrire le code Brainf * ck en python
Comment vérifier la taille de la mémoire d'un dictionnaire en Python
Comment obtenir les coordonnées de sommet d'une entité dans ArcPy
Comment créer une grande quantité de données de test dans MySQL? ??
Écrivez un script pour calculer la distance avec le système Elasticsearch 5 sans douleur
Créez une fonction pour obtenir le contenu de la base de données dans Go
Rendement dans la classe qui a hérité de l'unittest.TestCase ne fonctionnait pas avec le nez (selon la version du nez?)
Comment écrire quand on veut mettre un nombre après le numéro de groupe à remplacer par une expression régulière dans re.sub de Python
L'histoire d'un capteur de stationnement en 10 minutes avec le kit de démarrage GrovePi +
Réfléchissez à la façon d'écrire un filtre avec les versions Shotgun API-Contact
Générez une liste contenant le nombre de jours du mois en cours.
[Introduction à Python] Comment trier efficacement le contenu d'une liste avec le tri par liste
[Linux] Une commande pour obtenir une liste des commandes exécutées dans le passé
Je souhaite trier une liste dans l'ordre des autres listes
Paramètre pour entrer le contenu de la bibliothèque avec pytest et effectuer un test de débogage
Recevez une liste des résultats du traitement parallèle en Python avec starmap
[Introduction à Python] Comment écrire une chaîne de caractères avec la fonction format
Divers commentaires à écrire dans le programme
J'ai fait un programme pour vérifier la taille d'un fichier avec Python
J'ai fait une erreur en récupérant la hiérarchie avec MultiIndex of pandas
J'ai essayé d'afficher la valeur d'altitude du DTM dans un graphique
J'ai essayé de vérifier le résultat du test A / B avec le test du chi carré
[Python & SQLite] J'ai analysé la valeur attendue d'une course avec des chevaux dans la fourchette 1x win ①
Je voulais connaître le nombre de lignes dans plusieurs fichiers et j'ai essayé de l'obtenir avec une commande
Différentes façons de lire la dernière ligne d'un fichier csv en Python
Comment passer le résultat de l'exécution d'une commande shell dans une liste en Python
9 étapes pour devenir un expert en apprentissage automatique dans les plus brefs délais [Entièrement gratuit]
Comment mentionner un groupe d'utilisateurs avec une notification de mou, comment vérifier l'ID d'un groupe d'utilisateurs
[Python] A créé une classe pour jouer des vagues de péché en arrière-plan avec pyaudio
Comment compter le nombre d'éléments dans Django et sortir dans le modèle
[AWS] Lançons un test unitaire de la fonction Lambda dans l'environnement local
Notez la solution car django n'a pas pu s'installer avec pip
Vérifiez le nombre de fois où la requête (sql) a été lancée dans django avec un test
J'ai créé une commande appdo pour exécuter des commandes dans le contexte de l'application
Je souhaite définir un cycle de vie dans la définition de tâche d'ECS
Un mémorandum expliquant comment exécuter la commande magique! Sudo dans Jupyter Notebook
Connexion SSH au serveur cible à partir de Windows en un clic sur un raccourci
Je souhaite voir une liste de fichiers WebDAV dans le module Requêtes
Recherche d'un moyen efficace d'écrire un Dockerfile avec Python avec de la poésie
Je n'ai pas eu besoin d'écrire décorateur en classe Merci contextmanager