SlideShare a Scribd company logo
Testare cu pytest
Testare cu pytest
Ionel Cristian Mărieș — Python / OSS
blog.ionelmc.ro
github.com/ionelmc
Un pic de istorie
Am folosit Nose și uni昊est/uni昊est2, 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] h昊p://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 uni昊est
Funcții simple în loc de metode și clase
În loc de:
class MyTest(unittest.TestCase):
    def test_stuff(self):
        ...
Avem doar:
def test_stuff(self):
    ...
Aserții simple
În loc de:
self.assertIarăAmUitatCumÎiZice(variabilă)  # și mesaju de eroare
Putem avea ceva de genul:
def test_assert():
    var = [1, 2, 4]
    assert var == [1, 2, 4]
Inspecție aserții
def test_assert():
    var = [1, 2, 4]
    assert var == [1, 2, 4]
============================== FAILURES ===============================
_____________________________ test_assert _____________________________
teststest_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﴿
def test_assert_2():
    with open("qr.svg") as fh:
        assert fh.readlines() == ["foobar"]
============================== FAILURES ===============================
____________________________ test_assert_2 ____________________________
teststest_assert.py:17: in test_assert_2
    assert fh.readlines() == ["foobar"]
E   assert ["<?xml versi...ne" /></svg>'] == ['foobar']
E     At index 0 diff: "<?xml version='1.0' encoding='UTF‐8'?>n" != 'f
E     Left contains more items, first extra item: '<svg height="37mm" v
="fill:#000000;fill‐opacity:1;fill‐rule:nonzero;stroke:none" /></svg>'
E     Full diff:
E     + ['foobar']
E     ‐ ["<?xml version='1.0' encoding='UTF‐8'?>n",
E     ‐  '<svg height="37mm" version="1.1" viewBox="0 0 37 37" width="3
E     ‐  'xmlns="http://www.w3.org/2000/svg"><path d="M 10 32 L 10 33 L
E     ‐  '32 z M 23 8 L 23 9 L 24 9 L 24 8 z M 21 24 L 21 25 L 22 25 L
E     ‐  '23 L 26 24 L 27 24 L 27 23 z M 27 30 L 27 31 L 28 31 L 28 30
...
Fixturi [1]
În loc de  setUp  și  tearDown  sau pentru orice fel de dependință
Injecție automata („dependency injection”)
Și nu, ʺfixtureʺ nu înseamnă ce înseamnă în Django („data fixtures”)
Exemplu:
@pytest.fixture
def myfixture(request):
    return [1, 2, 3]
def test_fixture(myfixture):
    assert myfixture == [1, 2, 3]
[1] La țară mere, în zece ani o să fie în DEX ca și „adídas” (DEX ʹ09)
Fixturi ﴾finalizatoare﴿
Finalizatorul e echivalentul  tearDown  din  unittest .
Cel mai simplu e cu  pytest.yield_fixture :
@pytest.yield_fixture
def mydbfixture(request):
    conn = sqlite3.connect(":memory:")
    try:
        conn.execute("CREATE TABLE person "
                     "(id INTEGER PRIMARY KEY, name VARCHAR UNIQUE)")
        conn.execute("INSERT INTO person(name) VALUES (?)",
                     ("Gheorghe",))
        yield conn
    finally:
        # poate un DROP sau ceva ...
        conn.close()
def test_dbfixture(mydbfixture):
    assert list(mydbfixture.execute("select * from person")) == [
        (1, 'Gheorghe')]
Fixturi ﴾scope și autouse﴿
@pytest.yield_fixture(
    scope="function",
    autouse=False
)
def myfixture(request):
    ...
scope: „durata de viață” a fixturii
scope="function"  ‑ implicit, fixtura este apelată la fiecare funcție de test.
scope="module"  ‑ fixtura este apelată o singură dată per modul.
scope="session"  ‑ fixtura este apelată o singură dată (sesiunea de test doar una e).
autouse: activare automată
Dacă toate testele folosesc acelasi fixture, si nu au nevoie de rezultat  autouse  devine foarte
convenabil.
Fixturi în fixturi
O fixtură poate să depindă de alte fixturi. Reluând exemplul anterior:
@pytest.yield_fixture
def mydb(request):
    conn = sqlite3.connect(":memory:")
    try:
        conn.execute("CREATE TABLE person "
                     "(id INTEGER PRIMARY KEY, name VARCHAR UNIQUE)")
        yield conn
    finally:
        conn.close()
Fixturi în fixturi ﴾cont.﴿
@pytest.yield_fixture
def myfixture(request, mydb):
    try:
        mydb.execute("INSERT INTO person(name) VALUES (?)",
                     ("Gheorghe",))
        yield
    finally:
        mydb.execute("DELETE FROM person")
def test_fixture(mydb, myfixture):
    assert list(mydb.execute("select * from person")) == [
        (1, 'Gheorghe')]
Markers
Sunt niște simpli decoratori la funcțiile de test sau fixturi:
Etichete arbitare
Parametrizare:  pytest.mark.parametrize(argnames, argvalues)
Skip condițional:  pytest.mark.skipif(condition)
Fail „așteptat”: 
pytest.mark.xfail(condition, reason=None, run=True, raises=None)  [1]
[1] Când lenea e mare dar ești nostalgic și nu vrei să ștergi testul. Poate repari problema cândva!
Parametrizare
@pytest.mark.parametrize(['a', 'b'], [
    (1, 2),
    (2, 1),
])
def test_param(a, b):
    assert a + b == 3
collected 2 items
tests/test_param.py::test_param[1‐2] PASSED
tests/test_param.py::test_param[2‐1] PASSED
Parametrizare în fixturi
@pytest.fixture(params=[sum, len, max, min])
def func(request):
    return request.param
@pytest.mark.parametrize('numbers', [
    (1, 2),
    (2, 1),
])
def test_func(numbers, func):
    assert func(numbers)
tests/test_param.py::test_func[func0‐numbers0] PASSED
tests/test_param.py::test_func[func0‐numbers1] PASSED
tests/test_param.py::test_func[func1‐numbers0] PASSED
tests/test_param.py::test_func[func1‐numbers1] PASSED
tests/test_param.py::test_func[func2‐numbers0] PASSED
tests/test_param.py::test_func[func2‐numbers1] PASSED
tests/test_param.py::test_func[func3‐numbers0] PASSED
tests/test_param.py::test_func[func3‐numbers1] PASSED
Parametrizare cu etichete
@pytest.fixture(params=[sum, len, max, min],
                ids=['sum', 'len', 'max', 'min'])
def func(request):
    return request.param
@pytest.mark.parametrize('numbers', [
    (1, 2),
    (2, 1),
], ids=["alba", "neagra"])
def test_func(numbers, func):
    assert func(numbers)
tests/test_param.py::test_func[sum‐alba] PASSED
tests/test_param.py::test_func[sum‐neagra] PASSED
tests/test_param.py::test_func[len‐alba] PASSED
tests/test_param.py::test_func[len‐neagra] PASSED
tests/test_param.py::test_func[max‐alba] PASSED
tests/test_param.py::test_func[max‐neagra] PASSED
tests/test_param.py::test_func[min‐alba] PASSED
tests/test_param.py::test_func[min‐neagra] PASSED
Selecție parametrii
Putem selecta pe parametrii:
$ py.test ‐k alba ‐v
========================= test session starts =========================
platform win32 ‐‐ Python 3.4.3 ‐‐ py‐1.4.27 ‐‐ pytest‐2.7.1
collected 14 items
tests/test_param.py::test_func[sum‐alba] PASSED
tests/test_param.py::test_func[len‐alba] PASSED
tests/test_param.py::test_func[max‐alba] PASSED
tests/test_param.py::test_func[min‐alba] PASSED
=================== 10 tests deselected by '‐kalba' ===================
=============== 4 passed, 10 deselected in 0.06 seconds ===============
_______________________________ summary _______________________________
Hooks
Pentru customizarea framework‑ului de testare (pytest):
Plugins
Un fișier  conftest.py  („plugin local”)
Referință: h昊ps://pytest.org/latest/plugins.html#pytest‑hook‑reference
Se pot modifica multe lucruri: colectare, rulare, output (rapoarte, detalii aserții,
progres etc), opțiuni noi la linia de comandă.
Există plugin‑uri care au hook‑uri custom: pytest‑xdist, pytest‑bdd și probabil
altele.
Plugins
Foarte multe sunt „builtin”, cele mai interesante:
doctest
junitxml
monkeypatch  (fixtură pentru monkey‑patching)
recwarn  (fixtură pentru aserții la warnings)
tmpdir  (fixtură pentru fișiere temporare)
capture  (captură stdout/stderr)
Mai sunt multe alte pluginuri care defapt implementează nucleul pytest (colectare,
rulare, output etc).
Plugins ﴾PyPI﴿
Pluginuri externe:
pytest‑cov ‑ 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:
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
Testare cu pytest
Testare cu pytest

More Related Content

Featured

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot
Marius Sescu
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPT
Expeed Software
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
Pixeldarts
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
ThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
marketingartwork
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
Skeleton Technologies
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
Kurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
SpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Lily Ray
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
Rajiv Jayarajah, MAppComm, ACC
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
Christy Abraham Joy
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
Vit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
MindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
RachelPearson36
 

Featured (20)

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPT
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 

Testare cu pytest