SlideShare a Scribd company logo
1 of 18
Download to read offline
Source: , 2015
Technology and Friends, Episode 354
from application import cli
1
from cli_test_helpers import shell
2
3
def test_cli_entrypoint():
4
result = shell("python-summit --help")
5
assert result.exit_code == 0
6
1. What's wrong with scripts?
2. Coding example #1 (refactoring)
3. Why CLI applications?
4. Challenges with writing tests
5. Coding example #2 (cli & tests)
print("This is important code")
1
2
for index, arg in enumerate(sys.argv):
3
print(f"[{index}]: {arg}")
4
What's Wrong with Scripts?
Easy to get started
Limited possibilities for structure
Hard to (unit) test
No dependency management
Deployment may require care
Custom user experience
$ cowsay -e ~~ WHAT IS WRONG WITH SCRIPTS? | lolcat
_____________________________
< WHAT IS WRONG WITH SCRIPTS? >
-----------------------------
 ^__^
 (~~)_______
(__) )/
||----w |
|| ||
Coding Example #1
print("Usage: foo <bar> --baz")
def main():
1
2
3
if __name__ == "__main__":
4
main()
5
Why CLI Applications?
Standardized user experience
More possibilities for structure
Possibilities for all kinds of testing
Dependency management
Packaging & distribution
import argparse
from . import __version__
def parse_arguments():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--version', action='version',
version=__version__)
parser.add_argument('filename')
args = parser.parse_args()
return args
def main():
args = parse_arguments()
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Argparse
import click
@click.command()
@click.version_option()
@click.argument('filename')
def main(filename):
click.echo(filename)
1
2
3
4
5
6
7
Click
import click
@click.command()
@click.version_option()
@click.argument('filename', type=click.Path(exists=True))
def main(filename):
click.echo(filename)
1
2
3
4
5
6
7
import click
@click.command()
@click.version_option()
@click.argument('infile', type=click.File())
def main(infile):
click.echo(infile.read())
1
2
3
4
5
6
7
"""Foobar
Usage:
foobar (-h | --help | --version)
foobar [-s | --silent] <file>
foobar [-v | --verbose] <file>
Positional arguments:
file target file path name
Optional arguments:
-h, --help show this help message and exit
-s, --silent don't show progress output
-v, --verbose explain progress verbosely
--version show program's version number and exit
"""
from docopt import docopt
from . import __version__
def parse_arguments():
args = docopt(__doc__, version=__version__)
return dict(
file=args['<file>'],
silent=args['-s'] or args['--silent'],
verbose=args['-v'] or args['--verbose'],
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Docopt
with pytest.raises(SystemExit):
foobar.cli.main()
pytest.fail("CLI doesn't abort")
def test_cli():
1
2
3
4
Challenges with Writing Tests
How test our CLI configuration?
Control taken away from us
Package features require deployment
result = shell('foobar')
def a_functional_test():
1
2
assert result.exit_code != 0, result.stdout
3
CLI Test Strategy
1. Start from the user interface with functional tests.
2. Work down towards unit tests.
1. Start from the user interface with functional tests.
result = shell('foobar')
with ArgvContext('foobar', 'myfile', '--verbose'):
args = foobar.cli.parse_arguments()
def a_functional_test():
1
2
assert result.exit_code != 0, result.stdout
3
4
def a_unit_test():
5
6
7
assert args['verbose'] == True
8
result = shell('foobar --help')
assert result.exit_code == 0
def test_entrypoint():
1
"""Is entrypoint script installed? (setup.py)"""
2
3
4
Functional Tests (User Interface)
@patch('foobar.command.process')
with ArgvContext('foobar', 'myfile', '-v'):
foobar.cli.main()
import foobar
1
from cli_test_helpers import ArgvContext
2
from unittest.mock import patch
3
4
5
def test_process_is_called(mock_command):
6
7
8
9
assert mock_command.called
10
assert mock_command.call_args.kwargs == dict(
11
file='myfile', silent=False, verbose=True)
12
Unit Tests
[tox]
[testenv]
cli-test-helpers
coverage[toml]
pytest
coverage run -m pytest {posargs}
1
envlist = py{38,39,310}
2
3
4
description = Unit tests
5
deps =
6
7
8
9
commands =
10
11
coverage xml
12
coverage report
13
Tox
$ cowsay MOO! I ♥ CLI-TEST-HELPERS | lolcat
___________________________
< MOO! I ♥ CLI-TEST-HELPERS >
---------------------------
 ^__^
 (oo)_______
(__) )/
||----w |
|| ||
Coding Example #2
Thank you!
for your precious time
Painless Software
Less pain, more fun.

More Related Content

Similar to Python Summit 2022: Never Write Scripts Again

關於測試,我說的其實是......
關於測試,我說的其實是......關於測試,我說的其實是......
關於測試,我說的其實是......hugo lu
 
Global Interpreter Lock: Episode I - Break the Seal
Global Interpreter Lock: Episode I - Break the SealGlobal Interpreter Lock: Episode I - Break the Seal
Global Interpreter Lock: Episode I - Break the SealTzung-Bi Shih
 
The enterprise manager command line interface2
The enterprise manager command line interface2The enterprise manager command line interface2
The enterprise manager command line interface2Kellyn Pot'Vin-Gorman
 
The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6Wim Godden
 
Jenkins Pipelines Advanced
Jenkins Pipelines AdvancedJenkins Pipelines Advanced
Jenkins Pipelines AdvancedOliver Lemm
 
The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202Mahmoud Samir Fayed
 
Debugging of (C)Python applications
Debugging of (C)Python applicationsDebugging of (C)Python applications
Debugging of (C)Python applicationsRoman Podoliaka
 
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMPInria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMPStéphanie Roger
 
Introduction to julia
Introduction to juliaIntroduction to julia
Introduction to julia岳華 杜
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVMSylvain Wallez
 
The why and how of moving to php 5.4/5.5
The why and how of moving to php 5.4/5.5The why and how of moving to php 5.4/5.5
The why and how of moving to php 5.4/5.5Wim Godden
 
Mock cli with Python unittest
Mock cli with Python unittestMock cli with Python unittest
Mock cli with Python unittestSong Jin
 
The Ring programming language version 1.5.3 book - Part 27 of 184
The Ring programming language version 1.5.3 book - Part 27 of 184The Ring programming language version 1.5.3 book - Part 27 of 184
The Ring programming language version 1.5.3 book - Part 27 of 184Mahmoud Samir Fayed
 
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, TuningJava 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, TuningCarol McDonald
 
PuppetConf 2016: Getting to the Latest Puppet – Nate McCurdy & Elizabeth Witt...
PuppetConf 2016: Getting to the Latest Puppet – Nate McCurdy & Elizabeth Witt...PuppetConf 2016: Getting to the Latest Puppet – Nate McCurdy & Elizabeth Witt...
PuppetConf 2016: Getting to the Latest Puppet – Nate McCurdy & Elizabeth Witt...Puppet
 

Similar to Python Summit 2022: Never Write Scripts Again (20)

關於測試,我說的其實是......
關於測試,我說的其實是......關於測試,我說的其實是......
關於測試,我說的其實是......
 
Global Interpreter Lock: Episode I - Break the Seal
Global Interpreter Lock: Episode I - Break the SealGlobal Interpreter Lock: Episode I - Break the Seal
Global Interpreter Lock: Episode I - Break the Seal
 
The enterprise manager command line interface2
The enterprise manager command line interface2The enterprise manager command line interface2
The enterprise manager command line interface2
 
The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6
 
Onward15
Onward15Onward15
Onward15
 
Jenkins Pipelines Advanced
Jenkins Pipelines AdvancedJenkins Pipelines Advanced
Jenkins Pipelines Advanced
 
The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202
 
report
reportreport
report
 
Pro PostgreSQL
Pro PostgreSQLPro PostgreSQL
Pro PostgreSQL
 
Debugging of (C)Python applications
Debugging of (C)Python applicationsDebugging of (C)Python applications
Debugging of (C)Python applications
 
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMPInria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
 
Introduction to julia
Introduction to juliaIntroduction to julia
Introduction to julia
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVM
 
Testing in go
Testing in goTesting in go
Testing in go
 
How to fake_properly
How to fake_properlyHow to fake_properly
How to fake_properly
 
The why and how of moving to php 5.4/5.5
The why and how of moving to php 5.4/5.5The why and how of moving to php 5.4/5.5
The why and how of moving to php 5.4/5.5
 
Mock cli with Python unittest
Mock cli with Python unittestMock cli with Python unittest
Mock cli with Python unittest
 
The Ring programming language version 1.5.3 book - Part 27 of 184
The Ring programming language version 1.5.3 book - Part 27 of 184The Ring programming language version 1.5.3 book - Part 27 of 184
The Ring programming language version 1.5.3 book - Part 27 of 184
 
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, TuningJava 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
 
PuppetConf 2016: Getting to the Latest Puppet – Nate McCurdy & Elizabeth Witt...
PuppetConf 2016: Getting to the Latest Puppet – Nate McCurdy & Elizabeth Witt...PuppetConf 2016: Getting to the Latest Puppet – Nate McCurdy & Elizabeth Witt...
PuppetConf 2016: Getting to the Latest Puppet – Nate McCurdy & Elizabeth Witt...
 

More from Peter Bittner

APPUiO Quick Start (OpenShift > DevOps > App Dev)
APPUiO Quick Start (OpenShift > DevOps > App Dev)APPUiO Quick Start (OpenShift > DevOps > App Dev)
APPUiO Quick Start (OpenShift > DevOps > App Dev)Peter Bittner
 
Pee Dee Kay (PDK) - Puppet Development Kit
Pee Dee Kay (PDK) - Puppet Development KitPee Dee Kay (PDK) - Puppet Development Kit
Pee Dee Kay (PDK) - Puppet Development KitPeter Bittner
 
EuroPython 2019: Modern Continuous Delivery for Python Developers
EuroPython 2019: Modern Continuous Delivery for Python DevelopersEuroPython 2019: Modern Continuous Delivery for Python Developers
EuroPython 2019: Modern Continuous Delivery for Python DevelopersPeter Bittner
 
Avoid the Vendor Lock-in Trap (with App Deployment)
Avoid the Vendor Lock-in Trap (with App Deployment)Avoid the Vendor Lock-in Trap (with App Deployment)
Avoid the Vendor Lock-in Trap (with App Deployment)Peter Bittner
 
A guide to modern software development 2018
A guide to modern software development 2018A guide to modern software development 2018
A guide to modern software development 2018Peter Bittner
 
PyCon 9: Continuous Delivery starts at your Development Dnvironment
PyCon 9: Continuous Delivery starts at your Development DnvironmentPyCon 9: Continuous Delivery starts at your Development Dnvironment
PyCon 9: Continuous Delivery starts at your Development DnvironmentPeter Bittner
 
Painless Continuous Delivery – DjangoCon 2017
Painless Continuous Delivery – DjangoCon 2017Painless Continuous Delivery – DjangoCon 2017
Painless Continuous Delivery – DjangoCon 2017Peter Bittner
 
Continuous Delivery for Python Developers – PyCon Otto
Continuous Delivery for Python Developers – PyCon OttoContinuous Delivery for Python Developers – PyCon Otto
Continuous Delivery for Python Developers – PyCon OttoPeter Bittner
 
Fix-Price Projects And Agile – PyCon Sette
Fix-Price Projects And Agile – PyCon SetteFix-Price Projects And Agile – PyCon Sette
Fix-Price Projects And Agile – PyCon SettePeter Bittner
 
Creating a Collaboration Platform (Leveraging the Django Eco System)
Creating a Collaboration Platform (Leveraging the Django Eco System)Creating a Collaboration Platform (Leveraging the Django Eco System)
Creating a Collaboration Platform (Leveraging the Django Eco System)Peter Bittner
 
Linux für Einsteiger und UmsteigerInnen (Vortrag)
Linux für Einsteiger und UmsteigerInnen (Vortrag)Linux für Einsteiger und UmsteigerInnen (Vortrag)
Linux für Einsteiger und UmsteigerInnen (Vortrag)Peter Bittner
 

More from Peter Bittner (13)

APPUiO Quick Start (OpenShift > DevOps > App Dev)
APPUiO Quick Start (OpenShift > DevOps > App Dev)APPUiO Quick Start (OpenShift > DevOps > App Dev)
APPUiO Quick Start (OpenShift > DevOps > App Dev)
 
Pee Dee Kay (PDK) - Puppet Development Kit
Pee Dee Kay (PDK) - Puppet Development KitPee Dee Kay (PDK) - Puppet Development Kit
Pee Dee Kay (PDK) - Puppet Development Kit
 
Managing 100+ WAFs
Managing 100+ WAFsManaging 100+ WAFs
Managing 100+ WAFs
 
EuroPython 2019: Modern Continuous Delivery for Python Developers
EuroPython 2019: Modern Continuous Delivery for Python DevelopersEuroPython 2019: Modern Continuous Delivery for Python Developers
EuroPython 2019: Modern Continuous Delivery for Python Developers
 
Avoid the Vendor Lock-in Trap (with App Deployment)
Avoid the Vendor Lock-in Trap (with App Deployment)Avoid the Vendor Lock-in Trap (with App Deployment)
Avoid the Vendor Lock-in Trap (with App Deployment)
 
A guide to modern software development 2018
A guide to modern software development 2018A guide to modern software development 2018
A guide to modern software development 2018
 
PyCon 9: Continuous Delivery starts at your Development Dnvironment
PyCon 9: Continuous Delivery starts at your Development DnvironmentPyCon 9: Continuous Delivery starts at your Development Dnvironment
PyCon 9: Continuous Delivery starts at your Development Dnvironment
 
Painless Continuous Delivery – DjangoCon 2017
Painless Continuous Delivery – DjangoCon 2017Painless Continuous Delivery – DjangoCon 2017
Painless Continuous Delivery – DjangoCon 2017
 
Continuous Delivery for Python Developers – PyCon Otto
Continuous Delivery for Python Developers – PyCon OttoContinuous Delivery for Python Developers – PyCon Otto
Continuous Delivery for Python Developers – PyCon Otto
 
Fix-Price Projects And Agile – PyCon Sette
Fix-Price Projects And Agile – PyCon SetteFix-Price Projects And Agile – PyCon Sette
Fix-Price Projects And Agile – PyCon Sette
 
Creating a Collaboration Platform (Leveraging the Django Eco System)
Creating a Collaboration Platform (Leveraging the Django Eco System)Creating a Collaboration Platform (Leveraging the Django Eco System)
Creating a Collaboration Platform (Leveraging the Django Eco System)
 
Linux für Einsteiger und UmsteigerInnen (Vortrag)
Linux für Einsteiger und UmsteigerInnen (Vortrag)Linux für Einsteiger und UmsteigerInnen (Vortrag)
Linux für Einsteiger und UmsteigerInnen (Vortrag)
 
Linux auf meinem PC
Linux auf meinem PCLinux auf meinem PC
Linux auf meinem PC
 

Recently uploaded

Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 

Recently uploaded (20)

Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 

Python Summit 2022: Never Write Scripts Again

  • 1.
  • 2.
  • 3.
  • 4. Source: , 2015 Technology and Friends, Episode 354
  • 5. from application import cli 1 from cli_test_helpers import shell 2 3 def test_cli_entrypoint(): 4 result = shell("python-summit --help") 5 assert result.exit_code == 0 6 1. What's wrong with scripts? 2. Coding example #1 (refactoring) 3. Why CLI applications? 4. Challenges with writing tests 5. Coding example #2 (cli & tests)
  • 6. print("This is important code") 1 2 for index, arg in enumerate(sys.argv): 3 print(f"[{index}]: {arg}") 4 What's Wrong with Scripts? Easy to get started Limited possibilities for structure Hard to (unit) test No dependency management Deployment may require care Custom user experience
  • 7. $ cowsay -e ~~ WHAT IS WRONG WITH SCRIPTS? | lolcat _____________________________ < WHAT IS WRONG WITH SCRIPTS? > ----------------------------- ^__^ (~~)_______ (__) )/ ||----w | || || Coding Example #1
  • 8. print("Usage: foo <bar> --baz") def main(): 1 2 3 if __name__ == "__main__": 4 main() 5 Why CLI Applications? Standardized user experience More possibilities for structure Possibilities for all kinds of testing Dependency management Packaging & distribution
  • 9. import argparse from . import __version__ def parse_arguments(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--version', action='version', version=__version__) parser.add_argument('filename') args = parser.parse_args() return args def main(): args = parse_arguments() ... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Argparse
  • 10. import click @click.command() @click.version_option() @click.argument('filename') def main(filename): click.echo(filename) 1 2 3 4 5 6 7 Click import click @click.command() @click.version_option() @click.argument('filename', type=click.Path(exists=True)) def main(filename): click.echo(filename) 1 2 3 4 5 6 7 import click @click.command() @click.version_option() @click.argument('infile', type=click.File()) def main(infile): click.echo(infile.read()) 1 2 3 4 5 6 7
  • 11. """Foobar Usage: foobar (-h | --help | --version) foobar [-s | --silent] <file> foobar [-v | --verbose] <file> Positional arguments: file target file path name Optional arguments: -h, --help show this help message and exit -s, --silent don't show progress output -v, --verbose explain progress verbosely --version show program's version number and exit """ from docopt import docopt from . import __version__ def parse_arguments(): args = docopt(__doc__, version=__version__) return dict( file=args['<file>'], silent=args['-s'] or args['--silent'], verbose=args['-v'] or args['--verbose'], ) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Docopt
  • 12. with pytest.raises(SystemExit): foobar.cli.main() pytest.fail("CLI doesn't abort") def test_cli(): 1 2 3 4 Challenges with Writing Tests How test our CLI configuration? Control taken away from us Package features require deployment
  • 13. result = shell('foobar') def a_functional_test(): 1 2 assert result.exit_code != 0, result.stdout 3 CLI Test Strategy 1. Start from the user interface with functional tests. 2. Work down towards unit tests. 1. Start from the user interface with functional tests. result = shell('foobar') with ArgvContext('foobar', 'myfile', '--verbose'): args = foobar.cli.parse_arguments() def a_functional_test(): 1 2 assert result.exit_code != 0, result.stdout 3 4 def a_unit_test(): 5 6 7 assert args['verbose'] == True 8
  • 14. result = shell('foobar --help') assert result.exit_code == 0 def test_entrypoint(): 1 """Is entrypoint script installed? (setup.py)""" 2 3 4 Functional Tests (User Interface)
  • 15. @patch('foobar.command.process') with ArgvContext('foobar', 'myfile', '-v'): foobar.cli.main() import foobar 1 from cli_test_helpers import ArgvContext 2 from unittest.mock import patch 3 4 5 def test_process_is_called(mock_command): 6 7 8 9 assert mock_command.called 10 assert mock_command.call_args.kwargs == dict( 11 file='myfile', silent=False, verbose=True) 12 Unit Tests
  • 16. [tox] [testenv] cli-test-helpers coverage[toml] pytest coverage run -m pytest {posargs} 1 envlist = py{38,39,310} 2 3 4 description = Unit tests 5 deps = 6 7 8 9 commands = 10 11 coverage xml 12 coverage report 13 Tox
  • 17. $ cowsay MOO! I ♥ CLI-TEST-HELPERS | lolcat ___________________________ < MOO! I ♥ CLI-TEST-HELPERS > --------------------------- ^__^ (oo)_______ (__) )/ ||----w | || || Coding Example #2
  • 18. Thank you! for your precious time Painless Software Less pain, more fun.