Players have parents, also known as guardians.
Let's make a module for a
This time let's do it with a bit of test-driven development (TDD) and show how to get PyCharm into a good "flow" for TDD.
src/laxleague/guardian.py with an empty class:
class Guardian:""" A guardian or parent in the league """pass
Why do we make an empty placeholder class?
To let PyCharm generate the test for us.
Navigate | Go To Test (
Shift-Cmd-T macOS) as explained in the last step to help generate
In that file, change the first test to
test_construction to "get me into the flow", letting PyCharm generate the import:
from laxleague.guardian import Guardiandef test_construction():assert Guardian()
Run the test by right-clicking in the editor outside any block and choosing to run it with
pytest (bigger target area than the tab.)
Yay, the test passes.
Let's switch to running all of our tests.
In the project tool window, right-click on
tests and choose
Run 'pytest in tests'.
The test runner now shows a tab with
pytest in tests, with 2 tests passing:
Not a major victory, but allows us to start inching forward:
Now let's get ourselves into a TDD flow. We'd like to easily look at the code we are writing and the tests we providing against that code. I like both visible, with my code on the left and the tests on the right.
Find Action with Cmd-Shift-A and search for
On the left, open
guardian.py and on the right, make sure
test_guardian.py is still open.
While we're at it, collapse the project tool window, turn off the toolbars and navigation bars, and tabs.
The run tool window stays on the bottom (though on wide monitors I put it on the right):
There, that has a nice feel to it. Room to focus.
Now that our code is setup, let's get our test running "in the flow". Let's have our tests run, automatically, as we type. PyCharm makes this easy and visually convenient -- it even integrates with your desktop notification system when tests are finished running and PyCharm isn't visible.
In the tool window for the test output, click on the
Toggle auto-test icon, two icons below the green run arrow.
With autorun enabled, next click the big green run arrow again. Now, all your tests run automatically two seconds (configurable) after you stop typing.
One final point: you don't have to save changes to your code or tests. PyCharm has an auto-save virtual filesystem thingy.
To see this autorun in action, change something in one of your
assert statements, without saving.
After two seconds, you'll see the tests re-run, automatically.
That's a nice start to a good TDD flow. Let's write a failing test, then fix the implementation.
Guardian needs a constructor that takes and stores
first_name and a
Change the first test in
from laxleague.guardian import Guardiandef test_construction():g = Guardian('Mary', 'Jones')
Notice that PyCharm warns you (on hovering) with 'Unexpected argument' when we supply arguments:
After two seconds, even without saving, our tests show as broken:
Of course it breaks:
Guardian has no
Since it is the code we are writing tests for, the mistake is conveniently right there in our left tab.
No need to think.
laxleague/guardian.py to implement storing names on instances:
class Guardian:""" A guardian or parent in the league """def __init__(self, first_name, last_name):self.first_name = first_nameself.last_name = last_name
As you are writing this, let PyCharm help you:
First, use autocomplete to finish
__init__and put your cursor in the right spot.
Next, when you type your constructor arguments, use
Add field 'first_name' to Guardian. PyCharm will generate the
self.first_name = first_nameboilerplate for you.
Finally, if the generation is in the wrong order, use
Shift-Alt-Upor down to move the line, instead of cutting and pasting.
Our test now passes but doesn't do an assertion.
test_construction, let's show a bit about how PyCharm can help you be more productive and accurate.
First, hold down
Ctrl and hover on the
PyCharm tells you that
g is of inferred type
Next, add an assertion:
assert g.first_name == 'Mary'
As you type
first_name you can see PyCharm offering you the autocomplete.
This is because PyCharm inferred the type of
Guardian, thus speeding up your TDD.
Oops, we had poor style on that.
In my projects, I prefer a testing convention for asserts with expected on the left, meaning
expected == actual.
While Guido declined to designate a winner, it seems Kent Beck did, and Brian Okken's examples also use that.
You can see this problem by changing the expected value of 'Mary' to a value of 'Expected'.
PyCharm's test output now shows expected vs. actual, and
Expected is in the wrong place.
We need to flip that, but good news: PyCharm excels at such janitorial work.
Click on the double-equal, hit
Alt-Enter, and choose
In fact, PyCharm will obey a style set by a project.
pytest.ini file at the root:
Let's write a test for last name, causing
test_guardian.py to finish like the following -- including the expected/actual ordering:
from laxleague.guardian import Guardiandef test_construction():g = Guardian('Mary', 'Jones')assert 'Mary' == g.first_nameassert 'Jones' == g.last_name
One last point: PyCharm's tool window for testing shows passing tests by default.
If you don't want to see them, and focus on failing tests instead, click on the
Show Passed icon to the right of the green play button.