From 9337750bb13ff0384ae449a0adca52f95a754f69 Mon Sep 17 00:00:00 2001 From: bonartm Date: Tue, 11 Aug 2020 17:45:08 +0200 Subject: [PATCH 01/17] bugfixed exercises --- .gitignore | 1 + README.md | 2 +- articles/mock_objects.md | 8 ----- articles/multiple_packages.md | 20 ----------- articles/organizing_tests.md | 8 ++--- articles/test_coverage.md | 2 +- articles/unit_tests.md | 8 ++--- mobydick/__init__.py | 2 -- mobydick/word_counter.py | 32 ++++++++++++++++++ test/test_border_cases.py | 63 +++++++++++++++++------------------ test/test_broken_code.py | 6 ++-- test/test_broken_test.py | 2 +- test/test_fixtures.py | 28 ---------------- test/test_parameterized.py | 7 ++-- test/test_unit_test.py | 2 +- test/word_counter.py | 16 --------- 16 files changed, 82 insertions(+), 125 deletions(-) delete mode 100644 articles/mock_objects.md delete mode 100644 articles/multiple_packages.md delete mode 100644 mobydick/__init__.py create mode 100644 mobydick/word_counter.py delete mode 100644 test/test_fixtures.py delete mode 100644 test/word_counter.py diff --git a/.gitignore b/.gitignore index f613f30..9aa9f93 100755 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ out.tmp test/.pytest_cache/* __pycache__/* .coverage +htmlcov diff --git a/README.md b/README.md index 5990e18..a8b8242 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This tutorial helps you to learn automated testing in Python 3 using the `pytest *Captain Ahab was vicious because Moby Dick, the white whale, had bitten off his leg. So the captain set sail for a hunt. For months he was searching the sea for the white whale. The captain finally attacked the whale with a harpoon. Unimpressed, the whale devoured captain, crew and ship. The whale won.* -![tick marks while counting words](../images/counting470.png "Counting words") +![tick marks while counting words](images/counting470.png "Counting words") Herman Melville's book *“Moby Dick”* describes the epic fight between the captain of a whaling ship and a whale. In the book, the whale wins by eating most of the other characters. **But does he also win by being mentioned more often?** diff --git a/articles/mock_objects.md b/articles/mock_objects.md deleted file mode 100644 index 428b9b2..0000000 --- a/articles/mock_objects.md +++ /dev/null @@ -1,8 +0,0 @@ - -# Mock Objects - -### Exercise 1: Using a Mock Object - -The function **word_report.get_top_words()** requires an instance of the class **TextBody**. You need to test the function, excluding the possibility that the **TextBody** class is buggy. To do so, you need to replace the class by a **Mock Object**, a simple placeholder. - -Your task is to write a test for the function **word_counter.get_top_words()** that does not use the class **TextBody**. diff --git a/articles/multiple_packages.md b/articles/multiple_packages.md deleted file mode 100644 index 479ea20..0000000 --- a/articles/multiple_packages.md +++ /dev/null @@ -1,20 +0,0 @@ -### Exercise 5: Import test data in multiple test packages -In a big software project, your tests are distributed to two packages. Both **test_first.py** and **test_second.py** require the variable **MOBYDICK_SUMMARY** from the module **test data.py**. The package structure is like this: - - testss/ - test_a/ - __init__.py - test_first.py - test_b/ - __init__.py - test_second.py - __init__.py - test_data.py - test_all.py - -Your task is to make sure that the variable **MOBYDICK_SUMMARY** is correctly imported to both test modules, so that the tests pass for all of: - - tests/test_a/test_first.py - tests/test_b/test_second.py - tests/test_all.py - diff --git a/articles/organizing_tests.md b/articles/organizing_tests.md index fd79c5b..074e503 100644 --- a/articles/organizing_tests.md +++ b/articles/organizing_tests.md @@ -22,7 +22,7 @@ Add `self` as the first parameter of each function: Run all tests written so far by simply typing :::bash - pytest + python -m pytest ---- @@ -31,17 +31,17 @@ Run all tests written so far by simply typing Run only one test file: :::bash - pytest FILE_NAME + python -m pytest FILE_NAME Run only one test class: :::bash - pytest FILE_NAME::CLASS_NAME + pytest -m pytest FILE_NAME::CLASS_NAME Finally, run a single test: :::bash - pytest FILE_NAME::CLASS_NAME::TEST_NAME + pytest -m pytest FILE_NAME::CLASS_NAME::TEST_NAME ---- diff --git a/articles/test_coverage.md b/articles/test_coverage.md index 0fc6f34..f51c6ca 100644 --- a/articles/test_coverage.md +++ b/articles/test_coverage.md @@ -25,7 +25,7 @@ Check whether any hidden files have appeared. Find out which lines are not covered by tests. Execute :::bash - coverage html + python -m pytest --cov=. --cov-report html Open the resulting file `htmlcov/index.html` in a web browser. diff --git a/articles/unit_tests.md b/articles/unit_tests.md index ee87499..ddab57c 100644 --- a/articles/unit_tests.md +++ b/articles/unit_tests.md @@ -22,19 +22,19 @@ ### Exercise 1: Test a Python function -The function `count_words()` in the module **word_counter.py** calculates the number of words in a text body. +The method `count_words()` of the class **TextCorpus** in the module **word_counter.py** calculates the number of words in a text body. For instance, we would expect the following input to result in a word count of `3`: :::bash Call me Ishmael -Your task is to prove that the `count_words()` function in fact returns `3`. +Your task is to prove that the `count_words()` method in fact returns `3`. Run the example test in `test_unit_test.py` with :::bash - pytest test_unit_test.py + python -m pytest test/test_unit_test.py ---- @@ -55,7 +55,7 @@ Run the test in `test_broken_test.py` and inspect the output. It fails, because there is a bug in the test file. -Fix the test code, so that the test passes. +Fix the *test code*, so that the test passes. ---- diff --git a/mobydick/__init__.py b/mobydick/__init__.py deleted file mode 100644 index b0179ee..0000000 --- a/mobydick/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ - -from .word_counter import TextCorpus, count_word diff --git a/mobydick/word_counter.py b/mobydick/word_counter.py new file mode 100644 index 0000000..af35e0c --- /dev/null +++ b/mobydick/word_counter.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python +""" +Code that is being tested +""" + +def split_to_words(text): + '''split a string into tokens''' + if type(text) != str: + raise TypeError('accepts only string input.') + words = text.split(' ') + return words + +def count_words(text): + '''count number of words in a text''' + words = split_to_words(text) + return len(words) + +def count_word(text, word): + '''count the frequency of a word in a text''' + words = split_to_words(text) + return words.count(word) + +def count_words_dict(text): + '''Returns a dictionary of word counts''' + words = split_to_words(text) + d = {} + + for word in words: + d.setdefault(word, 0) + d[word] += 1 + + return d diff --git a/test/test_border_cases.py b/test/test_border_cases.py index 13255db..87ce03d 100644 --- a/test/test_border_cases.py +++ b/test/test_border_cases.py @@ -4,46 +4,45 @@ TASK: fill in the gaps, so that all tests pass """ -from word_counter import count_words import pytest +from mobydick.word_counter import count_words -class TestBorderCases: - def test_empty(self): - """Empty input works""" - text = '' - assert count_words(text) == _____ +def test_empty(): + """Empty input works""" + text = '' + assert count_words(text) == _____ - def test_smallest(self): - """Minimal string works.""" - text = "whale" - assert ____ == ____ +def test_smallest(): + """Minimal string works.""" + text = "whale" + assert ____ == ____ - def test_typical(self): - """Representative input works.""" - text = "whale eats captain" - assert ____ +def test_typical(): + """Representative input works.""" + text = "whale eats captain" + assert ____ - def test_wrong_input(self): - """Non-string fails with a specific error""" - with pytest.raises(_____) as e_info: - count_words(777) +def test_wrong_input(): + """Non-string fails with a specific error""" + with pytest.raises(_____) as e_info: + count_words(777) - def test_biggest(self): - """An entire book works.""" - text = open('mobydick_full.txt').read() - assert _____ > 200000 +def test_biggest(): + """An entire book works.""" + text = open('mobydick_full.txt').read() + assert _____ > 200000 - def test_nasty1(self): - text = """you haint no objections to sharing a harpooneer's blanket, +def test_nasty1(): + text = """you haint no objections to sharing a harpooneer's blanket, have ye? I s'pose you are goin' a-whalin', so you'd better get used to that sort of thing.""" - assert count_words(text) == _____ - - def test_nasty2(self): - """Another ugly data example works.""" - text = """That #~&%* program still doesn't work! - I already de-bugged it 3 times, and still numpy.array keeps throwing AttributeErrors. - What should I do?""" - _____ + assert count_words(text) == _____ + +def test_nasty2(): + """Another ugly data example works.""" + text = """That #~&%* program still doesn't work! +I already de-bugged it 3 times, and still numpy.array keeps throwing AttributeErrors. +What should I do?""" + _____ diff --git a/test/test_broken_code.py b/test/test_broken_code.py index 88d0105..b17882a 100644 --- a/test/test_broken_code.py +++ b/test/test_broken_code.py @@ -2,10 +2,10 @@ Example of test that fails because of broken code. """ -from word_counter import count_words +from mobydick.word_counter import count_words def test_count_words_tabs(): """words are separated by tabs as well""" - text = "the\twhite\whale" - assert count_words(text) == 3 + n = count_words("the\twhite\thale") + assert n == 3 diff --git a/test/test_broken_test.py b/test/test_broken_test.py index 4209ee8..f19de28 100644 --- a/test/test_broken_test.py +++ b/test/test_broken_test.py @@ -2,7 +2,7 @@ Example of test that fails because of a broken test. """ -from word_counter import count_words +from mobydick.word_counter import count_words def test_words(): diff --git a/test/test_fixtures.py b/test/test_fixtures.py deleted file mode 100644 index 55e8a2c..0000000 --- a/test/test_fixtures.py +++ /dev/null @@ -1,28 +0,0 @@ -# -# example of tests with fixtures -# - -from word_counter import TextBody - - -def set_up(self): - """Prepare before each test""" - MOBYDICK_SUMMARY = open('../test_data/mobydick_summary.txt').read() - self.text = TextBody(MOBYDICK_SUMMARY) - -def test_count_months(self): - self.assertEqual(self.counter.count_word("months"), 1) - -def test_count_the(self): - """Count word in a longer text""" - self.assertEqual(self.counter.count_word("the"), 6) - -def test_word_number_text(): - """Count words in a text paragraph""" - text = TextBody(MOBYDICK_SUMMARY) - assert_equal(text.word_number, 54) - - -def tearDown(self): - """Clean up after a test has passed or failed.""" - pass diff --git a/test/test_parameterized.py b/test/test_parameterized.py index f65cd88..e925eac 100644 --- a/test/test_parameterized.py +++ b/test/test_parameterized.py @@ -1,7 +1,6 @@ +from mobydick.word_counter import count_words_dict -from word_counter import count_words_dict - -MOBYDICK_SUMMARY = open('../data/mobydick_summary.txt').read() +MOBYDICK_SUMMARY = open('./data/mobydick_summary.txt').read() PAIRS = [ @@ -15,6 +14,6 @@ def test_count_words_dict(): - counts = count_words_dict(text) + counts = count_words_dict(MOBYDICK_SUMMARY) for word, number in PAIRS: assert counts[word] == number diff --git a/test/test_unit_test.py b/test/test_unit_test.py index 0880df7..e592944 100644 --- a/test/test_unit_test.py +++ b/test/test_unit_test.py @@ -2,7 +2,7 @@ Example of a Unit Test """ -from word_counter import count_words +from mobydick.word_counter import count_words class TestMobyDick: diff --git a/test/word_counter.py b/test/word_counter.py deleted file mode 100644 index af7a7d7..0000000 --- a/test/word_counter.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -Code that is being tested -""" - -def count_words(text): - if type(text) != str: - raise TypeError('word counter accepts only string input.') - words = text.split(' ') - return len(words) - - -def count_words_dict(text, n): - '''Returns the n most frequent words.''' - d = {'dummy': 1} - ... - return d From 37aa6ef6c2bf6b4d91b0ddcebb808ab9e3b98ca6 Mon Sep 17 00:00:00 2001 From: bonartm Date: Tue, 11 Aug 2020 17:50:01 +0200 Subject: [PATCH 02/17] simplifications --- articles/unit_tests.md | 4 ++-- test/test_broken_code.py | 4 ++-- test/test_unit_test.py | 9 ++++----- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/articles/unit_tests.md b/articles/unit_tests.md index ddab57c..00f0fea 100644 --- a/articles/unit_tests.md +++ b/articles/unit_tests.md @@ -22,14 +22,14 @@ ### Exercise 1: Test a Python function -The method `count_words()` of the class **TextCorpus** in the module **word_counter.py** calculates the number of words in a text body. +The function `count_words()` in the module **word_counter.py** calculates the number of words in a text body. For instance, we would expect the following input to result in a word count of `3`: :::bash Call me Ishmael -Your task is to prove that the `count_words()` method in fact returns `3`. +Your task is to prove that the `count_words()` function in fact returns `3`. Run the example test in `test_unit_test.py` with diff --git a/test/test_broken_code.py b/test/test_broken_code.py index b17882a..7d72213 100644 --- a/test/test_broken_code.py +++ b/test/test_broken_code.py @@ -7,5 +7,5 @@ def test_count_words_tabs(): """words are separated by tabs as well""" - n = count_words("the\twhite\thale") - assert n == 3 + text = "the\twhite\thale" + assert count_words(text) == 3 diff --git a/test/test_unit_test.py b/test/test_unit_test.py index e592944..1bf9a7b 100644 --- a/test/test_unit_test.py +++ b/test/test_unit_test.py @@ -5,9 +5,8 @@ from mobydick.word_counter import count_words -class TestMobyDick: - def test_count_words(self): - """Count words in a short sentence""" - n = count_words("Call me Ishmael") - assert n == 3 +def test_count_words(): + """Count words in a short sentence""" + text = "Call me Ishmael" + assert count_words(text) == 3 From 5b0d5c702152b845f8d753e31d808ec78e24c49f Mon Sep 17 00:00:00 2001 From: bonartm Date: Wed, 12 Aug 2020 17:36:08 +0200 Subject: [PATCH 03/17] setup for mkdocs and githubpages --- .github/workflows/build_deploy.yml | 43 +++++++++++ .gitignore | 1 + README.md | 65 +--------------- articles/README.md | 70 ++++++++++++++++++ articles/challenges.md | 53 ------------- articles/find_pairs.md | 2 +- articles/fixtures.md | 29 ++++---- {images => articles/images}/counting.png | Bin {images => articles/images}/counting.svg | 0 {images => articles/images}/counting470.png | Bin {images => articles/images}/cover.png | Bin {images => articles/images}/cover.svg | 0 {images => articles/images}/mobydick.png | Bin {images => articles/images}/recap_puzzle.svg | 0 .../images}/testing_is_incomplete.png | Bin .../images}/testing_is_incomplete.svg | 0 articles/organizing_tests.md | 38 ++++++---- articles/parameterized.md | 14 ++-- articles/test_coverage.md | 13 ++-- articles/unit_tests.md | 24 +++--- mkdocs.yml | 55 ++++++++++++++ requirements.txt | 5 ++ 22 files changed, 245 insertions(+), 167 deletions(-) create mode 100644 .github/workflows/build_deploy.yml create mode 100644 articles/README.md delete mode 100644 articles/challenges.md rename {images => articles/images}/counting.png (100%) rename {images => articles/images}/counting.svg (100%) rename {images => articles/images}/counting470.png (100%) rename {images => articles/images}/cover.png (100%) rename {images => articles/images}/cover.svg (100%) rename {images => articles/images}/mobydick.png (100%) rename {images => articles/images}/recap_puzzle.svg (100%) rename {images => articles/images}/testing_is_incomplete.png (100%) rename {images => articles/images}/testing_is_incomplete.svg (100%) create mode 100644 mkdocs.yml create mode 100644 requirements.txt diff --git a/.github/workflows/build_deploy.yml b/.github/workflows/build_deploy.yml new file mode 100644 index 0000000..db6f37c --- /dev/null +++ b/.github/workflows/build_deploy.yml @@ -0,0 +1,43 @@ +# adapted from https://github.com/peaceiris/actions-gh-pages/blob/master/README.md#%EF%B8%8F-static-site-generators-with-nodejs and https://github.com/appleboy/scp-action/blob/master/README.md#example + +name: build and deploy the site + +on: + push: + +jobs: + build-deploy: + runs-on: ubuntu-18.04 + steps: + - name: Checkout repo + uses: actions/checkout@v1 + with: + submodules: true + + - name: Setup Python + uses: actions/setup-python@v1 + with: + python-version: '3.7' + architecture: 'x64' + + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install dependencies + run: | + python3 -m pip install --upgrade pip + python3 -m pip install -r ./requirements.txt + + - name: Build docs + run: mkdocs build + + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./_site diff --git a/.gitignore b/.gitignore index 9aa9f93..b8f798b 100755 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ test/.pytest_cache/* __pycache__/* .coverage htmlcov +_site diff --git a/README.md b/README.md index a8b8242..80b7105 100644 --- a/README.md +++ b/README.md @@ -2,67 +2,6 @@ This tutorial helps you to learn automated testing in Python 3 using the `pytest` framework. -![Moby Dick](images/mobydick.png) +## Credits -## Goal: Count Words in Moby Dick - -*Captain Ahab was vicious because Moby Dick, the white whale, had bitten off his leg. So the captain set sail for a hunt. For months he was searching the sea for the white whale. The captain finally attacked the whale with a harpoon. Unimpressed, the whale devoured captain, crew and ship. The whale won.* - -![tick marks while counting words](images/counting470.png "Counting words") - -Herman Melville's book *“Moby Dick”* describes the epic fight between the captain of a whaling ship and a whale. In the book, the whale wins by eating most of the other characters. **But does he also win by being mentioned more often?** - -**In this course, you will test a program that is counting words in Melville's book.** - - -## Preparations - -clone the repository: - - :::bash - git clone https://github.com/krother/python_testing_tutorial.git - -install **pytest**: - - :::bash - pip install pytest - -## Chapters - -* [Unit Tests](articles/unit_tests.md) -* [Fixtures](articles/fixtures.md) -* [Parameterized Tests](articles/parameterized.md) -* [Organizing Tests](articles/organizing_tests.md) -* [Test Coverage](articles/test_coverage.md) -* [Recap Puzzle](articles/find_pairs.md) - -## Appendix - -* [Quotes on Testing](articles/quotes.md) -* [Instructions for Trainers](articles/instructions_for_trainers.md) - -## Links - -* [Python Testing Tutorial](https://katyhuff.github.io/python-testing/) - by Kathryn Huff -* [Introduction to pytest](https://www.youtube.com/watch?v=UPanUFVFfzY) - by Michael Tom-Wing and Christie Wilson -* [Test & Code Podcast](http://testandcode.com/) - by Brian Okken -* [The Clean Code Talks – Unit Testing](http://www.youtube.com/watch?v=wEhu57pih5w&feature=channel) -* [Test-Driven-Development](https://www.youtube.com/watch?v=L4hOiGOKSxQ) - by H.Percival - - -## Sources - -Sources for this tutorial: [github.com/krother/python_testing_tutorial](https://github.com/krother/python_testing_tutorial). - -## Copyright - -Feedback and comments are welcome at: [krother@academis.eu](mailto:krother@academis.eu) - -© 2018 Magdalena & Kristian Rother - -Released under the conditions of a Creative Commons -Attribution License 4.0. - -## Contributors - -Kristian Rother, Magdalena Rother, Daniel Szoska +Adopted from [github.com/krother/python_testing_tutorial](https://github.com/krother/python_testing_tutorial). diff --git a/articles/README.md b/articles/README.md new file mode 100644 index 0000000..f4c500d --- /dev/null +++ b/articles/README.md @@ -0,0 +1,70 @@ +# Python Testing Tutorial + +This tutorial helps you to learn automated testing in Python 3 using the `pytest` framework. + +![Moby Dick](./images/mobydick.png) + +## Goal: Count Words in Moby Dick + +*Captain Ahab was vicious because Moby Dick, the white whale, had bitten off his leg. So the captain set sail for a hunt. For months he was searching the sea for the white whale. The captain finally attacked the whale with a harpoon. Unimpressed, the whale devoured captain, crew and ship. The whale won.* + +![tick marks while counting words](images/counting470.png "Counting words") + +Herman Melville's book *“Moby Dick”* describes the epic fight between the captain of a whaling ship and a whale. In the book, the whale wins by eating most of the other characters. **But does he also win by being mentioned more often?** + +**In this course, you will test a program that is counting words in Melville's book.** + + +## Preparations + +clone the repository: + +```shell +git clone https://github.com/bonartm/python_testing_tutorial.git +``` + +install **pytest**: + +```shell +pip install pytest +``` + +## Chapters + +* [Unit Tests](articles/unit_tests.md) +* [Fixtures](articles/fixtures.md) +* [Parameterized Tests](articles/parameterized.md) +* [Organizing Tests](articles/organizing_tests.md) +* [Test Coverage](articles/test_coverage.md) +* [Recap Puzzle](articles/find_pairs.md) + +## Appendix + +* [Quotes on Testing](articles/quotes.md) +* [Instructions for Trainers](articles/instructions_for_trainers.md) + +## Links + +* [Python Testing Tutorial](https://katyhuff.github.io/python-testing/) - by Kathryn Huff +* [Introduction to pytest](https://www.youtube.com/watch?v=UPanUFVFfzY) - by Michael Tom-Wing and Christie Wilson +* [Test & Code Podcast](http://testandcode.com/) - by Brian Okken +* [The Clean Code Talks – Unit Testing](http://www.youtube.com/watch?v=wEhu57pih5w&feature=channel) +* [Test-Driven-Development](https://www.youtube.com/watch?v=L4hOiGOKSxQ) - by H.Percival + + +## Sources + +Sources for this tutorial: [github.com/krother/python_testing_tutorial](https://github.com/krother/python_testing_tutorial). + +## Copyright + +Feedback and comments are welcome at: [krother@academis.eu](mailto:krother@academis.eu) + +© 2018 Magdalena & Kristian Rother + +Released under the conditions of a Creative Commons +Attribution License 4.0. + +## Contributors + +Kristian Rother, Magdalena Rother, Daniel Szoska diff --git a/articles/challenges.md b/articles/challenges.md deleted file mode 100644 index 24a0a40..0000000 --- a/articles/challenges.md +++ /dev/null @@ -1,53 +0,0 @@ - -# Challenges - -## 1. Unit Tests - -### 1.1 Test a Python function -The function **main()** in the module **word_counter.py** calculates the number of words in a text body. - -For instance, the following sentence contains **three** words: - - Call me Ishmael - -Your task is to prove that the **main()** function calculates the number of words in the sentence correctly with **three**. - -Use the example test in **test_1_1_unit_test.py**. - -### 1.2 Test proves if code is broken -The test in the module **test_failing_code.py** fails, because there is a bug in the function **word_counter.average_word_length()**. In the sentence - - Call me Ishmael - -The words are **four, two,** and **seven** characters long. This gives an average of: - - >>> (4 + 2 + 7) / 3.0 - 4.333333333333333 - -Your task is to fix the code, so that the test passes. - -Use the example in **test_1_2_broken_code.py**. - -### 1.3 Code proves if tests are broken -The test in the module **test_failing_test.py** fails, because there is a bug in the test file. - -Your task is to fix the test, so that the test passes. Use the example in **test_1_3_broken_test.py**. - - -### 1.4 Test border cases -High quality tests cover many different situations. The most common situations for the program **word_counter.py** include: - -| test case | description | example input | expected output -|-----------|-------------|---------------|----------------- -| empty | input is valid, but empty | "" | 0 -| minimal | smallest reasonable input | "whale" | 1 -| typical | representative input | "whale eats captain" | 3 -| invalid | input is supposed to fail | 777 | *Exception raised* -| maximum | largest reasonable input | *Melville's entire book* | *more than 200000* -| sanity | program recycles its own output | *TextBody A created from another TextBody B* | *A equals B* -| nasty | difficult example | "That #~&%* program still doesn't work!" | 6 - -Your task is to make all tests in **test_1_4_border_cases.py** pass. - - ----- diff --git a/articles/find_pairs.md b/articles/find_pairs.md index 7ccb9ec..9524b71 100644 --- a/articles/find_pairs.md +++ b/articles/find_pairs.md @@ -3,6 +3,6 @@ **Match the test strategies with the correct descriptions.** -![recap puzzle](../images/recap_puzzle.svg) +![recap puzzle](./images/recap_puzzle.svg) This exercise works best on the board or on paper. diff --git a/articles/fixtures.md b/articles/fixtures.md index 8b51b35..cd4441c 100644 --- a/articles/fixtures.md +++ b/articles/fixtures.md @@ -13,12 +13,13 @@ There, add a function that loads the file `data/mobydick_summary.txt`: Place the decorator `@pytest.fixture` on top of it: - :::python3 - import pytest +```python +import pytest - @pytest.fixture - def text_summary(): - return open(...).read() +@pytest.fixture +def text_summary(): + return open(...).read() +``` ---- @@ -26,9 +27,10 @@ Place the decorator `@pytest.fixture` on top of it: Now create a module `test_corpus.py` with a function that uses the fixture: - :::python3 - def test_short_sample(text_summary): - assert count_words(text_summary) == 77 +```python +def test_short_sample(text_summary): + assert count_words(text_summary) == 77 +``` Execute the module with `pytest`. Note that you **do not** need to import `conftest`. Pytest does that automatically. @@ -44,11 +46,12 @@ Create a fixture for the full text of the book `mobydick_full.txt` as well. Create a fixture in `conftest.py` that prepares a dictionary with word counts using the `word_counter.count_words_dict()` function. - :::python3 - from word_counter import count_words_dict +```python +from word_counter import count_words_dict - @pytest.fixture - def count_dict(text_summary): - return ... +@pytest.fixture +def count_dict(text_summary): + return ... +``` Write a simple test that makes sure the dictionary is not empty. diff --git a/images/counting.png b/articles/images/counting.png similarity index 100% rename from images/counting.png rename to articles/images/counting.png diff --git a/images/counting.svg b/articles/images/counting.svg similarity index 100% rename from images/counting.svg rename to articles/images/counting.svg diff --git a/images/counting470.png b/articles/images/counting470.png similarity index 100% rename from images/counting470.png rename to articles/images/counting470.png diff --git a/images/cover.png b/articles/images/cover.png similarity index 100% rename from images/cover.png rename to articles/images/cover.png diff --git a/images/cover.svg b/articles/images/cover.svg similarity index 100% rename from images/cover.svg rename to articles/images/cover.svg diff --git a/images/mobydick.png b/articles/images/mobydick.png similarity index 100% rename from images/mobydick.png rename to articles/images/mobydick.png diff --git a/images/recap_puzzle.svg b/articles/images/recap_puzzle.svg similarity index 100% rename from images/recap_puzzle.svg rename to articles/images/recap_puzzle.svg diff --git a/images/testing_is_incomplete.png b/articles/images/testing_is_incomplete.png similarity index 100% rename from images/testing_is_incomplete.png rename to articles/images/testing_is_incomplete.png diff --git a/images/testing_is_incomplete.svg b/articles/images/testing_is_incomplete.svg similarity index 100% rename from images/testing_is_incomplete.svg rename to articles/images/testing_is_incomplete.svg diff --git a/articles/organizing_tests.md b/articles/organizing_tests.md index 074e503..a915f5a 100644 --- a/articles/organizing_tests.md +++ b/articles/organizing_tests.md @@ -9,11 +9,12 @@ Make sure the name of the class starts with the word `Test`. Indent your test functions so that they belong to the class. Add `self` as the first parameter of each function: - :::python3 - class TestDummy: +```python +class TestDummy: - def test_dummy(self): - assert ... + def test_dummy(self): + assert ... +``` ---- @@ -21,8 +22,9 @@ Add `self` as the first parameter of each function: Run all tests written so far by simply typing - :::bash - python -m pytest +```bash +python -m pytest +``` ---- @@ -30,18 +32,21 @@ Run all tests written so far by simply typing Run only one test file: - :::bash - python -m pytest FILE_NAME +```bash +python -m pytest FILE_NAME +``` Run only one test class: - :::bash - pytest -m pytest FILE_NAME::CLASS_NAME +```bash +pytest -m pytest FILE_NAME::CLASS_NAME +``` Finally, run a single test: - :::bash - pytest -m pytest FILE_NAME::CLASS_NAME::TEST_NAME +```bash +pytest -m pytest FILE_NAME::CLASS_NAME::TEST_NAME +``` ---- @@ -51,7 +56,8 @@ Find out which options of pytest do the following: *more verbose output | re-run failing tests | stop on first test that fails* - :::bash - pytest -lf - pytest -v - pytest -x +```bash +pytest -lf +pytest -v +pytest -x +``` diff --git a/articles/parameterized.md b/articles/parameterized.md index 72077fd..be5b8fe 100644 --- a/articles/parameterized.md +++ b/articles/parameterized.md @@ -5,7 +5,7 @@ The tests in `test_parameterized.py` check a list of pairs (word, count) that apply to the text file `mobydick_summary.txt`: - :::python3 + ```python PAIRS = [ ('whale', 5), ('goldfish', 0), @@ -14,6 +14,7 @@ The tests in `test_parameterized.py` check a list of pairs (word, count) that ap ('jellyfish', 99), ('harpoon', 1), ] + ``` Run the tests and see what happens. @@ -34,12 +35,13 @@ We will create six tests from the example data. Use the **test parametrization in pytest**. Change the test function by adding the following decorator: - :::python3 - import pytest +```python +import pytest - @pytest.mark.parametrize('word, number', PAIRS) - def test_count_words_dict(word, number): - ... +@pytest.mark.parametrize('word, number', PAIRS) +def test_count_words_dict(word, number): + ... +``` The two arguments will be filled in automatically. Now remove the `for` loop. diff --git a/articles/test_coverage.md b/articles/test_coverage.md index f51c6ca..526bbdd 100644 --- a/articles/test_coverage.md +++ b/articles/test_coverage.md @@ -3,8 +3,9 @@ For the next exercises, you need to install a small plugin: - :::bash - pip install pytest-cov +```bash +pip install pytest-cov +``` ---- @@ -12,8 +13,9 @@ For the next exercises, you need to install a small plugin: Calculate the percentage of code covered by automatic tests: - :::bash - pytest --cov=. +```bash +pytest --cov=. +``` Instead of the `.` you can insert the path you would like to see in the coverage report. @@ -24,8 +26,9 @@ Check whether any hidden files have appeared. ### Exercise 2: Identify uncovered lines Find out which lines are not covered by tests. Execute - :::bash + ```bash python -m pytest --cov=. --cov-report html + ``` Open the resulting file `htmlcov/index.html` in a web browser. diff --git a/articles/unit_tests.md b/articles/unit_tests.md index 00f0fea..96d1050 100644 --- a/articles/unit_tests.md +++ b/articles/unit_tests.md @@ -5,17 +5,19 @@ #### How many words are in the following sentence? - :::bash - Call me Ishmael. +```bash +Call me Ishmael. +``` ---- #### How many words are in the next sentence? - :::bash - "you haint no objections to sharing a harpooneer's blanket, - have ye? I s'pose you are goin' a-whalin', - so you'd better get used to that sort of thing." +```bash +"you haint no objections to sharing a harpooneer's blanket, +have ye? I s'pose you are goin' a-whalin', +so you'd better get used to that sort of thing." +``` ---- @@ -26,15 +28,17 @@ The function `count_words()` in the module **word_counter.py** calculates the nu For instance, we would expect the following input to result in a word count of `3`: - :::bash - Call me Ishmael +```bash +Call me Ishmael +``` Your task is to prove that the `count_words()` function in fact returns `3`. Run the example test in `test_unit_test.py` with - :::bash - python -m pytest test/test_unit_test.py +```bash +python -m pytest test/test_unit_test.py +``` ---- diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..635dc74 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,55 @@ +site_name: Python Testing Tutorial +site_description: This tutorial helps you to learn automated testing in Python 3 using the `pytest` framework. +site_author: Spiced Academy +copyright: Spiced Academy +site_url: '' +theme: + name: material + palette: + primary: 'blue grey' + accent: 'light blue' +site_dir: ./_site +docs_dir: ./articles + +plugins: + - search + - git-revision-date-localized + #- minify: + # minify_html: true + # minify_js: true + #- mkdocs-jupyter + +markdown_extensions: + - footnotes + - admonition + - pymdownx.arithmatex + - pymdownx.betterem: + smart_enable: all + - pymdownx.caret + - pymdownx.critic + - pymdownx.details + - pymdownx.emoji: + emoji_generator: !!python/name:pymdownx.emoji.to_svg + - pymdownx.inlinehilite + - pymdownx.magiclink + - pymdownx.mark + - pymdownx.smartsymbols + - pymdownx.superfences + - pymdownx.tasklist: + custom_checkbox: true + - pymdownx.tilde + - codehilite: + guess_lang: false + - toc: + permalink: true + +nav: + - Unit Tests: 'unit_tests.md' + - Fixtures: 'fixtures.md' + - Parameterized Tests: 'parameterized.md' + - Organizing Tests: 'organizing_tests.md' + - Test Coverage: 'test_coverage.md' + - Recap Puzzle: 'find_pairs.md' + - 'Appendix: Quotes': 'quotes.md' + - 'Appendix: Instructions For Trainers': 'instructions_for_trainers.md' + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..1477713 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +Markdown==3.1.1 +mkdocs==1.0.4 +mkdocs-material==4.6.0 +mkdocs-git-revision-date-localized-plugin==0.4.5 +mkdocs-minify-plugin==0.2.1 From e7e996625db74cdfbb4c168ab97d41aa442f7f84 Mon Sep 17 00:00:00 2001 From: bonartm Date: Thu, 13 Aug 2020 10:00:50 +0200 Subject: [PATCH 04/17] update toc --- mkdocs.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 635dc74..d7f6909 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,7 +2,7 @@ site_name: Python Testing Tutorial site_description: This tutorial helps you to learn automated testing in Python 3 using the `pytest` framework. site_author: Spiced Academy copyright: Spiced Academy -site_url: '' +site_url: 'https://bonartm.github.io/python_testing_tutorial/' theme: name: material palette: @@ -14,10 +14,6 @@ docs_dir: ./articles plugins: - search - git-revision-date-localized - #- minify: - # minify_html: true - # minify_js: true - #- mkdocs-jupyter markdown_extensions: - footnotes @@ -51,5 +47,4 @@ nav: - Test Coverage: 'test_coverage.md' - Recap Puzzle: 'find_pairs.md' - 'Appendix: Quotes': 'quotes.md' - - 'Appendix: Instructions For Trainers': 'instructions_for_trainers.md' From 72a49cabb4b734981b4139d8f532a68e2ac5ebb1 Mon Sep 17 00:00:00 2001 From: bonartm Date: Thu, 13 Aug 2020 11:10:00 +0200 Subject: [PATCH 05/17] add testing workflow --- .github/workflows/test.yml | 25 +++++++++++++++++++++++++ requirements.txt | 2 ++ 2 files changed, 27 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..484114a --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,25 @@ +name: run pytest + +on: + push: + +jobs: + build-deploy: + runs-on: ubuntu-18.04 + steps: + - name: Checkout repo + uses: actions/checkout@v1 + + - name: Setup Python + uses: actions/setup-python@v1 + with: + python-version: '3.7' + architecture: 'x64' + - name: Install dependencies + run: | + python3 -m pip install --upgrade pip + python3 -m pip install -r ./requirements.txt + + - name: Run tests + run: python -m pytest + diff --git a/requirements.txt b/requirements.txt index 1477713..76e4177 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,5 @@ mkdocs==1.0.4 mkdocs-material==4.6.0 mkdocs-git-revision-date-localized-plugin==0.4.5 mkdocs-minify-plugin==0.2.1 +pytest +pytest-cov From 7b3047ae5a5b4a8f1ad75ae118b56eb22c40e0af Mon Sep 17 00:00:00 2001 From: bonartm Date: Thu, 13 Aug 2020 11:17:35 +0200 Subject: [PATCH 06/17] try out test matrix --- .github/workflows/test.yml | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 484114a..a2aca04 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,22 +4,24 @@ on: push: jobs: - build-deploy: - runs-on: ubuntu-18.04 + test: + runs-on: ${{ matrix.os }} + strategy: + matrix: + # os: [macos-latest, windows-latest, ubuntu-18.04] + os: [ubuntu-18.04] + # python-version: [3.8, 3.6] + python-version: [3.8] steps: - - name: Checkout repo - uses: actions/checkout@v1 - - - name: Setup Python - uses: actions/setup-python@v1 - with: - python-version: '3.7' - architecture: 'x64' - - name: Install dependencies - run: | - python3 -m pip install --upgrade pip - python3 -m pip install -r ./requirements.txt - - - name: Run tests - run: python -m pytest - + - name: chekout repo + uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Run tests + run: python -m pytest From a3f102d8aad3e23a2b2d41c3f037ccb8f3a65ad1 Mon Sep 17 00:00:00 2001 From: bonartm Date: Thu, 13 Aug 2020 14:11:29 +0200 Subject: [PATCH 07/17] update README --- articles/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/articles/README.md b/articles/README.md index f4c500d..bc8e577 100644 --- a/articles/README.md +++ b/articles/README.md @@ -1,5 +1,7 @@ # Python Testing Tutorial +## I love Cologne + This tutorial helps you to learn automated testing in Python 3 using the `pytest` framework. ![Moby Dick](./images/mobydick.png) From 3cfd04d2656ebf8d51d5455c2d5fa67e0837bd1a Mon Sep 17 00:00:00 2001 From: bonartm Date: Thu, 13 Aug 2020 14:23:00 +0200 Subject: [PATCH 08/17] update testing workflow --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a2aca04..400b515 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: # python-version: [3.8, 3.6] python-version: [3.8] steps: - - name: chekout repo + - name: checkout repo uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }} uses: actions/setup-python@v1 @@ -24,4 +24,4 @@ jobs: python -m pip install --upgrade pip pip install -r requirements.txt - name: Run tests - run: python -m pytest + run: python -m pytest test/test_unit_test.py From 22927432236b9d8a0ca5f1174b66b5172bb3ff3b Mon Sep 17 00:00:00 2001 From: bonartm Date: Thu, 13 Aug 2020 14:27:50 +0200 Subject: [PATCH 09/17] update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 80b7105..3cfa4cc 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Python Testing Tutorial +![run pytest](https://github.com/bonartm/python_testing_tutorial/workflows/run%20pytest/badge.svg) + This tutorial helps you to learn automated testing in Python 3 using the `pytest` framework. ## Credits From 43d052983da33329d2bca4848563cd06e788b8fb Mon Sep 17 00:00:00 2001 From: bonartm Date: Thu, 13 Aug 2020 14:43:43 +0200 Subject: [PATCH 10/17] update workflow --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 400b515..775dd6f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,9 +9,9 @@ jobs: strategy: matrix: # os: [macos-latest, windows-latest, ubuntu-18.04] - os: [ubuntu-18.04] + os: [ubuntu-18.04, macos-latest, windows-latest] # python-version: [3.8, 3.6] - python-version: [3.8] + python-version: [3.8, 3.6, 3.3] steps: - name: checkout repo uses: actions/checkout@v2 From 6f087c2a717582701b96841d82fcd88af657dc5c Mon Sep 17 00:00:00 2001 From: bonartm Date: Thu, 13 Aug 2020 14:45:35 +0200 Subject: [PATCH 11/17] update workflow --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 775dd6f..e5c701d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: # os: [macos-latest, windows-latest, ubuntu-18.04] os: [ubuntu-18.04, macos-latest, windows-latest] # python-version: [3.8, 3.6] - python-version: [3.8, 3.6, 3.3] + python-version: [3.8.5, 3.7.8, 3.6.11] steps: - name: checkout repo uses: actions/checkout@v2 From c12f70e9515b6071081ed6934760331cea81c31d Mon Sep 17 00:00:00 2001 From: bonartm Date: Thu, 13 Aug 2020 14:46:47 +0200 Subject: [PATCH 12/17] update workflow --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e5c701d..4c5ca20 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: # os: [macos-latest, windows-latest, ubuntu-18.04] os: [ubuntu-18.04, macos-latest, windows-latest] # python-version: [3.8, 3.6] - python-version: [3.8.5, 3.7.8, 3.6.11] + python-version: [3.8.5, 3.7.8] steps: - name: checkout repo uses: actions/checkout@v2 From 4a9b748fe386d166b2ff15a42e0e289a80608514 Mon Sep 17 00:00:00 2001 From: bonartm Date: Fri, 16 Oct 2020 14:39:56 +0200 Subject: [PATCH 13/17] update --- articles/organizing_tests.md | 2 +- articles/test_coverage.md | 4 ++-- mobydick/word_counter.py | 2 +- test/test_unit_test.py | 3 +-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/articles/organizing_tests.md b/articles/organizing_tests.md index a915f5a..7f3402b 100644 --- a/articles/organizing_tests.md +++ b/articles/organizing_tests.md @@ -57,7 +57,7 @@ Find out which options of pytest do the following: *more verbose output | re-run failing tests | stop on first test that fails* ```bash -pytest -lf +pytest --lf pytest -v pytest -x ``` diff --git a/articles/test_coverage.md b/articles/test_coverage.md index 526bbdd..a7b16c1 100644 --- a/articles/test_coverage.md +++ b/articles/test_coverage.md @@ -14,7 +14,7 @@ pip install pytest-cov Calculate the percentage of code covered by automatic tests: ```bash -pytest --cov=. +python -m pytest --cov=. ``` Instead of the `.` you can insert the path you would like to see in the coverage report. @@ -27,7 +27,7 @@ Check whether any hidden files have appeared. Find out which lines are not covered by tests. Execute ```bash - python -m pytest --cov=. --cov-report html + python -m pytest --cov=. --cov-report term-missing ``` Open the resulting file `htmlcov/index.html` in a web browser. diff --git a/mobydick/word_counter.py b/mobydick/word_counter.py index af35e0c..7621529 100644 --- a/mobydick/word_counter.py +++ b/mobydick/word_counter.py @@ -12,7 +12,7 @@ def split_to_words(text): def count_words(text): '''count number of words in a text''' - words = split_to_words(text) + words = split_to_words(text) return len(words) def count_word(text, word): diff --git a/test/test_unit_test.py b/test/test_unit_test.py index 1bf9a7b..6d5d5ee 100644 --- a/test/test_unit_test.py +++ b/test/test_unit_test.py @@ -2,8 +2,7 @@ Example of a Unit Test """ -from mobydick.word_counter import count_words - +from mobydick.word_counter import count_words, split_to_words def test_count_words(): From edec98bc0a92061c9606acf28d2df4ecf5b57e61 Mon Sep 17 00:00:00 2001 From: bonartm Date: Tue, 29 Jun 2021 14:06:55 +0200 Subject: [PATCH 14/17] cleanup --- .github/workflows/test.yml | 27 --------------------------- README.md | 2 -- articles/README.md | 4 +--- mkdocs.yml | 4 ++-- 4 files changed, 3 insertions(+), 34 deletions(-) delete mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 4c5ca20..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: run pytest - -on: - push: - -jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - matrix: - # os: [macos-latest, windows-latest, ubuntu-18.04] - os: [ubuntu-18.04, macos-latest, windows-latest] - # python-version: [3.8, 3.6] - python-version: [3.8.5, 3.7.8] - steps: - - name: checkout repo - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - - name: Run tests - run: python -m pytest test/test_unit_test.py diff --git a/README.md b/README.md index 3cfa4cc..80b7105 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # Python Testing Tutorial -![run pytest](https://github.com/bonartm/python_testing_tutorial/workflows/run%20pytest/badge.svg) - This tutorial helps you to learn automated testing in Python 3 using the `pytest` framework. ## Credits diff --git a/articles/README.md b/articles/README.md index bc8e577..c73bca6 100644 --- a/articles/README.md +++ b/articles/README.md @@ -1,7 +1,5 @@ # Python Testing Tutorial -## I love Cologne - This tutorial helps you to learn automated testing in Python 3 using the `pytest` framework. ![Moby Dick](./images/mobydick.png) @@ -69,4 +67,4 @@ Attribution License 4.0. ## Contributors -Kristian Rother, Magdalena Rother, Daniel Szoska +Kristian Rother, Magdalena Rother, Daniel Szoska, Malte Bonart diff --git a/mkdocs.yml b/mkdocs.yml index d7f6909..bffe704 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,7 +1,7 @@ site_name: Python Testing Tutorial site_description: This tutorial helps you to learn automated testing in Python 3 using the `pytest` framework. -site_author: Spiced Academy -copyright: Spiced Academy +site_author: Malte Boanrt +copyright: Magdalena & Kristian Rother site_url: 'https://bonartm.github.io/python_testing_tutorial/' theme: name: material From d066420412f6f5ad1f161cff17b3e0823af2f757 Mon Sep 17 00:00:00 2001 From: bonartm Date: Wed, 30 Jun 2021 10:13:27 +0200 Subject: [PATCH 15/17] update readme --- articles/README.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/articles/README.md b/articles/README.md index c73bca6..0179116 100644 --- a/articles/README.md +++ b/articles/README.md @@ -29,20 +29,6 @@ install **pytest**: pip install pytest ``` -## Chapters - -* [Unit Tests](articles/unit_tests.md) -* [Fixtures](articles/fixtures.md) -* [Parameterized Tests](articles/parameterized.md) -* [Organizing Tests](articles/organizing_tests.md) -* [Test Coverage](articles/test_coverage.md) -* [Recap Puzzle](articles/find_pairs.md) - -## Appendix - -* [Quotes on Testing](articles/quotes.md) -* [Instructions for Trainers](articles/instructions_for_trainers.md) - ## Links * [Python Testing Tutorial](https://katyhuff.github.io/python-testing/) - by Kathryn Huff From a2984c6e200fe41e36e8b73db753a1b7237e3b63 Mon Sep 17 00:00:00 2001 From: bonartm Date: Wed, 30 Jun 2021 12:05:36 +0200 Subject: [PATCH 16/17] remove trainer's instructions --- articles/instructions_for_trainers.md | 56 --------------------------- 1 file changed, 56 deletions(-) delete mode 100644 articles/instructions_for_trainers.md diff --git a/articles/instructions_for_trainers.md b/articles/instructions_for_trainers.md deleted file mode 100644 index 7ca860c..0000000 --- a/articles/instructions_for_trainers.md +++ /dev/null @@ -1,56 +0,0 @@ -# Instructions for Trainers - -This chapter aims to help you to run a tutorial on automated testing in Python. -Our aim is to save you preparation time while leaving room for your own ideas. -Most of all, we hope you have fun in your next course. - -## How to run a course using this toolkit - -1. Introduce the Moby Dick Theme to your trainees -2. Clone the repository -3. Share the exercises with your trainees -5. Start coding your way through the chapters - -## Lesson plan for a 180' tutorial - -| module | topic | time | -|--------|-------|------| -| warm-up | introduce the Moby Dick theme | 5' | -| warm-up | announce training objectives | 5' | -| | -| **part 1** | **Writing automatic tests in Python** | 45’ | -| warm-up | warmup question | 5' | -| new content | presentation: Unit Tests in pytest | 10’ | -| application | exercises: Unit Tests | 25’ | -| wrap-up | Q & A | 5’ | -| | -| **part 2** | **Test Strategies (45')** | | -| warm-up | quiz on test strategies | 10' | -| new content | presentation on Test-Driven-Development | 10’ | -| application | exercises: fixtures and parameterized tests | 20' | -| wrap-up | Q & A | 5’ | -| | -| **break** | | 10’ | -| | -| **part 3** | **Tests data and test suites (45')** | | -| warm-up | multiple choice questions | 10' | -| new content | presentation on Integration and Acceptance Tests | 10’ | -| application | exercises: test collection and test coverage | 20' | -| wrap-up | Q & A | 5’ | -| | -| **summary** | **Benefits of testing (25')** | | -| transfer | group discussion on benefits of testing | 15’ | -| wrap-up | recap puzzle | 5’ | -| finishing | summary | 4’ | -| finishing | goodbye | 1' | - -I used a similar lesson plan to conduct a training at EuroPython 2014. -The audience consisted of about 60 Python programmers, including beginners and seasoned developers. - -## Why the Moby Dick example? - -Three main reasons: - -* The implementation is simple enough for beginners -* Counting words yields different border cases (because of upper/lower case, special characters etc), making a sufficient use case for testing -* You can easily change the theme to another book from [Project Gutenberg](http://www.gutenberg.org/). From 67563f9137ccf194e4fcbef5a2c204a5012a641f Mon Sep 17 00:00:00 2001 From: bonartm Date: Wed, 30 Jun 2021 12:05:40 +0200 Subject: [PATCH 17/17] fix link --- articles/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/articles/README.md b/articles/README.md index 0179116..d96c6cf 100644 --- a/articles/README.md +++ b/articles/README.md @@ -29,6 +29,10 @@ install **pytest**: pip install pytest ``` +## Getting Started + +Start with the first exercises in the chapter [Unit Tests](unit_tests.md)! + ## Links * [Python Testing Tutorial](https://katyhuff.github.io/python-testing/) - by Kathryn Huff