Django Testing Tutorial with Pytest #2 - Unit Testing (2018)
Summary
TLDRThis tutorial offers a step-by-step guide on setting up and writing tests for a Django project. It begins with configuring a 'settings.py' file for testing, then moves on to creating test files for URLs, models, and views. The script demonstrates testing URL paths, model functions, and view access with both authenticated and unauthenticated users. It also touches on using the 'mixer' library for creating mock data and emphasizes the importance of testing to ensure project robustness.
Takeaways
- đ Start by setting up a file named 'pi_tests.py' in the home directory to specify the Django settings module for tests.
- đ§ Consider creating separate settings for production and testing to avoid issues like sending emails during tests.
- đ Create a 'test' folder to house all test files and a 'tests_urls.py' file to begin testing URLs.
- đ Use Django's 'reverse' function to get the URL path for a given view and 'resolve' to check if the URL resolves correctly to a view.
- đ Write test functions within a class dedicated to URL tests, ensuring each function has a single assert statement for clarity.
- đ ïž Utilize 'mixer' to create instances for testing model methods without manually specifying all model fields.
- đ Test model methods like 'is_in_stock' by creating product instances with varying quantities and asserting the correct outcomes.
- đ In 'tests_views.py', write tests for views ensuring they behave correctly with authenticated and unauthenticated users.
- đ€ Test views that require user authentication by mocking requests with an authenticated user and checking for the correct response.
- đ« For unauthenticated user tests, assert that the response redirects to the login page and contains the expected URL.
- đ Address database access issues in tests by using the '@pytest.mark.django_db' decorator to enable database access for test cases.
Q & A
What is the purpose of the 'PI tests.py' file in the Django testing setup described in the script?
-The 'PI tests.py' file is used to configure the test environment for a Django project. It specifies the settings module to be used for testing, which is typically different from the production settings to avoid side effects like sending out emails during tests.
Why is it recommended to create a separate settings file for testing in a production environment?
-Creating a separate settings file for testing in production helps to avoid unintended consequences such as sending emails or making changes to the database that could interfere with the live system.
What is the significance of the 'reverse' function in Django testing?
-The 'reverse' function in Django is used to obtain the URL path for a given view name and parameters. It's the equivalent of the URL in the templates and is used to ensure that the URLs are correctly resolving in tests.
What is the role of the 'resolve' function in the context of testing URLs in Django?
-The 'resolve' function is used to revert a URL path back to a view function. It's essentially the opposite of the 'reverse' function and helps in testing that the correct view is being called for a given URL.
Why is it suggested to have only one assert statement per test function, and when should you split it up?
-Having one assert statement per test function makes it easier to identify what each test is checking. If a test needs to perform more than one assertion, it's recommended to split it into multiple functions to keep the tests focused and easier to maintain.
What is the purpose of the 'mixer' library in the context of creating test instances for models in Django?
-The 'mixer' library is used to create test instances of models quickly and easily. It allows for the specification of which fields should be filled in, simplifying the process of setting up test data for unit tests.
How does the 'is_in_stock' function work in the product model, as described in the script?
-The 'is_in_stock' function in the product model checks whether the quantity of a product is greater than zero. If the quantity is greater than zero, it returns True, indicating that the product is in stock.
What does the 'Django DB mark' decorator do, and why is it used in the test functions?
-The 'Django DB mark' decorator is used to mark a test as requiring access to the database. It ensures that the test will run with a real database connection, which is necessary for tests that interact with the database.
Why is it important to test both authenticated and unauthenticated access to views in Django?
-Testing both authenticated and unauthenticated access ensures that the view behaves correctly under different user conditions. It helps to verify that authentication requirements are enforced and that unauthenticated users are redirected appropriately.
What is the expected outcome when an unauthenticated user tries to access a view that requires authentication in Django?
-When an unauthenticated user tries to access a view that requires authentication, the expected outcome is a redirect to the login page. The test should assert that the response includes a redirect to the login URL.
How can you measure test coverage in a Django project, as hinted at the end of the script?
-Test coverage in a Django project can be measured using tools like 'coverage.py', which analyzes the parts of the codebase that are covered by tests. The script suggests that future parts of the tutorial will delve into this topic.
Outlines
đ Setting Up Django Test Environment
This paragraph introduces the process of setting up a testing environment for a Django project. It begins by creating a 'PI tests.py' file in the home directory to specify the location of the settings file for the tests. The tutorial suggests using 'testing_top_settings' for the 'Django_settings_module'. It also mentions creating a separate settings file for production to avoid issues like sending out emails during testing. The focus then shifts to creating a 'test' folder and a 'tests_urls.py' file to start testing the URLs, specifically the 'intBK' path which is assumed to be working correctly. The paragraph explains the use of Django's 'reverse' and 'resolve' functions and outlines the structure of a test class and a test function to verify the URL path.
đ Testing Django URLs and Model Functions
The second paragraph delves into writing tests for URLs and model functions within a Django project. It describes importing necessary functions and setting up a test class for URL tests. The function 'test_detail_url' is explained, which uses the 'reverse' function to generate a URL path and the 'resolve' function to ensure the correct view is being called. The paragraph also covers the best practice of having a single assert statement per test function. Moving on to model testing, it introduces the 'test_models.py' file and the creation of a test function 'test_product_is_in_stock' using the 'mixer' library to create a product instance with a specific quantity. The function tests the 'is_in_stock' method of the product model, asserting its correctness based on the product's quantity.
đĄïž Authenticating User Access in Django Views Testing
The final paragraph focuses on testing user authentication in Django views. It outlines creating a test function 'test_product_detail_authenticated' to verify that authenticated users can access a specific view, which is protected by a 'login_required' decorator. The test involves using the 'RequestFactory' to create a request object with an authenticated user and then calling the 'product_detail' view function with this request. The response's status code is checked to ensure it's 200, indicating successful access. The paragraph also discusses handling database access issues during testing by using the '@django_db' decorator to mark tests that require database access. Additionally, it covers testing for unauthenticated users, expecting a redirect to the login page, and asserts that the login URL is part of the response's redirect chain.
Mindmap
Keywords
đĄDjango
đĄTesting
đĄPI tests
đĄURLs
đĄModels
đĄViews
đĄMixer
đĄRequest Factory
đĄTest Decorators
đĄRedirection
đĄAnonymous User
Highlights
Introduction to setting up a file called 'PI tests.py' for the initial testing setup in the home directory.
Explanation of specifying the Django settings module in the 'PI tests.py' file for testing purposes.
Creating a 'test' folder and a 'tests_urls.py' file to begin testing the application's URLs.
Importing 'reverse' and 'resolve' functions from Django's 'urls' for URL testing.
Writing a test class 'testURLs' for organizing URL tests within.
Testing the 'detail' URL using the 'reverse' function and checking its correctness with 'resolve'.
Running the first test with 'Python manage.py test' and observing the test execution.
Creating a 'tests_models.py' file for model testing and focusing on the 'is_in_stock' function.
Utilizing the 'mixer' library to create product instances for testing the 'is_in_stock' method.
Writing unit tests to check both true and false conditions for the 'is_in_stock' function.
Using the 'Django DB' mark to handle database access in tests.
Creating a 'test_views.py' file to test views, starting with the 'product detail' view for authenticated users.
Mocking a request with an authenticated user to test the 'product detail' view's access control.
Asserting the correct status code (200) for the 'product detail' view when accessed with proper authentication.
Testing the 'product detail' view with unauthenticated users and expecting a redirect to the login page.
Asserting that the redirect URL contains 'accounts/login' for unauthenticated access attempts.
Demonstration of running the test server and manually verifying the redirect behavior in a browser.
Invitation for feedback on the tutorial series and a teaser for the next part on test coverage measurement.
Transcripts
hey ole I hope your day is going great
and in this tutorial we will start by
writing our first tests so the very
first thing we need to do is set up a
file called PI tests though in E and
this file just sits in the home
directory and this is where we are going
to tell PI tests where our settings file
will be located so start with PI tests
in these square brackets and then you
can specify the Django underscore
settings module and I'm just going to
set it to testing top settings which is
- standard settings fyra here and if I
were in production now I would probably
create another one just for testing
because you know if you're sending out
emails or something like that it could
mess up but um that will be fine for now
and then we can go into the product and
first of all create a new folder and
call it test which is where all of our
test files are going to sit and then
create a new file and the first thing we
want to test out the URLs so I'm going
to name this file tests underscore URLs
but PI let's just go back to the US of
Pi file so see what's going on so
basically you want to test this path
right here because this one is just
default from Jenga and we'll just assume
that it works fine so we want to test
that this int BK path will always work
and as you can see we have assigned the
name of detail to it so that will also
help now while testing and first things
first we want to import from Django tour
URLs the functions called reverse and
resolve and we're going to discuss what
they do in a second and I'm going to
start out with the class called test
URLs and this is where all of our tests
for the URLs are going to set in this
class right here and then we want to
write a function and call the test
underscore detail URL so in this one we
are simply just going to test detail URL
and a very good practice is to have one
assert statement perform
so if more than that you should probably
split it up into two functions and it
takes on yourself and now we can first
of all get the part of the URL so set
the path equal to reverse detail and the
reverse function is simply just the
equivalent of the URL in the templates
so we pass at the name and then it gives
us the path back and as you can see in
this case a path is a parameter so
that's why we also have to pass it one
value for it and I'm gonna set the
keyword arguments equal to PK which is
how we named it and then it expects an
integer and this one will be one because
that's the standard integer for one
object and it's where the auto increment
field starts and then simply we can
assert that the resolved path don't view
name is equal to detail and resolved
path basically just or the resolved
function in general takes in a path and
then from there reverts back to the
function so it's kind of the opposite of
the reverse function and then we simply
call the view name and assert that we
are calling the correct function so that
will be it basically a for this function
and go back to your command line now and
now you can run Python tests and it kind
of takes a moment yeah and you will see
that our test ran through a my goal with
this part and the next part will be
really to get you guys up and running as
quickly as possible and after that we
are going to dig deeper into files like
this one and understand what's going on
right here but I really want to get you
up and running as quickly as possible so
you can start running your unit tests so
next up we have the models which we need
to test as well so create a new file
called tests underscore models stop key
Y and we're going to do the inputs in a
second first of all start with the class
of test
and that's just a convention I like to
use basically just with the perfect of
tests and then whatever I'm going to
test so in this case we want to create a
function and call it tests underscore
product is in stock text itself you can
remember in the model so PI we had a
function called isn't stock so that's
what we are going to test with this unit
tests and now we have to create a
scenario where we are going to assert
that the function works correctly so we
want to basically create a product
instance and as you can see a result of
the isn't stock function just depends on
the quantity so that's what we are going
to mimic and we could do it in a way
where we say like product equals product
the object stop great and then pass all
of the you know fields manually but that
will create a lot of overheat because we
really only want the quantity field and
that's the only thing that matters what
this test really and that's why we
imported or why we installed mix in the
last part because mixer allows us to
basically just say mixer blend and then
we can specify the the name of the app
which is product and then dot D model
which is product and then we can pass
all of the fields which we want to have
fixed in this case it's only quantity
and sell equal to one and now we want to
assert that whenever I call D is in stop
function on this product it returns true
because of course it's greater than zero
and that was our definition of returning
true
so assert that product though is in
stock is in stock is equal to true and
now we are going to make the imports so
from products products top models import
product oh actually we don't need
product yeah because we're using yeah we
don't need that from mixer top back end
django import mixer
now go back into your comment on and you
will see an error if we run it because
we are we don't have database access so
we can as you can see it already gives
us defects which is to use Django DB
mark and we are going to get into easy
ways of fixing that later on but for now
just import PI test and then we can add
it directly to the class instead of on
top of every single function so simply
use a decorator height as marked or
Django DB any will see that we ran it
successfully and if we we're to assert
that this should be false we would we
should get an error and with you so
that's working fine and then I'm simply
just going to copy this whole function
and then paste it right underneath and
call the test product is not in stock
and in this case we want to set the
quantity equal to 0 and then assert that
it's false because of course we are
returning saft or quality is greater
than zero and in this case it is zero so
that should be false and yet that works
as well now we can also create a new
file and name a test and go use the fire
and this is where our view tests are
going to set again start off with the
class of tests views and now we can
create a function called test product
detail authenticated clicking the self
and in this function we want to test
whether we can exercise when we are
authenticated because as you can
remember inside of the views file we
specified the log-in required decorator
to be able to access this view and of
course we want to make sure that it does
what we wanted to do so first of all we
want to test it with the authenticated
State and what we have to do in this
case is set a path equal to reverse
detail and again pass the keyword
piqué goes to one you already had that
and now we want to set the request equal
to requests factory so we are just
creating a new instance don't get which
is a method on the request factory
object half and then we want to modify
the request to passing the authenticated
user so simply set request the user
equal to mixer blend user so that
creates a new user instance and now we
want to gather the response because
we're just really mocking the access of
a view so set the response equal to
product detail and of course product
detail is the function which we have
inside of the views this one and as you
can see it expects a request and a
private key we already created the
request so we can simply pass it a
request and any private key of one and
now we want to assert that a response
top status code is equal to 200 so that
it ran through correctly and we can next
up make all of the inputs which we need
to first of all from general test input
the requests factory package then from
general URLs we want to import reverse
from Django contrib but all the models
we want to import in user model except
what we that is what we are using right
here can remove these quotes actually we
don't need them and then from products
top views we want to import the product
detail and of course we are using mix as
well so from from mixer or back end or
Django want to import mixer
and now go back into your comment line
and run PI test and again the database
access failed so just import PI test and
then we can add the PI test or marked or
Django DB no product matches to given
query of course it doesn't because we
try to give it the private key of one
one but we don't have a product which
has the property of one so we just are
going to make an instance of a product
and by default it's going to start with
the private key of one just mix it all
blend products top product let's check
work now
and yeah it runs through and now we want
to basically do the same thing with
unauthenticated users so def test
product detail when we are fun Senta
kated Oh
what is going on yeah I'm just good to
unauthenticated and the only thing we
want to change really is this request so
user inside it equal to anonymous user
and we can import this one from the
models as well
anonymous user and actually it running
that's right like this and you will see
that we should get a three or two error
and yeah we do because that's the
standard code for a temporary redirect
because after that we obviously want to
get back or we want to get redirected
back to the normal view as soon as we
logged in so the 302 redirect really
just redirects us to the login view and
from that it redirects us back to the
view we actually want to access but
instead of doing that we are just going
to assert that accounts login is inside
of the response dot URL
and yet works and just for demonstration
purposes I'm just going to run it server
and I'm now going to exit it on my
browser and if we we're now to go to
slash one you will see that we get
redirected to accounts logon and all we
are doing in the test is basically just
asserting that this redirect which just
happened will always happen with this
accounts login in the URL and that was
fine so I'm going to call it quits for
this part make sure to tell me the
comments down below what you want to see
inside of the series and what I can help
you with so stay tuned for the next part
where we are going to dig a bit deeper
in how you can measure your test
coverage and assert that everything
inside of your daring or project is
going to be tested and yeah see you then
Cheers
Voir Plus de Vidéos Connexes
Django Testing Tutorial with Pytest #1 - Setup (2018)
Curso Sistema de Ventas en ASP.NET Core 6 y SQL Server - Parte 06
How to test React apps with Vitest and Vite
Affiliate Marketing For Beginners (2024)
How to Make an Animated Cartoon Video Using Al
đ€ High-Salary Job with this Django Roadmap? | Advanced Django Developer roadmap || Code with SJ
5.0 / 5 (0 votes)