Discovering and running unit tests with pytest

Now, go to the restful01 folder that contains the manage.py file, with the virtual environment activated, and run the following command:

pytest

The pytest command and the Django REST framework will perform the following actions:

  1. Create a clean test database name test_drones.
  2. Run all the migrations required for the database.
  3. Discover the tests that have to be executed based on the settings specified in the pytest.ini file.
  4. Run all the methods whose name starts with the test_ prefix in the DroneCategoryTests class and display the results. We declared this class in the tests.py file and it matches the pattern specified for the python_files setting in the pytest.ini file.
  5. Drop the test database named test_drones.
It is very important to know that the tests won't make changes to the database we have been using when working with our RESTful Web Service. Notice that the test database name is test_drones and the database name that we have been using with Django's development server is drones.

The following screenshot shows a sample output generated by the pytest command:

The output indicated that the test runner collected and executed six tests and all of them passed. However, the output didn't show the names of the tests that passed. Hence, we will run pytest again with the -v option to increase verbosity. Run the following command:

pytest -v

The following screenshot shows a sample output generated by the pytest command with the increased verbosity:

We enabled verbose mode, and therefore, the new output displayed the full test names. Pytest displays the following information for each discovered and executed test: the Python file that defines it, the class name, and the method, such as the following line:

drones/tests.py::DroneCategoryTests::test_filter_drone_category_by_name PASSED [16%]

The line indicates that the test_filter_drone_category_by_name test method declared in the DroneCategoryTests class, within the drones/tests.py module has been executed, passed, and its execution represents 16% of the discovered tests.

The verbose mode makes it possible to know the specific tests that have been executed.

Some of the test methods include calls to the print function. By default, pytest captures both the stdout and stderr and only shows the captured content for the tests that fail. Sometimes, it is useful for us to see the results of calls to the print function while pytest runs the tests. We will run pytest again with -s option combined with the -v option to disable capturing and increase verbosity. Notice that the -s option is a shortcut that is equivalent to the -capture=no option. Run the following command:

pytest -vs

The following screenshot shows a sample output for the previous command:

The new output displayed the results of each call to the print function. In addition, we will notice that there are two messages displayed that are printed by Django, one line before the first test runs and another line after the last test finishes its execution:

Creating test database for alias 'default'...Destroying test database for alias 'default'...

These messages indicate that Django created the test database before running the first test and drops the database after all the tests have been executed.

The test_filter_drone_category_by_name test method declared in the DroneCategoryTests class has the following two calls to the print function:

url = '{0}?{1}'.format( 
    reverse(views.DroneCategoryList.name), 
    urlencode(filter_by_name)) 
print(url) 
response = self.client.get(url, format='json') 
print(response) 

The previous output shows the results of the two calls to the print function. First, the tests output display the value of the url variable with the composed URL and then the output shows the response of the call to self.client.get as a string:

drones/tests.py::DroneCategoryTests::test_filter_drone_category_by_name Creating test database for alias 'default'.../drone-categories/?name=Hexacopter<Response status_code=200, "application/json">PASSED     [ 16%]

In this case, the output is clear. However, as you might notice in the previous screenshot, the output generated by the other print statements is shown at the right-hand side of the test method name that was executed and it is not so clear. Hence, whenever we want to provide helpful output for tests, it is always a good idea to make sure we start with a new line ('n') and provide some context for the output we are displaying.

Now, we will replace the line that calls the print function in the test_post_and_get_drone_category method for the DroneCategoryTests class in the restful01/drones/tests.py file. The code file for the sample is included in the hillar_django_restful_10_02 folder in the restful01/drones/tests.py file. The replaced line is highlighted:

    def test_post_and_get_drone_category(self): 
        """ 
        Ensure we can create a new DroneCategory and then retrieve it 
        """ 
        new_drone_category_name = 'Hexacopter' 
        response = self.post_drone_category(new_drone_category_name) 
        print("nPK {0}n".format(DroneCategory.objects.get().pk)) 
        assert response.status_code == status.HTTP_201_CREATED 
        assert DroneCategory.objects.count() == 1 
        assert DroneCategory.objects.get().name == 
new_drone_category_name

Run the following command to execute pytest again with the -s and -v options combined:

pytest -vs

The following screenshot shows a sample output for the previous command:

The edits made in the call to the print statement that added a new line before and after the output made it easier to read the output. The generated output is highlighted in the previous screenshot. It is very important to take this formatting into account when working with pytest.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.40.177