SlideShare a Scribd company logo
Multiply your Testing
Effectiveness with
Parameterized Testing
Brian Okken
The Immense Value of
Automated Tests
and
How to Avoid Writing Them
Alternate title
Brian Okken
Brian Okken
weekly Python podcasts A book
I work here
new meetup there, Python PDX West Oct 8, 6 pm
Python-PDX-West
Outline
• A development workflow
• which includes a build pipeline
• which includes tests
• that I don’t want to spend too much time writing
• so most of my test cases use parametrization*
*one of many techniques I use to avoid writing tests
Target Workflow
Time
main
dev / fix / feature
branches
Merge Request /
Pipeline Runs
Drawing elements: Vincent Driessen
License: Creative Commons
Merge Request /
Pipeline Runs
• Branch off main
• Solo or collaborating
• Tests and code merge together
• Pipeline does magic
Developer Workflow
• Write some code & some tests.
• Commit code regularly
• Merge Request / Pull Request
• Pipeline does most of the work, build, test, etc.
• Reviewers get notified.
• Reviewers think my code is awesome & accept it.
• Merge finishes
• Fist bumps, high fives, etc.
• Repeat
After merge, I know
• I didn't break anything that used to work.
• New features are tested with new tests.
• Future changes won’t break current features.
• Team understands code and tests.
• The code is ready for users.
• I can refactor my code if I'm not proud of it and
know the tests will make sure everything is ok.
Reviewer knows,
before the review
✓ Static analysis
✓ Style guide checks
✓ Code coverage has not dropped.
✓ Tests all pass
✓ Legacy functionality working.
✓ New tests pass.
Reviewer Focus
• Just the code + test for this feature.
• Do I understand the code and the tests?
• Enough to maintain it if the original dev is on vacation?
• Are the tests sufficient for the new functionality?
Team Lead / Manager View
• Awesome code keeps popping out
• The tests have our backs.
• We’re moving fast.
• Big refactoring/rewrites are low risk.
• I can understand the tests.
• Maybe even write some tests myself.
Tests in a Pipeline
• fail fast
• negative feedback as fast as possible
• feeds into a deploy stage, maybe
smoke
tests
longer
running
tests
quick but
thorough
new tests
static
analysis
13
Tests to support this
• Customer focused
• Developer focused
• Feature / functionality focused
• Risk focused
• Complete but not crazy complete
• Have to be readable, fast to write, easy to maintain
Parametrization
• Many test cases with one test function.
• pytest has a few strategies for this.
• function parametrization
• fixture parametrization
• a hook function: pytest_generate_tests()
17
cards
$ cards
ID owner done summary
---- ------- ------ ————
$ cards add prepare for talk
$ cards add give talk
$ cards
ID owner done summary
---- ------- ------ ----------------
1 prepare for talk
2 give talk
$ cards update -o okken 1
$ cards update -o okken 2
$ cards finish 1
$ cards
ID owner done summary
---- ------- ------ ----------------
1 okken x prepare for talk
2 okken give talk
a test
import cards
from cards import Card
def test_add(tmp_path):
cards.set_db_path(tmp_path)
cards.connect()
a_card = Card('first task', 'brian', False)
id = cards.add_card(a_card)
c2 = cards.get_card(id)
cards.disconnect()
assert a_card == c2
push setup/teardown
into fixtures
@pytest.fixture(scope='session')
def db(tmp_path_factory):
d = tmp_path_factory.mktemp('cards_db')
cards.set_db_path(d)
cards.connect()
yield
cards.disconnect()
@pytest.fixture(scope='function')
def empty_db(db):
cards.delete_all()
def test_add(empty_db):
a_card = Card('first task', 'brian')
id = cards.add_card(a_card)
c2 = cards.get_card(id)
assert a_card == c2
so we can focus on this test
def test_add(empty_db):
a_card = Card('first task', 'brian', False)
id = cards.add_card(a_card)
c2 = cards.get_card(id)
assert a_card == c2
so we can focus on this test
def test_add(empty_db):
a_card = Card('first task', 'brian', False)
id = cards.add_card(a_card)
c2 = cards.get_card(id)
assert a_card == c2
@dataclass
class Card:
summary: str = None
owner: str = None
done: bool = None
id: int = field(default=None, compare=False)
But what about all
the other kinds of cards?
Parametrization !!!
@pytest.mark.parametrize('a_card', [
Card('first task', 'brian', False),
Card(),
Card(summary='do something'),
Card(owner='brian'),
Card(done=True)],ids=repr)
def test_add(empty_db, a_card):
id = cards.add_card(a_card)
c2 = cards.get_card(id)
assert a_card == c2
function parametrization
@pytest.fixture(params=[
Card('first task', 'brian', False),
Card(),
Card(summary='do something'),
Card(owner='brian'),
Card(done=True)], ids=repr)
def a_card(request):
return request.param
def test_add(empty_db, a_card):
id = cards.add_card(a_card)
c2 = cards.get_card(id)
assert a_card == c2
fixture parametrization
def pytest_generate_tests(metafunc):
if "a_card" in metafunc.fixturenames:
metafunc.parametrize("a_card", [
Card('first task', 'brian', False),
Card(),
Card(summary='do something'),
Card(owner='brian'),
Card(done=True)], ids = repr)
def test_add(empty_db, a_card):
id = cards.add_card(a_card)
c2 = cards.get_card(id)
assert a_card == c2
pytest_generate_tests
Multiply your Testing Effectiveness with Parameterized Testing, v1
Thank You
• twitter: @brianokken
• book: Python Testing with pytest
• pragprog.com/book/bopytest/python-testing-with-pytest
• also: pytestbook.com
• podcasts
• testandcode.com
• pythonbytes.fm
• https://www.me
• meetup
• meetup.com/Python-PDX-West/
• First one: Tuesday, Oct 8, Hillsboro

More Related Content

PDF
Solaris Kernel Debugging V1.0
ODP
Linux Capabilities - eng - v2.1.5, compact
PDF
David container security-with_falco
PPTX
Patching: answers to questions you probably were afraid to ask about oracle s...
KEY
Active Web Development
ODP
DiUS Computing Lca Rails Final
PDF
Deploying Prometheus stacks with Juju
PDF
Performance Wins with eBPF: Getting Started (2021)
Solaris Kernel Debugging V1.0
Linux Capabilities - eng - v2.1.5, compact
David container security-with_falco
Patching: answers to questions you probably were afraid to ask about oracle s...
Active Web Development
DiUS Computing Lca Rails Final
Deploying Prometheus stacks with Juju
Performance Wins with eBPF: Getting Started (2021)

What's hot (20)

PDF
YOW2020 Linux Systems Performance
PDF
BPF Internals (eBPF)
PDF
Tuning parallelcodeonsolaris005
ODP
Linux kernel tracing superpowers in the cloud
PDF
Linux kernel-rootkit-dev - Wonokaerun
PDF
LSFMM 2019 BPF Observability
PDF
LPC2019 BPF Tracing Tools
PDF
Performance Wins with BPF: Getting Started
PDF
Kernel development
PDF
eBPF Trace from Kernel to Userspace
PDF
bcc/BPF tools - Strategy, current tools, future challenges
PPT
Troubleshooting Linux Kernel Modules And Device Drivers
PDF
Linux Performance Tools 2014
PDF
Spying on the Linux kernel for fun and profit
PDF
Security Monitoring with eBPF
PDF
Trace kernel code tips
PDF
UM2019 Extended BPF: A New Type of Software
PDF
re:Invent 2019 BPF Performance Analysis at Netflix
PDF
Linux 4.x Tracing: Performance Analysis with bcc/BPF
PDF
Low Overhead System Tracing with eBPF
YOW2020 Linux Systems Performance
BPF Internals (eBPF)
Tuning parallelcodeonsolaris005
Linux kernel tracing superpowers in the cloud
Linux kernel-rootkit-dev - Wonokaerun
LSFMM 2019 BPF Observability
LPC2019 BPF Tracing Tools
Performance Wins with BPF: Getting Started
Kernel development
eBPF Trace from Kernel to Userspace
bcc/BPF tools - Strategy, current tools, future challenges
Troubleshooting Linux Kernel Modules And Device Drivers
Linux Performance Tools 2014
Spying on the Linux kernel for fun and profit
Security Monitoring with eBPF
Trace kernel code tips
UM2019 Extended BPF: A New Type of Software
re:Invent 2019 BPF Performance Analysis at Netflix
Linux 4.x Tracing: Performance Analysis with bcc/BPF
Low Overhead System Tracing with eBPF
Ad

Similar to Multiply your Testing Effectiveness with Parameterized Testing, v1 (20)

PDF
Effective testing with pytest
PDF
10 ways to shoot yourself in the foot with tests - Shai Geva, PyCon IL, 2024
PDF
Py.test
PPTX
10 ways to shoot yourself in the foot with tests - Shai Geva, PyConUS 2023
PDF
Parametrized testing, v2
PDF
PyCon JP 2024 Streamlining Testing in a Large Python Codebase .pdf
PDF
Model-Driven Testing For Agile Teams
PDF
EuroPython 2024 - Streamlining Testing in a Large Python Codebase
PDF
Oleksii Moskalenko "Continuous Delivery of ML Pipelines to Production"
PDF
Continuous Security Testing
PDF
Plone Conference 2007: Acceptance Testing In Plone Using Funittest - Maik Röder
PPTX
Upstate CSCI 540 Unit testing
PDF
Software Testing:
 A Research Travelogue 
(2000–2014)
PDF
Improving the accuracy and reliability of data analysis code
KEY
ATDD in Practice
PDF
Best Practices for Selenium Test Automation in Python
PPTX
Agile testingandautomation
PPTX
Testing Sap: Modern Methodology
PDF
Unit Testing in Python
PPTX
Agile vs. DevOps for Continuous Testing: How to Optimize Your Pipeline
Effective testing with pytest
10 ways to shoot yourself in the foot with tests - Shai Geva, PyCon IL, 2024
Py.test
10 ways to shoot yourself in the foot with tests - Shai Geva, PyConUS 2023
Parametrized testing, v2
PyCon JP 2024 Streamlining Testing in a Large Python Codebase .pdf
Model-Driven Testing For Agile Teams
EuroPython 2024 - Streamlining Testing in a Large Python Codebase
Oleksii Moskalenko "Continuous Delivery of ML Pipelines to Production"
Continuous Security Testing
Plone Conference 2007: Acceptance Testing In Plone Using Funittest - Maik Röder
Upstate CSCI 540 Unit testing
Software Testing:
 A Research Travelogue 
(2000–2014)
Improving the accuracy and reliability of data analysis code
ATDD in Practice
Best Practices for Selenium Test Automation in Python
Agile testingandautomation
Testing Sap: Modern Methodology
Unit Testing in Python
Agile vs. DevOps for Continuous Testing: How to Optimize Your Pipeline
Ad

Recently uploaded (20)

PDF
Understanding Forklifts - TECH EHS Solution
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PPTX
history of c programming in notes for students .pptx
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
top salesforce developer skills in 2025.pdf
PPTX
Introduction to Artificial Intelligence
PDF
Digital Strategies for Manufacturing Companies
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
Odoo POS Development Services by CandidRoot Solutions
PPTX
Reimagine Home Health with the Power of Agentic AI​
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PPTX
Essential Infomation Tech presentation.pptx
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
System and Network Administraation Chapter 3
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Understanding Forklifts - TECH EHS Solution
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
history of c programming in notes for students .pptx
PTS Company Brochure 2025 (1).pdf.......
2025 Textile ERP Trends: SAP, Odoo & Oracle
top salesforce developer skills in 2025.pdf
Introduction to Artificial Intelligence
Digital Strategies for Manufacturing Companies
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Internet Downloader Manager (IDM) Crack 6.42 Build 41
How to Choose the Right IT Partner for Your Business in Malaysia
Odoo POS Development Services by CandidRoot Solutions
Reimagine Home Health with the Power of Agentic AI​
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Essential Infomation Tech presentation.pptx
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
System and Network Administraation Chapter 3
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025

Multiply your Testing Effectiveness with Parameterized Testing, v1

  • 1. Multiply your Testing Effectiveness with Parameterized Testing Brian Okken
  • 2. The Immense Value of Automated Tests and How to Avoid Writing Them Alternate title Brian Okken
  • 3. Brian Okken weekly Python podcasts A book I work here new meetup there, Python PDX West Oct 8, 6 pm Python-PDX-West
  • 4. Outline • A development workflow • which includes a build pipeline • which includes tests • that I don’t want to spend too much time writing • so most of my test cases use parametrization* *one of many techniques I use to avoid writing tests
  • 5. Target Workflow Time main dev / fix / feature branches Merge Request / Pipeline Runs Drawing elements: Vincent Driessen License: Creative Commons Merge Request / Pipeline Runs • Branch off main • Solo or collaborating • Tests and code merge together • Pipeline does magic
  • 6. Developer Workflow • Write some code & some tests. • Commit code regularly • Merge Request / Pull Request • Pipeline does most of the work, build, test, etc. • Reviewers get notified. • Reviewers think my code is awesome & accept it. • Merge finishes • Fist bumps, high fives, etc. • Repeat
  • 7. After merge, I know • I didn't break anything that used to work. • New features are tested with new tests. • Future changes won’t break current features. • Team understands code and tests. • The code is ready for users. • I can refactor my code if I'm not proud of it and know the tests will make sure everything is ok.
  • 8. Reviewer knows, before the review ✓ Static analysis ✓ Style guide checks ✓ Code coverage has not dropped. ✓ Tests all pass ✓ Legacy functionality working. ✓ New tests pass.
  • 9. Reviewer Focus • Just the code + test for this feature. • Do I understand the code and the tests? • Enough to maintain it if the original dev is on vacation? • Are the tests sufficient for the new functionality?
  • 10. Team Lead / Manager View • Awesome code keeps popping out • The tests have our backs. • We’re moving fast. • Big refactoring/rewrites are low risk. • I can understand the tests. • Maybe even write some tests myself.
  • 11. Tests in a Pipeline • fail fast • negative feedback as fast as possible • feeds into a deploy stage, maybe smoke tests longer running tests quick but thorough new tests static analysis 13
  • 12. Tests to support this • Customer focused • Developer focused • Feature / functionality focused • Risk focused • Complete but not crazy complete • Have to be readable, fast to write, easy to maintain
  • 13. Parametrization • Many test cases with one test function. • pytest has a few strategies for this. • function parametrization • fixture parametrization • a hook function: pytest_generate_tests() 17
  • 14. cards $ cards ID owner done summary ---- ------- ------ ———— $ cards add prepare for talk $ cards add give talk $ cards ID owner done summary ---- ------- ------ ---------------- 1 prepare for talk 2 give talk $ cards update -o okken 1 $ cards update -o okken 2 $ cards finish 1 $ cards ID owner done summary ---- ------- ------ ---------------- 1 okken x prepare for talk 2 okken give talk
  • 15. a test import cards from cards import Card def test_add(tmp_path): cards.set_db_path(tmp_path) cards.connect() a_card = Card('first task', 'brian', False) id = cards.add_card(a_card) c2 = cards.get_card(id) cards.disconnect() assert a_card == c2
  • 16. push setup/teardown into fixtures @pytest.fixture(scope='session') def db(tmp_path_factory): d = tmp_path_factory.mktemp('cards_db') cards.set_db_path(d) cards.connect() yield cards.disconnect() @pytest.fixture(scope='function') def empty_db(db): cards.delete_all() def test_add(empty_db): a_card = Card('first task', 'brian') id = cards.add_card(a_card) c2 = cards.get_card(id) assert a_card == c2
  • 17. so we can focus on this test def test_add(empty_db): a_card = Card('first task', 'brian', False) id = cards.add_card(a_card) c2 = cards.get_card(id) assert a_card == c2
  • 18. so we can focus on this test def test_add(empty_db): a_card = Card('first task', 'brian', False) id = cards.add_card(a_card) c2 = cards.get_card(id) assert a_card == c2 @dataclass class Card: summary: str = None owner: str = None done: bool = None id: int = field(default=None, compare=False) But what about all the other kinds of cards?
  • 20. @pytest.mark.parametrize('a_card', [ Card('first task', 'brian', False), Card(), Card(summary='do something'), Card(owner='brian'), Card(done=True)],ids=repr) def test_add(empty_db, a_card): id = cards.add_card(a_card) c2 = cards.get_card(id) assert a_card == c2 function parametrization
  • 21. @pytest.fixture(params=[ Card('first task', 'brian', False), Card(), Card(summary='do something'), Card(owner='brian'), Card(done=True)], ids=repr) def a_card(request): return request.param def test_add(empty_db, a_card): id = cards.add_card(a_card) c2 = cards.get_card(id) assert a_card == c2 fixture parametrization
  • 22. def pytest_generate_tests(metafunc): if "a_card" in metafunc.fixturenames: metafunc.parametrize("a_card", [ Card('first task', 'brian', False), Card(), Card(summary='do something'), Card(owner='brian'), Card(done=True)], ids = repr) def test_add(empty_db, a_card): id = cards.add_card(a_card) c2 = cards.get_card(id) assert a_card == c2 pytest_generate_tests
  • 24. Thank You • twitter: @brianokken • book: Python Testing with pytest • pragprog.com/book/bopytest/python-testing-with-pytest • also: pytestbook.com • podcasts • testandcode.com • pythonbytes.fm • https://www.me • meetup • meetup.com/Python-PDX-West/ • First one: Tuesday, Oct 8, Hillsboro