Code Coverage and Quality

Part 2, Chapter 2


In this chapter, we'll add code coverage via Coverage.py to the project.


Point the Docker client back to the localhost:

$ eval $(docker-machine env -u)

Update the containers:

$ docker-compose up -d

Ensure the app is working in the browser, and then run the tests:

$ docker-compose exec users python manage.py test

Code Coverage

Code coverage is the process of finding areas of your code not covered by tests. Coverage.py is a popular tool for measuring code coverage in Python-based applications.

Add Coverage.py to the requirements.txt file in the "users" directory:

coverage==4.5.3

Next, we need to configure the coverage reports in manage.py. Start by adding the configuration right after the imports:

COV = coverage.coverage(
    branch=True,
    include='project/*',
    omit=[
        'project/tests/*',
        'project/config.py',
    ]
)
COV.start()

Then add a new CLI command:

@cli.command()
def cov():
    """Runs the unit tests with coverage."""
    tests = unittest.TestLoader().discover('project/tests')
    result = unittest.TextTestRunner(verbosity=2).run(tests)
    if result.wasSuccessful():
        COV.stop()
        COV.save()
        print('Coverage Summary:')
        COV.report()
        COV.html_report()
        COV.erase()
        return 0
    sys.exit(result)

Don't forget the import!

import coverage

Update the containers:

$ docker-compose up -d --build

Run the tests with coverage:

$ docker-compose exec users python manage.py cov

You should see something like:

Coverage Summary:
Name                    Stmts   Miss Branch BrPart  Cover
---------------------------------------------------------
project/__init__.py        14      6      0      0    57%
project/api/models.py      14     11      0      0    21%
project/api/users.py       56      0     10      0   100%
---------------------------------------------------------
TOTAL                      84     17     10      0    82%

The HTML version can be viewed within the newly created "htmlcov" directory. With it, you can quickly see which parts of the code are, and are not, covered by a test.

$ open services/users/htmlcov/index.html

Add this directory to the .gitignore and .dockerignore files.

Just keep in mind that while code coverage is a good metric to look at, it does not measure the overall effectiveness of the test suite. In other words, having 100% coverage means that every line of code is being tested; it does not mean that the tests handle every scenario.

In other words, just because you have 100% test coverage doesn’t mean you're testing the right things.

Code Quality

Linting is the process of checking your code for stylistic or programming errors. Although there are a number of commonly used linters for Python, we'll use Flake8 since it combines two other popular linters—pep8 and pyflakes.

Add flake8 to the requirements.txt file in the "users" directory:

flake8===3.7.7

Update the containers:

$ docker-compose up -d --build

Run flake8:

$ docker-compose exec users flake8 project

Were any errors found?

project/api/users.py:30:9: E122 continuation line missing indentation or outdented
project/api/users.py:31:9: E122 continuation line missing indentation or outdented
project/api/users.py:32:5: E122 continuation line missing indentation or outdented
project/api/users.py:91:80: E501 line too long (80 > 79 characters)
project/tests/test_users.py:111:5: E303 too many blank lines (2)

Correct any issues before moving on. Commit your code, and push it to GitHub.

Black is another recommended tool, which is used for formatting your code so that "code looks the same regardless of the project you're reading". This helps to speed up code reviews. "Formatting becomes transparent after a while and you can focus on the content instead." Implement this on your own.




Mark as Completed