|
1 | 1 | # Tests |
2 | 2 |
|
3 | | -## Tools to install |
| 3 | +- [Tests](#tests) |
| 4 | + - [Pytest](#pytest) |
| 5 | + - [Installing pytest Globally](#installing-pytest-globally) |
| 6 | + - [Windows](#windows) |
| 7 | + - [Linux / MacOS](#linux--macos) |
| 8 | + - [Installing pytest within a virtual environment](#installing-pytest-within-a-virtual-environment) |
| 9 | + - [Running the tests](#running-the-tests) |
| 10 | + - [Failures](#failures) |
| 11 | + - [Extra arguments](#extra-arguments) |
| 12 | + - [Stop After First Failure [`-x`]](#stop-after-first-failure--x) |
| 13 | + - [Failed Tests First [`--ff`]](#failed-tests-first---ff) |
| 14 | + - [Recommended Workflow](#recommended-workflow) |
| 15 | + - [Using PDB, the Python Debugger, with pytest](#using-pdb-the-python-debugger-with-pytest) |
| 16 | + - [Extending your IDE](#extending-your-ide) |
| 17 | + - [Additional information](#additional-information) |
| 18 | + - [Adding pytest to your PATH](#adding-pytest-to-your-path) |
| 19 | + - [Windows](#windows-1) |
| 20 | + - [Fixing warnings](#fixing-warnings) |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +## Pytest |
| 25 | + |
| 26 | +_Official pytest documentation can be found on the [pytest Wiki](https://pytest.org/en/latest/) page._ |
| 27 | + |
| 28 | +Pytest lets you test your solutions using our provided tests, and is what we use to validate your solutions on the website. |
| 29 | + |
| 30 | +### Installing pytest Globally |
| 31 | + |
| 32 | +Pytest can be installed and updated using the built-in Python utility `pip`. |
| 33 | + |
| 34 | +#### Windows |
| 35 | + |
| 36 | +```powershell |
| 37 | +PS C:\Users\foobar> python3 -m pip install pytest pytest-cache pytest-subtests pytest-pylint |
| 38 | +Successfully installed pytest-6.2.5 ... |
| 39 | +``` |
4 | 40 |
|
5 | | -We recommend you install [pytest](http://pytest.org/en/latest/) with the following plugins: |
| 41 | +#### Linux / MacOS |
6 | 42 |
|
7 | | -- [pytest-cache](http://pythonhosted.org/pytest-cache/) |
8 | | -- [pytest-subtests](https://github.com/pytest-dev/pytest-subtests) |
9 | | -- [pytest-pylint](https://github.com/carsongee/pytest-pylint) |
| 43 | +```bash |
| 44 | +$ python3 -m pip install pytest pytest-cache pytest-subtests pytest-pylint |
| 45 | +Successfully installed pytest-6.2.5 ... |
10 | 46 |
|
11 | | -The PyTest [Getting Started Guide](https://docs.pytest.org/en/latest/getting-started.html) has quick general instructions, although they do not cover installing the plugins. |
12 | | -Continue reading below for plugin installation. |
| 47 | +``` |
13 | 48 |
|
14 | | -We also recommend [pylint](https://pylint.pycqa.org/en/latest/user_guide/), as it is part of our automated feedback on the website, and can be a very useful (if noisy!) code analysis tool. |
| 49 | +To check if the installation was succesful: |
15 | 50 |
|
16 | | -Pylint can be a bit much, so this [tutorial](https://pylint.pycqa.org/en/latest/tutorial.html) can be helpful for getting started, as can this overview of [Code Quality: Tools and Best Practices](https://realpython.com/python-code-quality/) from Real Python. |
| 51 | +```bash |
| 52 | +$ python3 -m pytest --version |
| 53 | +pytest 6.2.5 |
| 54 | +``` |
17 | 55 |
|
18 | | -Finally, [this site](https://pycodequ.al/docs/pylint-messages.html) is a great place to look up more human-readable descriptions of Pylint linting messages. |
| 56 | +If you do not want to precede every command with `python3 -m` please refer to [adding to PATH](#adding-to-path) at the end of this document. |
19 | 57 |
|
| 58 | +#### Installing pytest within a virtual environment |
20 | 59 |
|
21 | | -### Installing `pytest` |
| 60 | +*For more information about virtual environments please refer to the [TOOLS](./TOOLS.md) file.* |
22 | 61 |
|
23 | | -To install `pytest`, run the following command in the environment (_active `venv`, `conda env`, `docker container`, `vm` or other project space with Python 3.8 installed_): |
| 62 | +When installing pytest or any other module(s), make sure that you have [activated your environment](.\TOOLS.md#activating-your-virtual-environment). After which you can run: |
24 | 63 |
|
25 | 64 | ```bash |
26 | | -pip3 install pytest pytest-cache pytest-subtests pytest-pylint |
| 65 | +$ pip install pytest pytest-cache pytest-subtests pytest-pylint |
| 66 | +Successfully installed pytest-6.2.5 ... |
27 | 67 | ``` |
28 | 68 |
|
29 | | -If you get a `command not found` response from your system, you can find a |
30 | | -tutorial on how to install `pip` |
31 | | -[here](https://pip.pypa.io/en/stable/installing/). |
| 69 | +### Running the tests |
32 | 70 |
|
33 | | -Once the installation has completed, you can check what the default version of `pytest` is by running the following: |
| 71 | +To run the tests, go to the folder where the exercise is stored using `cd` in your terminal (_replace `{exercise-folder-location}` below with the path_). |
34 | 72 |
|
35 | 73 | ```bash |
36 | | -pytest --version |
| 74 | +$ cd {exercise-folder-location} |
37 | 75 | ``` |
38 | 76 |
|
39 | | -## Testing |
| 77 | +The file you'll want always ends with `_test.py`. |
| 78 | +This file contains the tests for your solution, and are the same tests which run on the website. |
| 79 | +Now run the following command in your terminal, replacing `{exercise_test.py}` with the location/name of the test file: |
40 | 80 |
|
41 | | -### Run All Tests for an Exercise |
| 81 | +```bash |
| 82 | +$ python3 -m pytest {exercise_test.py} |
| 83 | +==================== 7 passed in 0.08s ==================== |
| 84 | +``` |
42 | 85 |
|
43 | | -To run all tests for a specific exercise (_we will take the `bob.py` exercise as |
44 | | -an example here_), navigate to the directory where that exercise has been |
45 | | -downloaded and run the following in the terminal: |
| 86 | +#### Failures |
| 87 | + |
| 88 | +When your code returns an incorrect or unexpected value, pytest returns all the failed tests and the returned and expected values of each. Look at the following failed test file: |
46 | 89 |
|
47 | 90 | ```bash |
48 | | -pytest bob_test.py |
| 91 | +$ python3 -m pytest {exercise_test.py} |
| 92 | +=================== FAILURES ==================== |
| 93 | +______________ name_of_failed_test ______________ |
| 94 | +# Test code inside of {exercise_test.py} that failed. |
| 95 | +... |
| 96 | +E TypeOfError: ReturnedValue != ExpectedValue |
| 97 | + |
| 98 | +exercise_test.py:{line_of_failed_test}: TypeOfError |
| 99 | +============ short test summary info ============ |
| 100 | +FAILED exercise_test.py::ExerciseTest::name_of_failed_test |
| 101 | +========== 1 failed, 2 passed in 0.13s ========== |
49 | 102 | ``` |
50 | 103 |
|
51 | | -**Note:** To run the tests you need to pass the name of the testsuite file to |
52 | | -`pytest` (_generally, this will be the file ending with `_test.py`_), **NOT** the file that was |
53 | | -created to solve the exercsim problem (which is the _solution implementation_). |
54 | | -`PyTest` needs the test definitions in the `_test.py` file in order to know how to call, run, and exercise the _solution implementation_ code. |
55 | | -Since there are no test cases defined in the _solution implementation_, `pytest` will just return a positive result, specifying that it found and ran zero tests. Like this: |
| 104 | +### Extra arguments |
| 105 | + |
| 106 | +If you really want to be specific about what pytest returns on your screen, here are some handy arguments that allows you to configure its behavior. |
56 | 107 |
|
| 108 | +#### Stop After First Failure [`-x`] |
57 | 109 |
|
| 110 | +Running the `pytest -x {exercise_test.py}` command, will run the tests like normal, but will stop the tests after the first failed test. This will help when you want to debug a single failure at a time. |
| 111 | + |
| 112 | +```bash |
| 113 | +$ python -m pytest -x example_test.py |
| 114 | +=================== FAILURES ==================== |
| 115 | +_______________ example_test_foo ________________ |
| 116 | +... |
| 117 | +... |
| 118 | +============ short test summary info ============ |
| 119 | +FAILED example_test.py::ExampleTest::example_test_foo |
| 120 | +!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!! |
| 121 | +========== 1 failed, 5 passed in 0.28s ========== |
58 | 122 | ``` |
59 | | -============================= bob.py ============================== |
60 | 123 |
|
61 | | ---------------------------------------------------------------------- |
| 124 | +#### Failed Tests First [`--ff`] |
62 | 125 |
|
63 | | -Ran 0 tests in 0.000s |
| 126 | +`pytest-cache` remembers which tests failed last time you ran `pytest`, running `pytest --ff {exercise_test.py}` will run those previously failed tests first, then it will continue with the rest of the tests. This might speed up your testing if you are making a lot of smaller fixes. |
64 | 127 |
|
65 | | -OK |
| 128 | +```bash |
| 129 | +$ python -m pytest --ff bob_test.py |
| 130 | +==================== 7 passed in 503s ==================== |
66 | 131 | ``` |
67 | 132 |
|
| 133 | +#### Recommended Workflow |
68 | 134 |
|
69 | | -### More `pytest` Examples |
| 135 | +We recommend using the following commands to make your debugging easier and (possibly) faster: |
70 | 136 |
|
71 | | -Below are some additional examples and details for getting up and running quickly with Pytest. |
72 | | -[How to invoke pytest](https://docs.pytest.org/en/latest/how-to/usage.html#usage) and [pytest command-line flags](https://docs.pytest.org/en/latest/reference/reference.html#command-line-flags) offer full details on all of pytests run options. |
| 137 | +First change your working directory to the directory of the exercise you want to test: |
73 | 138 |
|
| 139 | +```bash |
| 140 | +cd path/to/exercise |
| 141 | +``` |
74 | 142 |
|
75 | | -#### Stop After First Failure |
76 | | -The above will run all the tests, whether they fail or not. If you'd rather stop |
77 | | -the process and exit on the first failure, run: |
| 143 | +Then, run the tests together with the previously explained arguments `-x` and`--ff`: |
78 | 144 |
|
79 | 145 | ```bash |
80 | | -pytest -x bob_test.py |
| 146 | +pytest -x -ff bob_test.py |
81 | 147 | ``` |
82 | 148 |
|
83 | | -#### Failed Tests First |
| 149 | +This will test your solution. When `pytest` encounters a failed test, the program will stop and tell you which test failed. When you run the test again, `pytest` will first test that failed test, then continue with the rest. |
| 150 | + |
| 151 | +#### Using PDB, the Python Debugger, with pytest |
84 | 152 |
|
85 | | -`pytest-cache` remembers which tests failed, and can run those tests first. |
| 153 | +If you want to truly debug like a pro, use the `--pdb` argument after the `pytest` command. |
86 | 154 |
|
87 | 155 | ```bash |
88 | | -pytest --ff bob_test.py |
| 156 | +$ python3 -m pytest --pdb bob_test.py |
| 157 | +=============== 4 passed in 0.15s =============== |
89 | 158 | ``` |
90 | 159 |
|
91 | | -#### Running All Tests for All Exercises |
| 160 | +When a test fails, `PDB` allows you to look at variables and how your code responds. If you want to learn how to use the `PDB` module, have a look at the [Python Docs](https://docs.python.org/3/library/pdb.html#module-pdb) or [this](https://realpython.com/python-debugging-pdb/) Real Python article. |
92 | 161 |
|
93 | | -```bash |
94 | | -cd exercism/python/ |
95 | | -pytest |
96 | | -``` |
| 162 | +## Extending your IDE |
97 | 163 |
|
98 | | -## Recommended Workflow |
| 164 | +If you'd like to extend your IDE with some tools that will help you with testing and improving your code, check the [TOOLS](./TOOLS.md) page. We go into multiple IDEs, editors and some useful extensions. |
99 | 165 |
|
100 | | -Try this command while working on exercises: |
| 166 | +## Additional information |
| 167 | + |
| 168 | +### Adding pytest to your PATH |
| 169 | + |
| 170 | +**Note:** If you are running a [virtual environment](.\TOOLS.md) you do not need to *add to path* as it should work fine. |
| 171 | + |
| 172 | +Typing `python3 -m` every time you want to run a module can get a little annoying. You can add the `Scripts` folder of your Python installation to your path. If you do not know where you have installed Python, run the following command in your terminal: |
101 | 173 |
|
102 | 174 | ```bash |
103 | | -cd exercism/python/bob |
104 | | -pytest -x --ff bob_test.py |
| 175 | +$ python3 -c "import os, sys; print(os.path.dirname(sys.executable))" |
| 176 | +{python_directory} |
105 | 177 | ``` |
106 | 178 |
|
107 | | -## PDB |
| 179 | +The *returned* directory is where your Python version is installed, in this tutorial it is referred to as `{python_directory}`. |
108 | 180 |
|
109 | | -Typing pdb on the command line will drop you into the python debugger when a test fails. |
110 | | -To learn how to usepdb, check out the |
111 | | -[documentation](https://docs.python.org/3/library/pdb.html#debugger-commands). |
| 181 | +#### Windows |
112 | 182 |
|
113 | | -```bash |
114 | | -pytest --pdb bob_test.py |
| 183 | +Click the `Windows Start` button and lookup *Edit the system environment variables* and press enter. Next press, `Environment Variables...`: |
| 184 | + |
| 185 | + |
| 186 | + |
| 187 | +Then find the `Path` variable in your *User variables*, select it, and click `Edit...`: |
| 188 | + |
| 189 | + |
| 190 | + |
| 191 | +Then add a new line, as shown in the picture, replacing `{python_directory}` with your Python installation's directory: |
| 192 | + |
| 193 | + |
| 194 | + |
| 195 | +### Fixing warnings |
| 196 | + |
| 197 | +It is possible that you will get `warnings` about "unknown markers" when running a test that uses our _new_ syntax. |
| 198 | + |
| 199 | +To resolve this issue, we use a `pytest.ini` file, which can be downloaded from the top level of the Python track directory: [pytest.ini](https://github.com/exercism/python/blob/main/pytest.ini). |
| 200 | + |
| 201 | +You can also create your own file with the following content: |
| 202 | + |
| 203 | +```ini |
| 204 | +[pytest] |
| 205 | +markers = |
| 206 | + task: A concept exercise task. |
115 | 207 | ``` |
| 208 | + |
| 209 | +Whenever you run your tests, make sure that this file is in your _root_ or _working_ directory. |
| 210 | + |
| 211 | +_More information on customizing pytest can be found in the [PyTest docs](https://docs.pytest.org/en/6.2.x/customize.html#pytest-ini)_ |
0 commit comments