Django Testing Tutorial with Pytest #3 - Coverage (2018)

The Dumbfounds
2 Apr 201808:12

Summary

TLDRThis video tutorial teaches viewers how to refactor common setup code into functions and measure test coverage in Django. It demonstrates using the 'setUpClass' method to streamline test setup, reducing redundancy and improving performance. The video also guides on setting up a test coverage report with 'coverage', customizing it to exclude unnecessary files, and viewing results in an HTML format for a clear understanding of code execution coverage.

Takeaways

  • 🔧 Extract common setup code into its own function to improve code organization and performance.
  • 📈 Use Django's TestCase for unit testing to gain access to the 'setUpClass' method for shared setup tasks.
  • 📝 Call the 'super().setUpClass()' to ensure the base class's setup is executed before custom setup code.
  • 🔄 Instantiate shared objects like 'requestfactory' once in 'setUpClass' to avoid redundancy and improve efficiency.
  • 📑 Utilize 'setUpClass' as a decorator to ensure the method is run once for the class, not every time a test is executed.
  • 📊 Set up test coverage reports to measure the effectiveness of your tests and identify untested code.
  • 🛠️ Install necessary packages to enable test coverage reporting if not already present in your environment.
  • 📋 Use the 'coverage' flag with 'pytest' to generate a coverage report, indicating the percentage of code executed during tests.
  • 📁 Exclude irrelevant files such as test files, migrations, and certain configuration files from the coverage report for accuracy.
  • 📝 Create a '.coveragerc' file to specify directories and files to omit from the coverage report for cleaner results.
  • 🌐 Use 'pytest' options like '--cov-report=html' to export the coverage report in an HTML format for easy visualization.
  • 🔄 Regularly review and adjust test coverage to ensure all critical parts of the application are adequately tested.

Q & A

  • What is the main purpose of the video?

    -The video teaches viewers how to refactor common setup code into a separate function and how to measure test coverage in a Django project.

  • Why is it necessary to extract the mixer of blend line code into a separate function?

    -Extracting the mixer of blend line code into a separate function is necessary because it's not part of the main function's behavior but is required for the code to run successfully, avoiding failures due to missing objects with a private key of one.

  • What is the benefit of instantiating the requestfactory object only once?

    -Instantiating the requestfactory object only once improves performance, especially when there are many test functions, as it reduces the overhead of creating the object multiple times.

  • How does the 'setup_class' method in Django's TestCase work?

    -The 'setup_class' method in Django's TestCase is a class method that runs before all other test methods in the class. It is used for setting up code that needs to be executed once for the entire test class.

  • What is the purpose of the 'super' function in the 'setup_class' method?

    -The 'super' function is used to call the 'setup_class' method of the parent class (TestCase) to ensure that any setup actions defined in the parent class are also executed.

  • Why is it important to measure test coverage in a project?

    -Measuring test coverage is important to ensure that the codebase is adequately tested. It helps identify untested parts of the code which could lead to potential bugs or issues in production.

  • What does the '--coverage' flag do when running tests with 'manage.py test'?

    -The '--coverage' flag generates a test coverage report, showing which parts of the code are covered by tests and which are not.

  • How can you specify which files to exclude from the test coverage report?

    -You can specify files to exclude from the test coverage report by setting the 'omit' option in the '.coveragerc' file to the paths of the directories or files you want to omit.

  • What is the benefit of exporting the test coverage report to an HTML format?

    -Exporting the test coverage report to an HTML format makes it easier to navigate and visually inspect which parts of the code are covered by tests. It also provides a more user-friendly way to review the report.

  • How can you open and view the HTML coverage report in an editor like Atom?

    -You can open and view the HTML coverage report in Atom by installing the 'atom-html-preview' package, then opening the 'index.html' file and using the shortcut 'Ctrl + Shift + H' to preview it.

  • What should you consider when deciding which files to include or exclude from test coverage measurement?

    -You should consider excluding files that do not require testing, such as test files themselves, migration files, and certain configuration files like 'wsgi.py'. These files are typically not the focus of test coverage as they are either tested by definition or do not contain executable business logic.

Outlines

00:00

🔧 Refactoring and Test Coverage in Django

This paragraph discusses the process of refactoring common setup code into a separate function to improve performance and maintainability in Django. It explains how to use the `setUpClass` method from Django's TestCase to instantiate objects like the RequestFactory only once for all test methods within a class. The speaker also demonstrates how to use the `@classmethod` decorator to pass class parameters effectively. The focus then shifts to measuring test coverage using the `coverage` flag with `pytest`, showing how to generate a comprehensive report and how to adjust settings to exclude unnecessary files from the coverage analysis.

05:02

📊 Enhancing Test Coverage Reporting

The second paragraph delves into enhancing the test coverage report by using an Atom plugin for HTML preview, which allows for a more user-friendly way to view the coverage report. It describes how to install the Atom HTML preview plugin and use it to open the index.html file generated by the test coverage tool. The paragraph further explains how to exclude test files from the coverage report by creating a `.codecovrc` file with the `omit` key set to specific directories. The speaker illustrates the impact of including or excluding these files on the coverage percentage and emphasizes the importance of maintaining a clean and accurate test coverage report for better code quality assurance.

Mindmap

Keywords

💡Function

In the context of the video, a 'function' refers to a block of organized, reusable code that is used to perform a single, related action. The script discusses extracting common setup code into its own function to improve code organization and performance. For example, the script mentions creating a function to instantiate the 'requestfactory' object, which is used in multiple places, to avoid redundancy and enhance efficiency.

💡Test Coverage

Test coverage is a measure used in software testing to describe the degree to which the source code of a program is tested by a particular set of test cases. The script explains how to measure test coverage using the 'coverage' flag with the 'pytest' command, which helps identify untested parts of the code. The video demonstrates achieving 100% test coverage, indicating that every part of the code has been executed by the test suite.

💡Mixer

In the script, 'mixer' refers to a specific line of code that is used to create an object with a private key of one. It is mentioned as a part of the setup code that is not directly related to the main function's behavior but is necessary for the tests to run successfully. The script suggests that this line should be moved to a setup function to avoid repetition.

💡RequestFactory

The 'RequestFactory' is a class in Django's testing framework that allows for the creation of request objects in tests. The script discusses the instantiation of this object multiple times and suggests extracting its creation into a setup function to improve performance and reduce redundancy. This is demonstrated by assigning 'RequestFactory' to a variable 'factory' and using it in test functions.

💡Setup Class

The 'setup class' method in the script refers to a special method in Django's testing framework that is run before any tests in a test class are executed. It is used to set up any necessary preconditions for the tests. The script explains how to use the 'setup class' method to instantiate objects that are used across multiple test functions, thus ensuring they are only created once.

💡Subclass

In object-oriented programming, a 'subclass' is a class that is derived from another class, known as the superclass. The script mentions subclassing from 'TestCase' to gain access to the 'setup class' method. This is a way to extend the functionality of the existing 'TestCase' class with custom setup logic for the tests.

💡Django

Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. The script refers to Django's default unit test module, which is used for writing and running tests in a Django project. The video demonstrates how to integrate Django's testing framework with pytest for improved testing capabilities.

💡Performance

In the context of the video, 'performance' refers to the efficiency and speed of executing code, particularly in the context of running tests. The script suggests improvements to enhance performance, such as reducing the instantiation of objects like 'RequestFactory' to once per test class, rather than multiple times per test function.

💡HTML Coverage Report

An 'HTML coverage report' is a detailed report generated by the coverage tool, which is presented in HTML format for easy visualization of test coverage. The script explains how to generate this report using the '--coverage-report=HTML' option with the 'pytest' command, allowing developers to view which parts of the code have been tested and which have not.

💡Atom Plugin

In the script, an 'Atom plugin' refers to an extension for the Atom text editor that adds functionality or enhances the user experience. The video mentions the 'atom-html-preview' plugin, which allows for the convenient viewing of HTML files, such as the coverage report, directly within the Atom editor.

💡.coveragerc

The '.coveragerc' file is a configuration file used by the coverage tool to specify settings for generating coverage reports. The script explains how to create and use this file to omit certain directories, like 'tests' and 'migrations', from the coverage report, focusing only on the parts of the codebase that are relevant for testing.

Highlights

Learning to extract common setup code into its own function for efficiency.

Understanding the importance of creating an object with a private key of one for successful test execution.

Instantiating the requestfactory object in multiple places for performance improvement.

Using Django's standard unit test module with pytest for better test management.

Subclassing from TestCase to access the setUpClass method for setup code execution.

Calling the actual setUpClass of the TestCase to ensure proper setup sequence.

Instantiating the requestfactory object once to avoid redundancy and enhance performance.

Utilizing the setUpClass decorator to automate class parameter passing.

Running tests with the --coverage flag to measure test coverage.

Achieving 100% test coverage as indicated by the coverage report.

Excluding unnecessary files like manage.py and wsgi.py from test coverage calculation.

Configuring pytest to add options for consistent test coverage reporting.

Exporting coverage reports into HTML format for easier visualization.

Using an Atom plugin for HTML preview to conveniently view coverage reports.

Creating a .coveragerc file to specify directories to omit from coverage reports.

Ensuring test files and migrations are excluded from the coverage report for accuracy.

Demonstrating the impact of not having test coverage with a drop to 95% coverage.

Highlighting the necessity of test coverage for identifying untested code segments.

Encouraging viewers to stay tuned for the next part covering fixtures in testing.

Transcripts

play00:00

here you all I hope your day's going

play00:01

great in this video you will learn how

play00:03

to extract common set up code into their

play00:06

own function and how to measure test

play00:08

coverage as you can see we are using

play00:11

this mixer of blend line twice right

play00:13

here and right here as well and really

play00:16

it's not part of the main function

play00:18

behavior it's just some code that we

play00:20

need in order to run this line because

play00:23

as you can see we are relying on having

play00:25

an object with the private key of one

play00:26

and if we didn't run this line to create

play00:30

one with the private key of one then

play00:31

there wouldn't be would be none so of

play00:33

course it will fail and also we are

play00:36

instantiating the requestfactory object

play00:38

in on in two different places and you

play00:41

know there's some room for improvement

play00:42

as well in regards to performance so PI

play00:46

test works quite well with the standard

play00:48

unit test module which django uses by

play00:50

default and we can go to the top and

play00:54

import test case so that's inside of

play00:58

Jenga your test you can just import test

play01:01

case and then from our class you can

play01:05

subclass from test case and by doing so

play01:09

we are granted access to a method which

play01:12

is called setup class and everything

play01:15

that we put inside of that function will

play01:17

be running every you know before running

play01:20

all of these other functions inside of

play01:22

this class so def setup class and this

play01:28

one takes in the extra class instance

play01:30

and first of all we need to call the

play01:33

actual setup class of this test case and

play01:35

to get access to that we need to call

play01:37

super test views and passing the class

play01:41

don't set up class and this really just

play01:46

calls set up class of this test case and

play01:49

then we can override everything that we

play01:52

want to do after that and the first

play01:55

thing is this line because that you know

play01:58

we only need to instantiate it once

play02:00

really because we are using the same

play02:02

object here and here both should have

play02:04

deprived give one get rid of that one

play02:10

and then also this requestfactory we can

play02:13

extract that and now we want to set plus

play02:18

though I'm just going to call this

play02:20

factory equal to request factory and

play02:23

then inside of our single functions we

play02:26

can call self the factory and in here

play02:31

also self or factory and that should

play02:34

work and now what we need to do is if

play02:37

this set up plus the decorative class

play02:40

method and this is because we want to

play02:44

get the class you know parameter passed

play02:46

and the class method will take care of

play02:49

that for us

play02:49

and now we can just enter the terminal

play02:53

again and run high test and as you can

play02:58

see it still runs the same way it did

play03:00

before only that we are instantiating

play03:02

the requestfactory object once and also

play03:04

this mix it up plan once and if we have

play03:06

like one or two hundred separate test

play03:08

functions it should run faster this way

play03:10

because we are only doing once as I said

play03:13

so next up we want to setup the test

play03:16

coverage report and for this one we

play03:18

already install the package in the first

play03:20

part so just simply go into your time

play03:23

terminal and now you can type in high

play03:26

test and at the - - coverage flag and as

play03:32

you can see we get a total coverage

play03:34

report and the courage is at 100% and

play03:37

all of the files which are being tested

play03:39

are displayed for him and there's one

play03:43

more option we can set which is pi test

play03:45

test coverage and then we can set it

play03:48

equal to a path which we want specified

play03:50

and if we set it to dot it will get all

play03:54

of the files but as you can see there

play03:56

are three files which have a zero

play03:58

percent test coverage which are managed

play04:00

of Pi and F so pi and also this WSGI

play04:04

dope fire and these three files really

play04:07

we don't want tested so that will you

play04:09

know Titus is smart enough to figure

play04:11

that out that we shouldn't test these

play04:13

and it doesn't by default so that will

play04:16

be fine and so we don't need to specify

play04:18

the - - coverage option every time we

play04:21

can go into the PI test or any file

play04:23

and use the add options adopts fork

play04:27

short and set it equal to - - coverage

play04:30

and then we can specify another argument

play04:33

called - - coverage report equal to HTML

play04:38

and this will basically just take care

play04:40

of exporting our entire coverage report

play04:43

into HTML format and then it will give

play04:46

us a file or a directory as you're going

play04:49

to see in a minute so now back in the

play04:52

terminal we only need to run my test and

play04:56

as you can see we get this HTML coverage

play04:59

folder and inside of that is an indexed

play05:02

or HTML file and I found that the most

play05:04

convenient way of opening this is to use

play05:06

an atom plug-in if you haven't insulted

play05:08

already you can just go to file then to

play05:11

settings and to install and then you

play05:14

just simply search for atom HTML preview

play05:18

and then hit install on this one and if

play05:24

that's is done you can open the

play05:26

index.html file and to simply hit ctrl

play05:29

shift + H and if you did that correctly

play05:33

you should see this when they're popping

play05:34

up and we get our entire coverage report

play05:37

and just can browse all of the files and

play05:40

see which ones are being executed but of

play05:43

course we don't want to test the

play05:44

coverage of our test files because that

play05:46

wouldn't really make any sense because

play05:48

that should always be one percent

play05:50

basically because those are the files

play05:51

that are always being executed by us

play05:54

running the tests so just go back and

play05:57

I'm just going to close this file and

play05:59

the PATA so any file and then we can go

play06:03

into the main directory and create

play06:04

another file called dot coverage RC and

play06:08

this one also uses to draw any syntax

play06:11

and any syntax works by first of all

play06:14

specifying a section and this one is

play06:17

called run and then we have normal key

play06:21

value pairs and the key in this case is

play06:23

going to be the omit and we can set it

play06:26

equal to all of the directories we want

play06:28

to omit from a coverage report and those

play06:31

are first of all star slash tests and

play06:34

everything that is inside of the tests

play06:37

factories in general should be avoided

play06:39

and then we also have the migrations

play06:44

which we don't really need to include in

play06:47

our test coverage report and that should

play06:49

basically be it because of course the

play06:51

WSGI to pi EPSA player manager pi should

play06:54

be excluded by default and just open it

play06:58

up again

play06:59

and run PI test then we can go back into

play07:04

the HTML coverage folder and just open

play07:07

up in next door HTML again by pressing

play07:08

ctrl shift

play07:10

H and you will see that we successfully

play07:13

in got rid of T test files in our test

play07:16

coverage report and you know that's

play07:19

about it for this part we set up test

play07:21

coverage so you can measure all of the

play07:23

tests and I'm just going to show you

play07:25

real quickly how that would look if we

play07:27

didn't have one upset test coverage so

play07:30

just get rid of these two functions and

play07:34

run then run pi test any see it dropping

play07:39

down to 95% and this user profile only

play07:43

as 67% can open that one and you can see

play07:47

these two lines mark red because these

play07:49

ones weren't executed of course because

play07:51

we don't have tests for them but if we

play07:53

insert them back again and rerun pi test

play07:57

we get 100% as we want it so make sure

play08:01

to stick around for the next part where

play08:03

we are probably going to be covering

play08:05

fixtures and until then make sure to

play08:08

leave a like if you enjoyed and Cheers

Rate This

5.0 / 5 (0 votes)

Étiquettes Connexes
Django TestingCode OptimizationTest CoveragePerformance ImprovementSetup FunctionsRequestFactoryUnitTest ModuleHTML ReportsCoverage AnalysisTesting Best Practices
Besoin d'un résumé en anglais ?