Difference between revisions of "Python-Django/C2/Testing-in-Django/English"
Pravin1389 (Talk | contribs) |
Nancyvarkey (Talk | contribs) |
||
Line 25: | Line 25: | ||
|| To record this tutorial, I am using | || To record this tutorial, I am using | ||
− | * '''Ubuntu Linux OS | + | * '''Ubuntu Linux OS''' 16.04 |
− | * '''Python | + | * '''Python''' 3.5 |
* '''Python 3.4-venv''' or higher and | * '''Python 3.4-venv''' or higher and | ||
* '''gedit Text Editor ''' | * '''gedit Text Editor ''' | ||
Line 41: | Line 41: | ||
|| | || | ||
− | * | + | * '''Automated testing''' is very useful while coding |
* We can validate our code during the '''development stage''' itself | * We can validate our code during the '''development stage''' itself | ||
* It is preferred to write '''tests''' in '''Django''' using the '''unit test module''' | * It is preferred to write '''tests''' in '''Django''' using the '''unit test module''' | ||
Line 49: | Line 49: | ||
Press CTRl+ALT+T simultaneously | Press CTRl+ALT+T simultaneously | ||
− | ||Let us open the '''terminal '''by pressing '''Ctrl | + | ||Let us open the '''terminal '''by pressing '''Ctrl, Alt''' and '''T '''keys simultaneously on the keyboard. |
|- | |- | ||
|| [Terminal] | || [Terminal] | ||
Line 57: | Line 57: | ||
|- | |- | ||
|| [Terminal] Type: source myapp_env/bin/activate and press Enter | || [Terminal] Type: source myapp_env/bin/activate and press Enter | ||
− | || Activate the '''virtual | + | || Activate the '''virtual environment.''' |
|- | |- | ||
Line 118: | Line 118: | ||
'''from blog.models import Blog''' | '''from blog.models import Blog''' | ||
− | || So, after the '''TestCase''' | + | || So, after the '''TestCase import''', we will import the '''Blog model.''' |
|- | |- | ||
|| [tests.py] Highlight | || [tests.py] Highlight | ||
Line 177: | Line 177: | ||
|- | |- | ||
|| Only narration | || Only narration | ||
− | || Let us now run the '''test.''' | + | || Let us now '''run''' the '''test.''' |
|- | |- | ||
|| Switch to Terminal | || Switch to Terminal | ||
Line 185: | Line 185: | ||
Type python manage.py test blog [Enter] | Type python manage.py test blog [Enter] | ||
− | || Then type | + | || Then type '''python <space> manage dot py <space> test <space> blog''' |
− | + | ||
− | + | ||
− | + | ||
|- | |- | ||
|| [Terminal] Output: | || [Terminal] Output: | ||
Line 211: | Line 209: | ||
self.assertEqual(blog.name, name)''' | self.assertEqual(blog.name, name)''' | ||
− | || '''Test ''' | + | || '''Test ran''' successfully as the first and second '''arguments '''which were passed, are equal. |
|- | |- | ||
|| Switch to blog/tests.py | || Switch to blog/tests.py | ||
− | || The '''Test''' we ran is very minor. | + | || The '''Test''' we '''ran''' is very minor. |
So, let us add another '''test case''' for '''blog app.''' | So, let us add another '''test case''' for '''blog app.''' | ||
Line 234: | Line 232: | ||
'''blog = Blog.objects.get(id=1)''' | '''blog = Blog.objects.get(id=1)''' | ||
− | || Get the '''Blog object''' to '''test''' by passing the '''id''' and assigning it to the | + | || Get the '''Blog object''' to '''test''' by passing the '''id''' and assigning it to the '''variable blog.''' |
|- | |- | ||
|| [tests.py] Highlight | || [tests.py] Highlight | ||
Line 246: | Line 244: | ||
|| Here in '''assertEqual '''the first '''argument''' is a '''method call.''' | || Here in '''assertEqual '''the first '''argument''' is a '''method call.''' | ||
− | The '''method''' is '''was_created_recently '''and it is expected to | + | The '''method''' is '''was_created_recently '''and it is expected to '''return True.''' |
So our second '''argument''' is a '''boolean True.''' | So our second '''argument''' is a '''boolean True.''' | ||
Line 317: | Line 315: | ||
return self.created_on '''>=''' timezone.now() - timezone.timedelta(days=1) | return self.created_on '''>=''' timezone.now() - timezone.timedelta(days=1) | ||
− | || | + | || Now in the '''method was_created_recently '''under the '''Class Blog''', change the '''less than''' sign to '''greater than.''' |
− | + | ||
− | + | ||
|- | |- | ||
|| Press Ctrl+S | || Press Ctrl+S | ||
Line 338: | Line 334: | ||
Highlight '''assertTrue()''' | Highlight '''assertTrue()''' | ||
− | || Here '''assertTrue method''' is used to check the test the expression is '''TRUE''' | + | || Here '''assertTrue method''' is used to check the test that the expression is '''TRUE''' |
|- | |- | ||
|| Press Ctrl+S | || Press Ctrl+S | ||
Line 358: | Line 354: | ||
|| Slide: Assertions | || Slide: Assertions | ||
|| | || | ||
+ | https://docs.djangoproject.com/en/2.1/topics/testing/tools/#assertions | ||
− | * '''Django TestCase''' provides | + | * '''Django TestCase''' provides '''assertion methods''' |
* These are useful for '''testing web applications''' | * These are useful for '''testing web applications''' | ||
* Here is the reference link to the documentation of '''methods''' | * Here is the reference link to the documentation of '''methods''' | ||
− | |||
− | |||
|- | |- | ||
|| Switch to blog/tests.py | || Switch to blog/tests.py | ||
Line 415: | Line 410: | ||
'''blog2 = Blog.objects.get(id=2)''' | '''blog2 = Blog.objects.get(id=2)''' | ||
− | || Here we get the '''blog object '''2 that we created in the '''setUp().''' | + | || Here we get the '''blog object '''2 that we created in the '''setUp() method.''' |
|- | |- | ||
|| [tests.py] Highlight | || [tests.py] Highlight | ||
'''self.assertFalse(blog2.was_created_recently())''' | '''self.assertFalse(blog2.was_created_recently())''' | ||
− | || Let us use '''assertFalse method''' for our '''blog object 2''' in our''' was_created_recently function.''' | + | || Let us use '''assertFalse method''' for our '''blog object 2''' in our '''was_created_recently function.''' |
|- | |- | ||
|| [tests.py] Highlight | || [tests.py] Highlight | ||
'''assertFalse''' | '''assertFalse''' | ||
− | || Here '''assertFalse method''' is checks the test the expression is False | + | || Here '''assertFalse method''' is checks the test the expression is '''False'''. |
|- | |- | ||
|| Press Ctrl+S | || Press Ctrl+S | ||
Line 431: | Line 426: | ||
|- | |- | ||
|| Switch to terminal | || Switch to terminal | ||
− | || Switch to '''terminal''' | + | || Switch to '''terminal'''. |
|- | |- | ||
|| [Terminal]Type | || [Terminal]Type | ||
Line 438: | Line 433: | ||
|| Let us now '''run''' a particular '''test case'''. | || Let us now '''run''' a particular '''test case'''. | ||
− | To do that, we have to write the '''method''' name like this | + | To do that, we have to write the '''method''' name like this. |
|- | |- | ||
|| [Terminal] Highlight | || [Terminal] Highlight | ||
Line 485: | Line 480: | ||
|- | |- | ||
|| [Terminal] Type deactivate [Enter] | || [Terminal] Type deactivate [Enter] | ||
− | || | + | || Let us now deactivate the '''virtual environment.''' |
|- | |- | ||
|| Slide: Test Database | || Slide: Test Database | ||
|| | || | ||
− | |||
* '''Test runner''' will create an empty '''test database''' with required '''migrations.''' | * '''Test runner''' will create an empty '''test database''' with required '''migrations.''' | ||
* By default, '''database''' will be deleted if all '''tests''' are executed or if '''assertion error''' is raised. | * By default, '''database''' will be deleted if all '''tests''' are executed or if '''assertion error''' is raised. | ||
− | |||
|- | |- | ||
|| Slide: SetUp and Teardown methods | || Slide: SetUp and Teardown methods | ||
|| | || | ||
− | + | * '''SetUp''' and '''TearDown methods''' are '''run''' before and after every '''test''' respectively. | |
− | * | + | |
* This allows you to set up a basic '''context''' or '''environment''' inside each of the '''tests.''' | * This allows you to set up a basic '''context''' or '''environment''' inside each of the '''tests.''' | ||
− | |||
− | |||
|- | |- | ||
|| Slide: SetUp method | || Slide: SetUp method | ||
|| | || | ||
− | |||
* '''SetUp method runs''' before every '''test.''' | * '''SetUp method runs''' before every '''test.''' | ||
− | |||
|- | |- | ||
|| Slide: TearDown method | || Slide: TearDown method | ||
|| | || | ||
− | + | * '''TearDown method''' will only be '''called''' if the '''setUp() '''succeeds. | |
− | * | + | |
− | + | ||
|- | |- | ||
Line 531: | Line 517: | ||
|| Slide: Assignment | || Slide: Assignment | ||
|| As an assignment, | || As an assignment, | ||
− | |||
* Write a '''test case''' for '''Article model''' and '''run''' the '''test.''' | * Write a '''test case''' for '''Article model''' and '''run''' the '''test.''' | ||
Latest revision as of 15:01, 14 October 2019
Django/C2/Testing in Django/English
Title of script: Testing in Django
Keywords: Video tutorial, Django write test, Django run test
Visual cue | Narration |
Slide: Writing Tests in Django | Hello and welcome to the spoken tutorial on “Testing in Django“ |
Slide: Learning Objectives | In this tutorial, we will learn to
|
Slide: System Requirements | To record this tutorial, I am using
|
Slide: Prerequisites | To follow this tutorial, you need to know
|
Slide: Testing in Django |
|
Open a Terminal window
Press CTRl+ALT+T simultaneously |
Let us open the terminal by pressing Ctrl, Alt and T keys simultaneously on the keyboard. |
[Terminal]
cd my-django [Enter] |
Using the cd command, go to the folder my hyphen django |
[Terminal] Type: source myapp_env/bin/activate and press Enter | Activate the virtual environment. |
[Terminal] cd mysite and Press Enter | Now go to the mysite folder using cd command |
Here onwards, please remember to press the Enter key after typing each command. | |
[Terminal]
Type gedit blog/tests.py & [Enter] |
Let us write the test case for our blog app.
Type gedit <space> blog slash tests dot py <space> ampersand |
[tests.py]
Highlight from django.test import TestCase #Create your tests here. |
We are now in tests.py file
Here we import TestCase from Django’s test module. TestCase is a subclass of unit test. A test case checks whether a given set of inputs leads to an expected set of results. |
[tests.py] Type:
class BlogTestCase(TestCase): def setUp(self): Blog.objects.create(name='New Blog') def test_blog_created(self): blog = Blog.objects.get(id=1) name = 'New Blog' self.assertEqual(blog.name, name) |
Let us now add a class BlogTestCase as shown here. |
[tests.py]
Highlight class BlogTestCase(TestCase): |
Here, we have created a class BlogTestCase to test our Blog model.
It is a subclass of TestCase. |
[tests.py] Highlight
from django.test import TestCase |
class TestCase is used for writing tests in Django. |
[tests.py] Type:
from blog.models import Blog |
So, after the TestCase import, we will import the Blog model. |
[tests.py] Highlight
def setUp(self): |
Whenever the test runs, first it will call the setUp method.
setUp runs once for every test method to setup clean data. |
[tests.py]
Highlight Blog.objects.create(name= 'New Blog') |
So in the setUp, a blog is created. |
[tests.py] Highlight
def test_blog_created(self): |
Here a method test_blog_created is defined to test the blog which is created. |
[tests.py]
Highlight def test_blog_created(self): |
class TestCase methods begins with the name test.
Django’s test runner runs these test methods. |
[tests.py] Highlight
blog = Blog.objects.get(id=1) |
Here we get the blog object that we created in the setUp(). |
[tests.py]
Highlight id=1 |
ids are uniquely generated for each blog.
But in complex cases, many blogs are created and deleted. |
[tests.py] Highlight name = 'New Blog' | Let’s define a variable as string “New Blog”. |
[tests.py]
Highlight self.assertEqual(blog.name, name) |
assertEqual is a method provided by TestCase.
It checks whether the two arguments passed here are equal or not. Here we have passed the blog name and expected string New Blog. If the condition does not evaluate as expected, then the test will fail and report the error. |
Highlight the complete code | Now, we have added a TestCase. |
Press Ctrl+S | Save the file. |
Only narration | Let us now run the test. |
Switch to Terminal | Switch to the terminal. |
[Terminal]
Type python manage.py test blog [Enter] |
Then type python <space> manage dot py <space> test <space> blog |
[Terminal] Output:
Creating test database for alias 'default'... System check identified no issues (0 silenced). ------------------------------------------------------------- Ran 1 test in 0.002sOKDestroying test database for alias 'default'... |
Here, we can see the output. |
[tests.py] Highlight
def test_blog_created(self): blog = Blog.objects.get(id=1) name = 'New Blog' self.assertEqual(blog.name, name) |
Test ran successfully as the first and second arguments which were passed, are equal. |
Switch to blog/tests.py | The Test we ran is very minor.
So, let us add another test case for blog app. |
[tests.py]Type:
def test_was_created_recently(self): blog = Blog.objects.get(id=1) is_created_recently = True self.assertEqual(blog.was_created_recently(), is_created_recently) |
Add a method in BlogTestCase as shown here. |
[tests.py] Highlight
blog = Blog.objects.get(id=1) |
Get the Blog object to test by passing the id and assigning it to the variable blog. |
[tests.py] Highlight
is_created_recently = True |
Assign the value True to is_created_recently |
[tests.py] Highlight
self.assertEqual (blog.was_created_recently(), is_created_recently) |
Here in assertEqual the first argument is a method call.
The method is was_created_recently and it is expected to return True. So our second argument is a boolean True. |
Press Ctrl+S | Save the file. |
Switch to Terminal | Switch to the terminal. |
[Terminal] Type python manage.py test blog [Enter] | Now, recall the previous command to run the test. |
[Terminal] Output: Ran 2 tests in 0.003s | The output says, Ran 2 tests.
assertEqual function in method test_was_created_recently returns TRUE. As the two arguments passed are equal, the 2nd test also ran successfully. |
[Terminal] | Next open the models.py file.
We will change the logic of was_created_recently method in this file. |
[Terminal]
Type gedit blog/models.py & [Enter] |
Type gedit <space> blog slash models dot py <space> ampersand |
[models.py]Type:
def was_created_recently(self): return self.created_on <= timezone.now() - timezone.timedelta(days=1) |
We are now in models.py file.
In the class blog, locate the was_created_recently method. In the return statement, change the sign greater than to less than. |
[models.py] Highlight
return self.created_on <= timezone.now() - timezone.timedelta(days=1) |
Since the blog object was not created recently, the method returns False. |
Press Ctrl+S | Save the file. |
Switch to Terminal | Switch to the terminal. |
[Terminal] Type python manage.py test blog [Enter] | And run the test again. |
[Terminal] Output: AssertionError: False!= True | The output shows an assertion error.
was_created_recently method returns False instead of True. This shows the power of having tests. In case anyone modifies the code incorrectly later on, then the tests will help to detect it. |
Switch to models.py | Switch back to models.py file to revert the changes. |
[models.py] Highlight
return self.created_on >= timezone.now() - timezone.timedelta(days=1) |
Now in the method was_created_recently under the Class Blog, change the less than sign to greater than. |
Press Ctrl+S | Save the file. |
[tests.py] Type:
def test_was_created_recently(self): blog = Blog.objects.get(id=1) self.assertTrue(blog.was_created_recently()) |
Switch to the tests.py file.
In the function test_was_created_recently, modify the code as shown. |
[tests.py]
Highlight assertTrue() |
Here assertTrue method is used to check the test that the expression is TRUE |
Press Ctrl+S | Save the file. |
Switch to Terminal | Switch to the terminal. |
[Terminal] Type python manage.py test blog [Enter] | And run the test app. |
[Terminal] Highlight
Ran 2 tests in 0.003s OK |
The test ran without any errors, satisfying the given condition. |
Slide: Assertions |
https://docs.djangoproject.com/en/2.1/topics/testing/tools/#assertions
|
Switch to blog/tests.py | Switch to tests.py file. |
[tests.py]
from blog.models import Blog # Create your tests here.
def setUp(self): Blog.objects.create(name='Blog1') Blog.objects.create(name='Blog2')
blog = Blog.objects.get(id=1) name = 'New Blog' self.assertEqual(blog.name, name)
blog1 = Blog.objects.get(id=1) blog2 = Blog.objects.get(id=2) self.assertTrue(blog1.was_created_recently()) self.assertFalse(blog2.was_created_recently()) |
Modify the code as shown here. |
[tests.py] Highlight
Blog.objects.create(name='Blog2') |
Here, we created a blog object blog 2 in setUp() method. |
[tests.py] Highlight
blog2 = Blog.objects.get(id=2) |
Here we get the blog object 2 that we created in the setUp() method. |
[tests.py] Highlight
self.assertFalse(blog2.was_created_recently()) |
Let us use assertFalse method for our blog object 2 in our was_created_recently function. |
[tests.py] Highlight
assertFalse |
Here assertFalse method is checks the test the expression is False. |
Press Ctrl+S | Save the file. |
Switch to terminal | Switch to terminal. |
[Terminal]Type
python manage.py test blog.tests.BlogTestCase.test_was_created_recently [Enter] |
Let us now run a particular test case.
To do that, we have to write the method name like this. |
[Terminal] Highlight
AssertionError: True is not False |
On execution, we can see the output for the test case.
AssertionError raised an error message True is not False. This is because the was_created_recently returns TRUE and we are expecting FALSE. |
Switch to blog/tests.py | Switch to tests.py file to correct the assertion error. |
[tests.py]
def test_was_created_recently(self): blog1 = Blog.objects.get(id=1) blog2 = Blog.objects.get(id=2) self.assertTrue(blog1.was_created_recently()) self.assertTrue(blog2.was_created_recently()) |
Change assertFalse to assertTrue. |
Press Ctrl+S | Save the file. |
Switch to terminal | Switch to terminal. |
[Terminal]
Type python manage.py test blog.tests.BlogTestCase.test_was_created_recently [Enter] |
And execute the specific test case again. |
[Terminal]
Highlighting the output |
The test ran successfully without any assertion errors. |
Switch to Terminal | This is how we should perform the testing in Django. |
[Terminal] Type deactivate [Enter] | Let us now deactivate the virtual environment. |
Slide: Test Database |
|
Slide: SetUp and Teardown methods |
|
Slide: SetUp method |
|
Slide: TearDown method |
|
With this, we come to the end of this tutorial.
Let us summarize. | |
Slide: Summary | In this tutorial, we have learnt to
|
Slide: Assignment | As an assignment,
|
Slide: About Spoken Tutorial project | The video at the following link summarises the Spoken Tutorial project.
|
Slide: Spoken Tutorial workshops | TheSpoken Tutorial Projectteam conducts workshops and gives certificates.
|
Slide: Forum for specific questions: | Please post your timed queries in this Forum. |
Slide: FOSSEE to answer questions | Please post your general or technical questions in this Forum. |
Slide: Acknowledgement | Spoken Tutorial Project is funded by NMEICT, MHRD, Government of India.
More information on this mission is available at this link. |
Slide: Thanks Slide | This script has been contributed by Thiagarajar College of Engineering and the FOSSEE Project, IIT Bombay.
The video has been recorded by Praveen from Spoken Tutorial Project, IIT Bombay. Thanks for watching. |