Podchaser Logo
Home
HPR4091: Test Driven Development Demo

HPR4091: Test Driven Development Demo

Released Monday, 8th April 2024
Good episode? Give it some love!
HPR4091: Test Driven Development Demo

HPR4091: Test Driven Development Demo

HPR4091: Test Driven Development Demo

HPR4091: Test Driven Development Demo

Monday, 8th April 2024
Good episode? Give it some love!
Rate Episode

Test DrivenDevelopment Demo with PyTest

TDD

  • Discussed in hpr4075
  • Write a new test and run it. It should fail.
  • Write the minimal code that will pass the test
  • Optionally - refactor the code while ensure the tests continue topass

PyTest

  • Framework for writing software tests with python
  • Normally used to test python projects, but could test any softwarethat python can launch return input.
  • if you can write python, you can write tests in PyTest.
  • python assert - check that something is true

Test Discovery

  • Files named test*
  • Functions named test*

Demo Project

  • Trivial app as a demo
  • Print a summary of the latest HPR Episode
  • Title, Host, Date, Audio File
  • How do we get the latest show data
    • RSS feed
    • Feed parser
    • Feed URL

The pytest setup

  • The python script we want to test will be namedhpr_info.py
  • The test will be in a file will be namedtest_hpr_info.py

test_hpr_info.py

import hpr_info

Run pytest

ModuleNotFoundError: No module named 'hpr_info'

  • We have written our first failing test.
  • The minimum code to get pytest to pass is to create an emptyfile
  • touch hpr_info.py

Run pytest again

pytest============================= test session starts ==============================platform linux -- Python 3.11.8, pytest-7.4.4, pluggy-1.4.0rootdir: /tmp/Democollected 0 items

What just happened

  • We created a file named test_hpr_info.py with a singleline to import hpr_info
  • We ran pytest and it failed because hpr_info.py did not exist
  • We created hpr_info.py and pytest ran without anerror.
  • This means we confirmed:
    • Pytest found the file named test_hpr_info.py and triedto execute its tests
    • The import line is looking for a file namedhpr_info.py

Python Assert

  • In python, assert tests if a statement is true
  • For example

asert 1==1

In pytest, we can use assert to check a function returns a specificvalue

assert module.function() == "Desired Output"

Without doing a comparison operator, we can also use assert to checkif something exists without specifying a specific value

assert dictionary.key

Adding a Test

  • Import hpr_info will allow us to test functions insidehpr_info.py
  • We can reference functions inside hpr_info.py byprepending the name with hpr_info. for example

hpr_info.HPR_FEED

  • The first step in finding the latest HPR episode is fetching a copyof the feed.
  • Lets add a test to make sure the HPR feed is defined

import hpr_info

def test_hpr_feed_url():assert hpr_info.HPR_FEED == "https://hackerpublicradio.org/hpr_ogg_rss.php"

pytest again

  • Lets run pytest again and we get the errorAttributeError: module 'hpr_info' has no attribute 'HPR_FEED'
  • So lets add the just enough code hpr_info.py to get thetest to pass

HPR_FEED = "https://hackerpublicradio.org/hpr_ogg_rss.php"

  • Run pytest again and we get 1 passed indicating thepytest found 1 test which passed
  • Hooray, we are doing TDD

Next Test - Parsing the feed

  • lets plan a function that pulls the HPR feed and returns the feeddata.
  • We can test that the result of fetching the feed is a HTTP 200

def test_get_show_data():show_data = hpr_info.get_show_data()assert show_data.status == 200

  • Now when we run pytest we get 1 failed, 1 passed and wecan see the errorAttributeError: module 'hpr_info' has no attribute 'get_show_data'
  • Lets write the code to get the new test to pass.
  • We will use the feedparser python module to make iteasier to parse the rss feed.
  • After we add the import and the new function,hpr_info.py looks like this

import feedparser

HPR_FEED = "https://hackerpublicradio.org/hpr_ogg_rss.php"

def get_show_data():showdata = feedparser.parse(HPR_FEED)return showdata

  • Lets run pytest again. When I have more than one test, I like to addthe -v flag so I can see each test as it runs.

test_hpr_info.py::test_hpr_feed_url PASSED [ 50%]test_hpr_info.py::test_get_show_data PASSED [100%]

Next Test- Get the most recent episode from the feed

  • Now that we have the feed, lets test getting the first episode.
  • feedparser entries are dictionaries.
  • Lets test what the function returns to make sure it looks like a rssfeed entry.

def test_get_latest_entry():latest_entry = hpr_info.get_latest_entry()assert latest_entry["title"]assert latest_entry["published"]

  • After we verify the test fails, we can write the code to rerun thenewest entry data to hpr_info.py and pytest -vwill show 3 passing tests.

def get_latest_entry():showdata = get_show_data()return showdata["entries"][0]

Final Test

  • Lets test a function to see if it returns the values we want toprint.
  • We don't test for specific values, just that the data exists.

def test_get_entry_data():entry_data = hpr_info.get_entry_data(hpr_info.get_latest_entry())assert entry_data["title"]assert entry_data["host"]assert entry_data["published"]assert entry_data["file"]

And then code to get the test to pass

def get_entry_data(entry):for link in entry["links"]:if link.get("rel") == "enclosure":enclosure = link.get("href")

return {"title": entry["title"],"host": entry["authors"][0]["name"],"published": entry["published"],"file": enclosure,}

Finish the HPR info script.

Now that we have tested that we can, get all the info we want fromthe most recent episode lets add the last bit of code tohpr_info.py to print the episode info

if __name__ == "__main__":most_recent_show = get_entry_data(get_latest_entry())print()print(f"Most Recent HPR Episode")for x in most_recent_show:print(f"{x}: {most_recent_show.get(x)}")

if __name__ == "__main__": ensures code inside thisblock will only run when the script is called directly, and not whenimported by test_hpr_info.py

Summary

  • TDD is a programming method where you write tests prior to writingcode.
  • TDD forces me to write smaller functions and more modular code.
  • Link to HPR info script and tests - TODO
  • Additional tests to add
    • Check date is the most recent weekday
    • Check this the host is listed on corespondents page
    • Check others.
  • Project Files - https://gitlab.com/norrist/hpr-pytest-demo
Show More
Rate

Join Podchaser to...

  • Rate podcasts and episodes
  • Follow podcasts and creators
  • Create podcast and episode lists
  • & much more

Episode Tags

Do you host or manage this podcast?
Claim and edit this page to your liking.
,

Unlock more with Podchaser Pro

  • Audience Insights
  • Contact Information
  • Demographics
  • Charts
  • Sponsor History
  • and More!
Pro Features