meetup python nantes - les tests en python
Post on 11-Feb-2017
170 Views
Preview:
TRANSCRIPT
PythonMeetupoctobre2016lestestsenpython
IntroductionMeetupPythonNantes-mai2016
( ) ArthurLutz Logilab @arthurlutz @logilab
Planintroductionauxtestsunittaireslancerlestests:unittestdebase,py.test,nose,pytest,etc.toxpourlancerlestestdansdesvirtualenvsl'intégrationcontinueavecpython(jenkins,travis,etc.)lestestsenprod:healthchecksaucœurdel'application
introductionauxtestsunitaires
TDD-testdrivendeveloppement-dévelopementpilotéparlestests
testunitaire
passerdesprintsetvérificationhumaineàunpointOK/notOKdocumenterdesexemplesd'usagedesoncode
https://en.wikipedia.org/wiki/Test-driven_developmenthttps://fr.wikipedia.org/wiki/Test_driven_development
https://fr.wikipedia.org/wiki/Test_unitaire
Enpythonmoduleunittest
nepasutiliserassert(assertTrueàlaplace)
https://docs.python.org/3.5/library/unittest.htmlassertEqual(a,b)assertNotEqual(a,b)assertTrue(x)assertFalse(x)
Écrireuntestclasseshéritantdeunittest.TestCasetouteslesmethodescommencantpartestsontconsidéréescommeuntestunittaire
Exemple(deladoc)importunittest
classTestStringMethods(unittest.TestCase):
deftest_upper(self):self.assertEqual('foo'.upper(),'FOO')
deftest_isupper(self):self.assertTrue('FOO'.isupper())self.assertFalse('Foo'.isupper())
deftest_split(self):s='helloworld'self.assertEqual(s.split(),['hello','world'])#checkthats.splitfailswhentheseparatorisnotastringwithself.assertRaises(TypeError):s.split(2)
if__name__=='__main__':unittest.main()
Avant/aprèslestests
defsetUp()deftearDown()setUpClassettearDownClasssetup_methodetteardown_methodsetup_functionetteardown_function
https://en.wikipedia.org/wiki/Test_fixture#Software
Extensionscouverturesdetests(pycoverage,python-coverage,etc.)linters(pychecker,pylint,flake8,etc.)doctestshttps://docs.python.org/2/library/doctest.htmlhttps://en.wikipedia.org/wiki/Fuzz_testing
Mockmockornottomock(orwheretomock?)
unittest.mock:
https://en.wikipedia.org/wiki/Mock_object
https://docs.python.org/3/library/unittest.mock.html
>>>fromunittest.mockimportMagicMock>>>thing=ProductionClass()>>>thing.method=MagicMock(return_value=3)>>>thing.method(3,4,5,key='value')3>>>thing.method.assert_called_with(3,4,5,key='value')
Mockencoredecorator@patchcontextmanagerwithPatch...quelquesexemplesd'assertions
assert_called_withassert_called_once_withassert_any_callassert_has_callsassert_not_calledreset_mock
Nepasmockerpostgresqlàlademande:Pythonfixturesanddaemonmanagingtoolsforfunctionaltesting:
http://faitout.fedorainfracloud.org/
https://github.com/jd/pifpaf
platformspecific1/2django
cubicweb-populateDB
testwithreallivedatabase
https://docs.djangoproject.com/en/1.10/topics/testing/https://factoryboy.readthedocs.io/en/latest/
https://docs.cubicweb.org/book/devrepo/testing.html
https://docs.cubicweb.org/book/devrepo/testing.html#testing-on-a-real-life-database
platformspecific2/2saltfromsalttestingimportTestCase
infrastructure:testinfra:
https://docs.saltstack.com/en/latest/topics/development/tests/unit.html
http://testinfra.readthedocs.io/en/latest/
Seleniumhttp://www.seleniumhq.org/https://github.com/SeleniumHQ/selenium/tree/master/py
pipinstallselenium
Seleniumexempleimportunittestfromseleniumimportwebdriver
classAfpyTestCase(unittest.TestCase):
defsetUp(self):self.browser=webdriver.Firefox()self.addCleanup(self.browser.quit)
deftestPageTitle(self):self.browser.get('http://nantes.afpy.org/')self.assertIn('Python-Nantes',self.browser.title)
if__name__=='__main__':unittest.main(verbosity=2)
lancerlestests
unittestdebaseunit2pytest(logilab-common)py.test(nextpytest)nose&nose2etc
https://wiki.python.org/moin/PythonTestingToolsTaxonomy
unittest.mainEnbasdechaquefichierpython:
Pourlelancer:
if__name__=='__main__':unittest.main()
#pythontest_this.py
pytest(logilab-common)historique
testlib-extensiondeunittestpytest-lanceurdetestsselectiontagsavecdesdecorateurs(tags)suppriméauprofitdenouveauxprojets
unit2unittest2estunbackportpython2dunouveauunittestpython3
unit2==python-munittest2unit2discover
py.test
py.test(bientôtpytest)http://docs.pytest.org/en/latest/
$pipinstallpytest
py.testpy.testpy.test-x:s'arrêteàlapremièreerreurpy.test--maxfail=3:s'arrêteauboutde3erreurs
py.testselectionpy.testtest_module.pypy.testtest_mod.py::test_funcpy.testtest_mod.py::TestClass::test_method
py.testaffichagepy.test--tb=long#thedefaultinformativetracebackformattingpy.test--tb=native#thePythonstandardlibraryformattingpy.test--tb=short#ashortertracebackformatpy.test--tb=line#onlyonelineperfailure
py.testavancémarkersfixturesparametrisationpy.test--fixturespluginspipsearchpytest(ouapt-cachesearchpytest)
http://docs.pytest.org/en/latest/mark.htmlhttp://docs.pytest.org/en/latest/fixture.html
http://docs.pytest.org/en/latest/parametrize.html
nose&nose2
Commandes:
nosetestsnose2
https://nose.readthedocs.io/en/latest/https://github.com/nose-devs/nose2
toxpourlancerlestestdansdesvirtualenvshttps://tox.readthedocs.io/en/latest/
#contentof:tox.ini,putinsamedirassetup.py[tox]envlist=py26,py27[testenv]deps=pytest#installpytestinthevenvscommands=py.test#or'nosetests'or...
toxestamourSlides:Vidéo:
http://tox.jehaisleprintemps.net/#/http://video-pyconfr2015.paulla.asso.fr/108_-
_Bruno_Bord_-_tox_est_amour.html
Accélerertox:cachesserverpypilocal:dansdocker(avecapt-cacher-ngetsquid)
http://doc.devpi.net/latest/
https://github.com/ebar0n/proxy-cache
L'intégrationcontinueavecpython
(monopoleavecgithub?)
(testssouswindows)etc.
hudsonjenkinsapycottravisbitbucketpipelinesdrone.ioappveyor
JenkinsPythonPlugin:
ShiningPanda:
https://wiki.jenkins-ci.org/display/JENKINS/Python+Plugin
https://wiki.jenkins-ci.org/display/JENKINS/ShiningPanda+Plugin
MatrixProjectMatrixProjectpourplusieursenvironnements:
jenkins-job-builder(descriptiondevosprojetsenYAML):https://wiki.jenkins-ci.org/display/JENKINS/Matrix+Project+Plugin
http://docs.openstack.org/infra/jenkins-job-builder/project_matrix.html
Junit/xUnitfichiersXMLdedescriptiondestestsréussisounon
ilexisteaussidesformatsxmlpourlacouverturedetests(Corbetura,etc.)
https://en.wikipedia.org/wiki/XUnit
Quandlancerlestests?Surchaquepullrequest?surchaquetêteavantunpush?avantuncommit?surl'ensemble?surquelsous-ensemble?
lestestsenprod:healthchecksaucœurde
l'application
Inspirationspyconfr2015:BenoitBryon,Peopledoc
KelseyHightower-healthz:Stopreverseengineeringapplicationsandstartmonitoringfromtheinside
Vidéo:Code:
https://blog.notmyidea.org/pyconfr-2015-hospital-des-tests-en-prod.html
https://vimeo.com/173610242https://github.com/kelseyhightower/app-healthz
healthchecks-principelancerdestestsdirectementaucoeurdel'applicationenproductioncomplémentdelasupervisiontraditionnellepermetdedifférentierentre"leprocesstourne"et"leservicerépond"
particulièrementutilepourledéploiementcontinueetlarépartissiondechargedynamique
healthchecksenpythonhttps://github.com/python-hospital/hospitalhttps://github.com/danielfrg/django-hospitalhttps://github.com/healthchecks/healthcheckshttps://github.com/ludia/pyramid_health
FinDesquestions?Desajouts?Présentation:Contact:
http://slides.logilab.fr/2016/meetup_python_nantes_tests/@arthurlutz @logilab
top related