Remarques sur l'utilisation du test unittest standard Python

introduction

Positionnement de ce mémo

Ce commentaire est un bref enregistrement de la façon d'utiliser la fonctionnalité unittest de Python. Le but est d'expliquer ce qu'est la fonction de test unitaire de Python, de fournir un exemple simple et de fournir un modèle lorsque vous souhaitez effectuer une sorte de test à l'avenir.

Il ne traite pas de la façon d'utiliser doctest.

De plus, je pense que j'utilise nosetests lors de l'exécution de nombreux tests, mais je ne l'explique pas non plus.

** Bien sûr, lire un livre ou un document officiel vous apportera des connaissances utiles, et si vous l'utilisez au travail, vous devriez plutôt en lire un qui convient. Pour tout le monde. ** **

Version cible de Python

Python 2.7.11

Python

Qu'est-ce que le test unitaire Python?

Un groupe de modules qui implémentent des fonctionnalités utiles pour tester le code Python. Il est inclus dans l'environnement d'exécution Python et devrait être disponible lorsque Python est installé. Il peut être utilisé en important comme suit.

import unittest

Il semble y avoir beaucoup d'autres outils de test. Jetez un œil aux sites sur références.

Documentation officielle

Pour plus d'informations sur les fonctionnalités de Python unittest, consultez la documentation officielle.

Tout d'abord, il décrit brièvement le type de fonction dont il dispose. Après cela, des exemples d'utilisation sont montrés afin que de nombreuses personnes devraient supprimer cette utilisation. À partir de la phase intermédiaire, il y a des détails sur chaque fonction et une liste des méthodes Assert hogehoge utilisées pour les tests.

Version anglaise: https://docs.python.org/2.7/library/unittest.html Version japonaise: https://docs.python.org/ja/2.7/library/unittest.html#module-unittest

Comment utiliser

Comment utiliser

L'utilisation de base est la suivante.

  1. Importez unittest
  2. Créez une classe TestHOGEHOGE qui hérite unittest.TestCase
  3. Décrivez le scénario de test dans TestHOGEHOGE. Le scénario de test utilise un ensemble de méthodes nommées AssertHOGE (). Cette méthode compare la correspondance, la relation de magnitude, etc.
  4. Exécutez le test avec unittest.main (). Si le résultat souhaité est atteint, le résultat est le succès, sinon l'échec.

L'exemple le plus élémentaire

Supposons que vous ayez un code approprié. Par exemple, la méthode suivante qui ajoute simplement.

tashizan.py



def tashizan(a, b):
    """ calculate (a + b)
    """
    return a + b

Je veux tester ça. La fonction qui devrait être remplie serait que l'addition soit effectuée correctement (pas de soustraction, etc.). J'écrirai un module pour cela.

test_tashizan.py



import unittest
from tashizan import tashizan


class TestTashizan(unittest.TestCase):
    """test class of tashizan.py
    """

    def test_tashizan(self):
        """test method for tashizan
        """
        value1 = 2
        value2 = 6
        expected = 8
        actual = tashizan(value1, value2)
        self.assertEqual(expected, actual)


if __name__ == "__main__":
    unittest.main()

Frapper unittest.main () exécutera un groupe de tests. Le résultat de cette opération est le suivant.

$ python test_tashizan.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

Lorsque unittest.main () est exécuté, toutes les classes qui héritent d'unittest.TestCase dans le script cible sont reconnues, et toutes les méthodes dont le nom commence par test sont exécutées comme cas de test.

Exécuter uniquement des méthodes de test spécifiques

S'il y a plusieurs tests, exécutez-les par la méthode ci-dessus et ils seront exécutés en même temps. Le résultat de l'ajout d'une soustraction à la précédente et de son exécution est le suivant

keisan.py


def tashizan(a, b):
    """calculate a+b

    :param a: value 1(int)
    :param b: value 2(inte)
    :return: a + b
    """
    return a + b


def hikizan(a, b):
    """calculate a - b

    :param a:  value 1(int)
    :param b:  value 2(int)
    :return:  a - b
    """
    return a - b

--−−−

test_keisan.py


import unittest
import keisan


class TestKeisan(unittest.TestCase):
    """test class of keisan.py
    """

    def test_tashizan(self):
        """test method for tashizan
        """
        value1 = 2
        value2 = 6
        expected = 8
        actual = keisan.tashizan(value1, value2)
        self.assertEqual(expected, actual)


class TestKeisan2(unittest.TestCase):
    def test_hikizan(self):
        """test method for hikizan
        """
        value1 = 2
        value2 = 12
        expected = -10
        actual = keisan.hikizan(value1, value2)
        self.assertEqual(expected, actual)


if __name__ == "__main__":
    unittest.main()

$ python test_keisan.py -v
test_tashizan (__main__.TestKeisan)
test method for tashizan ... ok
test_hikizan (__main__.TestKeisan2)
test method for hikizan ... ok

----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

(Classes arbitrairement séparées. Dans le cas ci-dessus, vous écrivez probablement dans une classe) Cependant, il arrive que vous souhaitiez exécuter uniquement une classe de test spécifique. Dans ce cas, utilisez l'option -m lors de l'exécution. Un exemple est présenté ci-dessous. Ici, en ajoutant l'option -v après unittest, des informations sur le contenu du test sont affichées. Si vous faites python -m -v ..., l'option -v sera passée à l'interpréteur Python, donc beaucoup d'informations sans rapport avec le test seront affichées. (Voir le commentaire de @ skawagt)

$ python  -m unittest test_keisan.TestKeisan2 -v
.
test_hikizan (test_keisan.TestKeisan2)
test method for hikizan ... ok

----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

Résumer le traitement avant et après l'exécution du scénario de test

L'initialisation de la valeur peut prendre du temps. Lorsque vous souhaitez vérifier diverses opérations sur un objet spécifique, il est difficile de saisir une valeur pour chaque scénario de test. Dans ce cas, il existe des méthodes setUp et tearDown. SetUp et tearDown seront exécutés pour chaque cas de test.

Voici un exemple de cas où vous avez une classe d'équations quadratiques et que vous souhaitez la tester.

QuadraticEquation.py


import numpy as np


class QuadraticEquation(object):
    """Quadratic equation class
    """

    def __init__(self):
        self.a = 1.0
        self.b = 2.0
        self.c = 1.0

    def calc_root(self):
        """calculate root

        :return: root1, root2 (root1 < root2)
        """
        x1 = (-1.0 * self.b - np.sqrt(self.b * self.b - 4.0 * self.a * self.c)) / (2.0 * self.a)
        x2 = (-1.0 * self.b + np.sqrt(self.b * self.b - 4.0 * self.a * self.c)) / (2.0 * self.a)
        return x1, x2

    def calc_value(self, x):
        """ calculate polynomial value

        :param x: x
        :return: a * x^2 + b * x + c
        """

        return self.a * np.power(x, 2.0) + self.b * x + self.c

Le scénario de test pour cela est le suivant.

test_quadraticEquation.py


import unittest
import QuadraticEquation
from unittest import TestCase


class TestQuadraticEquation(unittest.TestCase):
    def setUp(self):
        print "setup"
        self.eq = QuadraticEquation.QuadraticEquation()

    def test_calc_root(self):
        """ test method of s"""
        expected = (-1.0, -1.0)
        actual = self.eq.calc_root()

        self.assertEqual(expected, actual)
        self.assertEqual((0.0, 0.0), (self.eq.calc_value(actual[0]), self.eq.calc_value(actual[1])))

    def test_calc_value(self):
        """ test method of calc_value() """
        expected = (4.0, 9.0)
        actual = (self.eq.calc_value(1.0), self.eq.calc_value(2.0))

        self.assertEqual(expected, actual)

    def tearDown(self):
        print "tearDown"
        del self.eq


if __name__ == '__main__':
    unittest.main()

Lorsqu'elles sont exécutées avec this, on peut voir que les méthodes setUp et tearDown sont appelées au début et à la fin du scénario de test comme indiqué ci-dessous.

$ python -m unittest test_quadraticEquation
setup
tearDown
.setup
tearDown
.
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

Faites un groupe de tests à la fois

En réalité, je pense que c'est le cas lorsqu'il y a plusieurs modules que vous prenez la peine de créer et de tester explicitement des tests unitaires. Dans ce cas, vous ne pouvez pas simplement frapper un grand nombre de modules de test à la main.

Dans ce cas, vous pouvez utiliser la fonction de découverte d'unittest.

$ python -m unittest discover

Compte tenu des deux cas de test ci-dessus

$ ls
QuadraticEquation.py  keisan.py  test_keisan.py  test_quadraticEquation.py

En utilisant la découverte ci-dessus, cela ressemble à ceci: Tous les tests ont été exécutés.

$ python -m unittest discover
....
----------------------------------------------------------------------
Ran 4 tests in 0.000s

OK

Mesurer la couverture

[Inachevé]

Vous voudrez peut-être mesurer le taux de couverture du test, mais ce n'est probablement pas une fonctionnalité d'unittest. Alors Utilisez une couverture.

$ pip install coverage

Vous pouvez l'utiliser pour mesurer la couverture d'un certain module ou en faire un fichier html ... Mais faire beaucoup Vous devez écrire le script vous-même.

Puisqu'il n'y a aucun test, il vaudrait mieux l'utiliser (lancer)

Liste des méthodes d'actif

Extrait du fonctionnaire. Presque égal est également utile pour comparer les flottants. Ce n'est pas tout, veuillez donc vous référer à la formule.

Type de méthode ASSER Vérifier la cible
assertEqual(a, b) a == b
assertNotEqual(a, b) a != b
assertTrue(x) bool(x) is True
assertFalse(x) bool(x) is False
assertIs(a, b) a is b
assertIsNot(a, b) a is not b
assertIsNone(x) x is None
assertIsNotNone(x) x is not None
assertIn(a, b) a in b
assertNotIn(a, b) a not in b
assertIsInstance(a, b) isinstance(a, b)
assertNotIsInstance(a, b) not isinstance(a, b)
assertAlmostEqual(a, b) round(a-b, 7) == 0
assertNotAlmostEqual(a, b) round(a-b, 7) != 0
assertGreater(a, b) -a > b
assertGreaterEqual(a, b) a >= b
assertLess(a, b) a < b
assertLessEqual(a, b) a <= b
assertRegexpMatches(s, r) r.search(s)
assertNotRegexpMatches(s, r) not r.search(s)
assertDictContainsSubset(a, b) all the key/value pairs in a exist in b

Résumé

  1. Importez unittest et écrivez un cas de test dans une classe qui hérite d'unittest.TestCase ――A ce moment, avec une méthode comme AssetHOGEHOGE
  2. Exécutez le test en appuyant sur unittest.main (). Utilisez Discover si vous souhaitez tester différents modules à la fois

references Vous trouverez ci-dessous des références et des sites.

Recommended Posts

Remarques sur l'utilisation du test unittest standard Python
notes d'utilisation du décorateur python
python * args, ** kwargs Notes d'utilisation
Mémo de raclage Python
Note d'apprentissage Python_000
Notes d'apprentissage Python
concurrent.futures Notes d'utilisation
Unittest en Python
Notes de débutant Python
Note d'apprentissage Python_006
[Python] Entrée standard
notes de python C ++
Note d'apprentissage Python_005
Notes de grammaire Python
Note sur la bibliothèque Python
notes personnelles python
mémo pandas python
Note d'apprentissage Python_001
notes d'apprentissage python
Notes d'installation de Python3.4
notes personnelles en python manquantes
Notes de développement de package Python
liste assertXXX unittest python
Utilisation des locaux Python ()
Mémo du package d'adresse IP Python
Notes sur le format Python Pickle
Premier mémo divers sur Python
Matlab => Notes de migration Python
Remarques sur l'affectation Python3
Notes sur l'utilisation de sous-processus Python
[Python] À propos de l'entrée standard
Python essayer / sauf mémo
Notes sur le flacon de framework Python
Structure de répertoire lors de l'écriture de tests avec unittest standard Python 3
mémo python utilisant l'opérateur perl-ternaire
Mémo d'apprentissage O'Reilly python3 Primer
Python 3.4 ou version ultérieure standard pip
[Python3] Entrée standard [Cheet sheet]
Notes Python à oublier bientôt
notes python pour l'utilisation de variables spéciales perl
Notes sur l'expression régulière de la théorie Python
Mémo Python Tkinter (pour moi)
Remarques pratiques sur l'utilisation de la commande diff
Entrée standard Python3 (compétition pro)
Entrée standard / résumé / python, ruby
Recevoir des conseils d'entrée standard @ python
[Python] Notes sur l'analyse des données
Matrice transposée au standard Python
Notes d'apprentissage sur l'analyse des données Python
Remarques sur l'installation de Python sur votre Mac
Exemple d'utilisation de pickle Python
Unittest et CI en Python
Utilisation basique de la f-string Python
Obtenez des notes Evernote en Python
[Python] Utilisation correcte de la jointure
environnement virtuel standard python venv
Remarques sur l'installation de Python sur CentOS
Entrée standard Python3 pour une programmation compétitive