Déclenche une exception AssertionError si la variable test est false.
test = 0
data = "assertion error"
try:
assert test,data
except AssertionError:
print data
finally:
print "the end"
S'il ne s'agit que de la partie instruction assert, vous pouvez la remplacer en écrivant comme suit.
if __debug__:
if not test
raise AssertionError, data
somedata = 1
#Abattez les exceptions que vous voulez attraper.
fatal_exceptions = (KeyboardInterrupt, MemoryError)
try:
assert somedata
except fatal_exceptions, inst: #Vous pouvez recevoir le contenu de l'exception avec l'argument inst.
print type(inst) #Afficher le type d'exception
print inst #Afficher le contenu de l'exception
raise
#Attrapez toutes les autres exceptions
except Exception, inst:
print type(inst) #Afficher le type d'exception
print inst #Afficher le contenu de l'exception
finally:
print "the end"
UnitTest Exemples légèrement modifiés et ajoutés du tutoriel officiel.
import random
import unittest
class TestSequenceFunctions(unittest.TestCase):
#Processus d'initialisation appelé à chaque fois
#En plus de cela, il existe une méthode appelée après l'exécution du test, etc.
def setUp(self):
self.seq = range(10)
#Décrivez le nom de la méthode en commençant par test.
def test_shuffle(self):
random.shuffle(self.seq)
self.seq.sort()
#Vérifiez que les deux arguments sont égaux.
#Vérifier l'inégalité est assertNotEqual()Vous pouvez le faire avec.
self.assertEqual(self.seq, range(10))
#Vérifiez les exceptions.
# assertRaises(exception, callable, *args, **kwds)
#Passez args et kwds à la fonction du deuxième argument et vérifiez que l'exception spécifiée par le premier argument se produit.
self.assertRaises(TypeError, random.shuffle, (1,2,3))
def test_choice(self):
element = random.choice(self.seq)
#Vérifiez que la valeur de l'argument est True.
# bool(element)Équivaut à est vrai
self.assertTrue(element in self.seq)
def test_sample(self):
#Si seul l'argument d'exception est passé, le gestionnaire de contexte est renvoyé.
#Vous pouvez écrire le code à tester en ligne.
with self.assertRaises(ValueError):
random.sample(self.seq, 20)
for element in random.sample(self.seq, 5):
self.assertTrue(element in self.seq)
if __name__ == '__main__':
# main()Peut être exécuté avec.
unittest.main()
#Faites exécuter des tests individuellement.
_test_choice = TestSequenceFunctions('test_choice')
_test_sample = TestSequenceFunctions('test_sample')
#Il peut être enregistré dans la suite de tests et exécuté collectivement par le coureur.
TestSuite = unittest.TestSuite()
TestSuite.addTest(_test_choice)
TestSuite.addTest(_test_sample)
runner = unittest.TextTestRunner()
runner.run(TestSuite)
#Vous pouvez obtenir des fonctions de test collectivement avec le chargeur.
suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)
unittest.TextTestRunner(verbosity=2).run(suite)
traceback La pile est la zone de mémoire où le programme est en cours d'exécution. Une trace de pile enregistre l'état d'exécution (nom de la fonction, nom de la fonction appelante, ligne, instruction, nom de fichier) du programme dans la zone de mémoire, et il s'agit d'un objet dans les langages de script tels que Python. Il est fourni.
Tout d'abord, les informations de trace de pile peuvent être obtenues à partir de sys.exc_info ().
exc_type, exc_value, exc_traceback = sys.exc_info()
En utilisant ces trois variables comme arguments, traceback.print_tb () et traceback.print_exception () affichent des informations.
Cependant, si vous utilisez traceback.print_exc () ci-dessous, vous pouvez omettre l'acquisition de variable de sys.exc_info (), et vous pouvez également afficher le type et le contenu, ce qui est pratique. En gros, vous pouvez l'utiliser.
import sys
import traceback
def somework():
try:
print a #Utiliser des variables non définies
except Exception:
print "error"
traceback.print_exc(file=sys.stdout)
finally:
print "the end"
if __name__ == '__main__':
somework()
Résultat de sortie Le nom du module, la ligne, le nom de la fonction, l'instruction de cause et le message d'erreur de cause sont affichés.
error
Traceback (most recent call last):
File "/Users/test.py", line 8, in somework
print a
NameError: global name 'a' is not defined
the end
Il s'agit de la sortie lorsque la traceback n'est pas écrite. Rien n'est sorti, juste en passant l'exception.
error
the end
Ensuite, une méthode d'acquisition des informations de trace de pile sous forme de liste comprenant des taples est présentée. Voici également un exemple d'obtention d'une variable depuis sys.exc_info (). (Parce qu'il est utilisé comme argument)
import sys
import traceback
def somework():
try:
print a #Utiliser des variables non définies
except Exception:
print "error"
exc_type, exc_value, exc_traceback = sys.exc_info()
print traceback.extract_tb(exc_traceback) #Obtenez uniquement des informations actuelles
print traceback.extract_stack() #Obtenez une touche contenant les informations de fonction de l'appelant
#Appelez-le si vous voulez simplement le recevoir dans une liste au lieu d'un tap et le rendre plus facile à afficher.
traceback.format_tb(exc_traceback)
traceback.format_stack()
print "the end"
if __name__ == '__main__':
somework()
nosetest
J'ai fait référence à la «programmation professionnelle Python».
installation du nez
pip install nose
Classe à tester Cette classe ajoute ou soustrait simplement des nombres à votre compte bancaire.
# coding: UTF-8
class NotEnoughFundsException(Exception):
pass
class BankAccount(object):
def __init__(self):
self._balance = 0
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
self.balance -= amount
def get_balance(self):
return self._balance
def set_balance(self, value):
if value < 0:
raise NotEnoughFundsException
self._balance = value
#Préparez un emballage pour pouvoir utiliser des getters et des setters.
#équilibrer=Ou+Ces fonctions seront appelées automatiquement en accédant avec.
balance = property(get_balance, set_balance)
Écrivez du code pour tester avec le nez. Ici, la préparation d'une valeur fixe pour un test telle que 100 ou 0 est appelée un appareil de données.
# coding: UTF-8
import unittest
class BankAccountTest(unittest.TestCase):
def _getTarget(self):
from bankaccount import BankAccount
return BankAccount
#Créez une instance à tester.
def _makeOne(self, *args, **kwargs):
return self._getTarget()(*args, **kwargs)
def test_construct(self):
target = self._makeOne()
self.assertEqual(target._balance, 0)
def test_deposit(self):
target = self._makeOne()
target.deposit(100)
self.assertEqual(target._balance, 100)
def test_withdraw(self):
target = self._makeOne()
target._balance = 100
target.withdraw(20)
self.assertEqual(target._balance, 80)
def test_get_blance(self):
target = self._makeOne()
target._balance = 500
self.assertEqual(target.get_balance(), 500)
def test_set_balance_not_enough_funds(self):
target = self._makeOne()
from bankaccount import NotEnoughFundsException
try:
target.set_balance(-1)
self.fail()
except NotEnoughFundsException:
pass
Placez les deux ci-dessus dans le même répertoire et exécutez nose dans ce répertoire.
nosetest
.....
----------------------------------------------------------------------
Ran 5 tests in 0.004s
OK
pip install coverage
# nosetests -v --with-coverage
test_construct (test_bankaccount.BankAccountTest) ... ok
test_deposit (test_bankaccount.BankAccountTest) ... ok
test_get_blance (test_bankaccount.BankAccountTest) ... ok
test_set_balance_not_enough_funds (test_bankaccount.BankAccountTest) ... ok
test_withdraw (test_bankaccount.BankAccountTest) ... ok
Name Stmts Miss Cover Missing
-------------------------------------------
bankaccount 16 0 100%
----------------------------------------------------------------------
Ran 5 tests in 0.006s
OK
Une couverture facile à lire est sortie.
Sortie au format XUNIT avec l'option "--with-xunit".
# nosetests -v -w . --with-coverage --with-xunit
test_construct (test_bankaccount.BankAccountTest) ... ok
test_deposit (test_bankaccount.BankAccountTest) ... ok
test_get_blance (test_bankaccount.BankAccountTest) ... ok
test_set_balance_not_enough_funds (test_bankaccount.BankAccountTest) ... ok
test_withdraw (test_bankaccount.BankAccountTest) ... ok
----------------------------------------------------------------------
XML: nosetests.xml
Name Stmts Miss Cover Missing
-------------------------------------------
bankaccount 16 0 100%
----------------------------------------------------------------------
Ran 5 tests in 0.006s
OK
Sortie en XML pour qu'il puisse être lu par jenkins.
coverage xml
mock
Classe à tester testモジュールのTest.py
# coding: UTF-8
class Widget(object):
def __init__(self):
self.value = 10
def Additional(self, add):
self.value += add
return self.value
Code de test
from mock import Mock
from test import Test
def mock_value(value):
return 20 + value
if __name__ == '__main__':
#Remplacez la fonction par une simulation qui renvoie 100 de manière fixe.
Test.Widget.Additional = Mock(return_value=100)
w = Test.Widget()
print w.Additional(1)
#Si vous voulez faire un calcul au lieu d'une valeur fixe, côté_Passez une fonction factice en vigueur.
Test.Widget.Additional = Mock(side_effect=mock_value)
print w.Additional(1)
100
21
from mock import Mock
from test import Test
def mock_value(value):
return 20 + value
if __name__ == '__main__':
#Remplacez la classe elle-même.
Test.Widget = Mock()
#La valeur renvoyée par la fonction est fixe.
Test.Widget.return_value.Additional.return_value = 10
w = Test.Widget()
print w.Additional(1)
#Fonctions d'échange
Test.Widget.return_value.Additional = mock_value
print w.Additional(1)
patch Remplacez l'objet fictif dans lequel la fonction s'exécute par l'objet réel.
# coding: UTF-8
from mock import patch
#Spécifiez la méthode et la valeur de retour à remplacer uniquement pendant l'exécution de cette fonction
@patch("Test.Widget.Additional", return_value=10)
def test_func(m):
import Test
w = Test.Widget()
print w.Additional(1)
assert w.Additional(1) == 10
#Au fait, m reçu comme argument est une fonction supplémentaire remplacée par un simulacre.
#Ici aussi, le résultat est 10.
#Cette fois j'ai remplacé la méthode, mais dans le cas d'une classe, elle devient une classe.
print m()
if __name__ == '__main__':
test_func()
# coding: UTF-8
from mock import patch
def test_func():
#Spécifiez la méthode et la valeur de retour à remplacer uniquement pendant l'exécution de la portée
with patch("Test.Widget.Additional", return_value=10) as m:
import Test
w = Test.Widget()
print w.Additional(1)
assert w.Additional(1) == 10
print m()
if __name__ == '__main__':
test_func()
mock = Mock(spec=SomeClass)
isinstance(mock, SomeClass) #Cela réussit
# coding: UTF-8
from mock import Mock, patch
if __name__ == '__main__':
#Une méthode qui renvoie 3 avec la méthode name,
#Une méthode qui déclenche une exception KeyError avec le nom autre
attrs = {'method.return_value': 3, 'other.side_effect': KeyError}
#Vous pouvez ajouter des attributs en même temps que déclarer(some_attribute)。
mock = Mock(some_attribute='eggs', **attrs)
print mock.some_attribute
print mock.method()
print mock.other()
Une autre chose qui semble utile
@patch('sys.stdout', new_callable=StringIO)
Ainsi, il sera créé en tant qu'objet StringIO au moment de la création.
Vous pouvez écrire une pseudo-classe pour le test et l'assigner avec "Test.Widget =" sans utiliser mock. Si vous n'utilisez pas la fonction de validation de simulation, cette méthode peut être plus rapide.
Très utile pour tester Django.
pip install webtest
pip install django-webtest
L'application Django ressemble à ceci:
mysite
|-mysite
| |-__init__.py
| |-settings.py
| |-urls.py
| |-wsgi.py
|-test app
| |-__init__.py
| |-form.py
| |-modes.py
| |-views.py
| |-tests.py Ecrivez ce test dans ce fichier|
|-templates
|-manage.py
Écrivez le contenu de tests.py comme suit
from django_webtest import WebTest
class TestIndex(WebTest):
def test_index(self):
res = self.app.get("/") #Obtenez la réponse
#Vérifiez le code d'état et le contenu.
assert res.status == '200 OK'
assert 'html' in res
Démarrez le serveur de développement avec manage.py runserver, puis exécutez le test avec la commande suivante.
# sudo python manage.py test testapp
Résultat de sortie
Creating test database for alias 'default'...
.
----------------------------------------------------------------------
Ran 1 test in 0.175s
OK
Destroying test database for alias 'default'...
Recommended Posts