Testare cu pytest ================= ----- Testare cu pytest ================= .. class:: center | | | **Ionel Cristian Mărieș** — **Python** / **OSS** .. epigraph:: `blog.ionelmc.ro `_ `github.com/ionelmc `_ .footer: `RoPython Meetup `_ — generat cu `Darkslide `_ Presenter Notes --------------- * Mi s-a pus pata pe pytest * Sondaj! ----- Un pic de istorie ================= * Am folosit Nose și unittest/unittest2, dar au tot felul de lacune (explicații pe parcurs) * Nose a pornit de la o versiune antica de pytest (0.8) [1]_ * Pytest s-a schimbat mult, merită revăzut dacă te-ai uitat la el acu câțiva ani. .. [1] http://pytest.org/latest/faq.html#what-s-this-magic-with-pytest-historic-notes ----- Ce e așa special la pytest? =========================== * Testele sunt scrise și organizate diferit: * Teste doar cu simple funcții și aserții * Fixtures, markers, hooks * Multe facilități builtin (care există ca și plugin-uri în Nose) * Suportă teste scrise în stil vechi, cu nose (suport partial) și unittest ----- Funcții simple în loc de metode și clase ======================================== În loc de: .. sourcecode:: python class MyTest(unittest.TestCase): def test_stuff(self): ... Avem doar: .. sourcecode:: python def test_stuff(self): ... ----- Aserții simple ============== În loc de: .. sourcecode:: python self.assertIarăAmUitatCumÎiZice(variabilă) # și mesaju de eroare Putem avea ceva de genul: .. sourcecode:: python def test_assert(): var = [1, 2, 4] assert var == [1, 2, 4] ----- Inspecție aserții ================= .. sourcecode:: python def test_assert(): var = [1, 2, 4] assert var == [1, 2, 4] :: ============================== FAILURES =============================== _____________________________ test_assert _____________________________ tests\test_assert.py:6: in test_assert assert var == [1, 2, 3] E assert [1, 2, 4] == [1, 2, 3] E At index 2 diff: 4 != 3 E Full diff: E - [1, 2, 4] E ? ^ E + [1, 2, 3] E ? ^ ----- Inspecție aserții (2) ===================== .. sourcecode:: python def test_assert_2(): with open("qr.svg") as fh: assert fh.readlines() == ["foobar"] :: ============================== FAILURES =============================== ____________________________ test_assert_2 ____________________________ tests\test_assert.py:17: in test_assert_2 assert fh.readlines() == ["foobar"] E assert ["'] == ['foobar'] E At index 0 diff: "\n" != 'f E Left contains more items, first extra item: '' E Full diff: E + ['foobar'] E - ["\n", E - '`_ - coverage * `pytest-benchmark `_ - benchmarks * `pytest-xdist `_ - rulare teste in paralel * `pytest-django `_ - testare aplicații Django * `pytest-capturelog `_ - captura logging * `pytest-splinter `_ - testare cu Splinter (teste UI cu webdriver Chrome/Firefox sau PhantomJS) ----- pytest-splinter cu pytest-django ================================ Splinter poate folosi Selenium și alte backend-uri (PhantomJS). Exemplu: .. sourcecode:: python def test_login(browser, db, live_server): User.objects.create_superuser('user', email='user@example.com', password='abc') browser.visit(live_server.url) form = browser.find_by_tag('form') form.find_by_name('username').fill('user') form.find_by_name('password').fill('abc') form.find_by_css('input[type=submit]').click() assert 'success' in browser.html ----- Link prezentare =============== .qr: https\://blog.ionelmc.ro/presentations/pytest/