Skip to content

Commit bdaabbc

Browse files
committed
Final tweaks to Python testing exercise
1 parent 1916012 commit bdaabbc

File tree

1 file changed

+10
-16
lines changed

1 file changed

+10
-16
lines changed

05_testing_and_ci/python_testing_exercise.md

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77

88
## Prerequisites
99

10-
- An operating system / software / environment where you can install Python and some basic Python tools
11-
- An editor or IDE to edit Python code and write text files
12-
- Python (version >= 3)
1310
- [pip](https://pypi.org/project/pip/)
1411
- [NumPy](https://numpy.org/)
1512
- [Matplotlib](https://matplotlib.org/)
@@ -20,15 +17,14 @@
2017

2118
## Step 1 - Getting Familiar With the Code
2219

23-
- Fork the [repository](https://github.com/Simulation-Software-Engineering/testing-python-exercise-wt2425).
24-
- The code in `diffusion2d.py` is in principle the same code used for the Python packaging exercise. The main difference is that now the code has a class `SolveDiffusion2D` which has several member functions.
20+
- Fork the [repository](https://github.com/Simulation-Software-Engineering/testing-python-exercise).
21+
- The code in `diffusion2d.py` is in principle the same code used for the packaging exercise. The main difference is that now the code has a class `SolveDiffusion2D` which has several member functions.
2522
- Each function name states what the function does, for example the function `initialize_domain()` takes in input arguments `w` (width), `h` (height), `dx` and `dy` and sets the values to member variables of the class and also calculates the number of points in x and y directions.
2623
- The functions `initialize_domain` and `initialize_physical_parameters` have default values for all input parameters, hence they can be called without any parameters.
2724
- The file also has a `main()` function which shows a step-by-step procedure to solve the diffusion problem using an object of the class `SolveDiffusion2D`.
2825
- Make sure that `NumPy` and `Matplotlib` are installed on the system that you are working on.
2926
- Run this example by running `python3 diffusion2d.py`.
3027
- Observe the output produced, it should be the same output as what was seen during the packaging exercise.
31-
- Spend some time understanding what each function does. It is important to understand all the functions as you will be writing tests for these functions.
3228

3329
## Step 2 - Adding Assertion Statements
3430

@@ -39,22 +35,21 @@
3935
## Step 3 - Writing Unit Tests
4036

4137
- Write unit tests using either pytest or unittest.
42-
- In the repository there is a folder `tests/`. In this folder there are two folders `unit/` and `integration/`. The first tests written will be unit tests.
43-
- In the file `tests/unit/test_diffusion2d_functions.py` there is already a skeleton code for three unit tests which are to be implemented. The name of each test is of the format `test_<name_of_function_being_tested>`.
44-
- As these are unit tests, in each test, only the call to the respective function needs to be made. No other function from `diffusion2d.py` must be called. If another function call is required to define some member variables, it can be evaded by directly defining the member variables in the test. All the member variables can be accessed directly using the class object.
38+
- In the repository there is a folder `tests/`. In this folder there are two folders `unit/` and `integration/`. Write the unit tests first.
39+
- In the file `tests/unit/test_diffusion2d_functions.py` there is already a skeleton code for three unit tests. The name of each test is of the format `test_<name_of_function_being_tested>`.
40+
- As these are unit tests, in each test, only the call to the respective function needs to be made. No other function from `diffusion2d.py` must be called. If another function call is required to define some member variables, mock it or directly define the internal variables.
4541
- As an example, let us look at how we can write a unit test for the function `initialize_domain`.
4642
- When the function `initialize_domain` is being tested, you need to first identify which variables are being calculated in this function.
4743
- In this case they are the variables `nx` and `ny`. Now choose some values for the variables `w`, `h`, `dx`, and `dy` which are different from the default values. For these values, manually calculate the values of `nx` and `ny`. These manually calculated values are the expected values in this test.
4844
- Now call the function `initialize_domain` with the chosen values of `w`, `h`, `dx`, and `dy` and using an assertion statement, check if the values of `nx` and `ny` in the class member variables are equal to your expected values.
4945
- Note that you have the object of the class `SolveDiffusion2D` and hence you can access member variables, for example `solver.nx` and `solver.ny`. This is useful to check the actual values.
5046
- Using a similar workflow, complete the other two unit tests.
51-
- It is observed that in some instances pytest is not able to find the tests. One reason is the way pytest is installed, which is typically either using pip or apt. Refer to the [corresponding section](https://github.com/Simulation-Software-Engineering/Lecture-Material/blob/main/05_testing_and_ci/python_testing_demo.md#pytest) in the demo for more details. If such errors occur, then try to explicitly point pytest to the relevant test file in the following way:
47+
- Sometimes pytest is not able to find the tests. One reason is the way pytest is installed, which is typically either using pip or apt. Refer to the [corresponding section](https://github.com/Simulation-Software-Engineering/Lecture-Material/blob/main/05_testing_and_ci/python_testing_demo.md#pytest) in the demo for more details. If such errors occur, then try to explicitly point pytest to the relevant test file in the following way:
5248

5349
```bash
5450
pytest tests/unit/test_diffusion2d_functions.py
5551
```
5652

57-
- If everything is done correctly, all the tests should pass.
5853
- How can you make sure that you have written correct tests? By breaking them purposely!
5954
- Introduce a bug in a function on purpose and then re-run the test to see if the test fails.
6055
- Lets try this in the function `initialize_domain`. In line 42 of `diffusion2d.py`, change the calculation from `self.nx = int(w / dx)` to `self.nx = int(h / dx)`. This is clearly a mistake and our test should catch it.
@@ -63,9 +58,8 @@ pytest tests/unit/test_diffusion2d_functions.py
6358
- If you are writing tests with unittest, start by creating a class `TestDiffusion2D` which is derived from the class `unittest.TestCase`. Migrate all the tests inside the class and change them to be member functions of the class. Note that the parameter `self` needs to be used in the input parameters of all member functions and also while defining and using member variables.
6459
- Identify the common steps necessary in all the tests and transfer the functionality to the function `setUp`. One example of this is the definition of the object of class `SolveDiffusion2D`.
6560
- The main change is in the assertion statements. Change the assertion statements to the format as required by `unittest`. Refer to the lecture demo for an example on how to do this.
66-
- Using the same logic as in the previous step, intentionally break the tests to make sure that the tests are constructed correctly.
6761

68-
## Step 5 - Writing Integration Tests
62+
## Step 4 - Writing Integration Tests
6963

7064
- Write integration tests will be written for the functions `initialize_physical_parameters` and `set_initial_conditions`. As these are integration tests, each test should check how different functions from `SolveDiffusion2D` work together.
7165
- For example, let us look at how the test for `initialize_physical_parameters` will look like.
@@ -77,16 +71,16 @@ pytest tests/unit/test_diffusion2d_functions.py
7771
- Now also write a similar integration test for `set_initial_conditions`. Note that this will be the most extensive test from the whole set. The field variable `u` is computed in `set_initial_conditions`, which is a 2D array. The test should have a computation which computes a similar `u` array for a user-defined set of initial parameters. This computed `u` is the expected result.
7872
- Using the same logic as in the previous steps, intentionally break the tests to make sure that the tests are constructed correctly.
7973

80-
## Step 6 - Checking Test Coverage
74+
## Step 5 - Checking Test Coverage
8175

8276
- Using the coverage tool generate a HTML report of the code coverage of all the tests.
8377
- Open the report file in a browser and print the report to a file called `coverage-report.pdf`. Add this file to the repository.
8478

85-
## Step 7 - Automation Using tox
79+
## Step 6 - Automation Using tox
8680

8781
- Write a `tox.toml` file such that by running the command `tox`, the tests are run using pytest and/or unittest in separate virtual environments.
8882
- Use the `requirements.txt` file to send all the dependencies information to tox.
8983

90-
## Step 8 - Submission
84+
## Step 7 - Submission
9185

9286
- Open a pull request titled `[<your GitLab username>] Adding tests` (for example: `[desaiin] Adding tests`) from your fork to the main branch of the exercise repository.

0 commit comments

Comments
 (0)