Wiring Up Our Form to Send a POST Request
แก้ไขไฟล์ lists/templates/home.html.
<h1>Your To-Do list</h1> <form method="POST"> <input name="item_text" id="id_new_item" placeholder="Enter a to-do item" /> </form> <table id="id_list_table">
รันไฟล์ Functional_test.py จะแสดงผลดังนี้ คือ โปรแกรม Error และไม่สามารถหาองค์ประกอบของ method : id , selector : id_list_table
$ python functional_tests.py E ====================================================================== ERROR: test_can_start_a_list_and_retrieve_it_later (__main__.NewVisitorTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "functional_tests.py", line 39, in test_can_start_a_list_and_retrieve_it_later table = self.browser.find_element_by_id('id_list_table') File "/usr/local/lib/python2.7/dist-packages/selenium-2.41.0-py2.7.egg/selenium/webdriver/remote/webdriver.py", line 199, in find_element_by_id return self.find_element(by=By.ID, value=id_) File "/usr/local/lib/python2.7/dist-packages/selenium-2.41.0-py2.7.egg/selenium/webdriver/remote/webdriver.py", line 655, in find_element {'using': by, 'value': value})['value'] File "/usr/local/lib/python2.7/dist-packages/selenium-2.41.0-py2.7.egg/selenium/webdriver/remote/webdriver.py", line 166, in execute self.error_handler.check_response(response) File "/usr/local/lib/python2.7/dist-packages/selenium-2.41.0-py2.7.egg/selenium/webdriver/remote/errorhandler.py", line 164, in check_response raise exception_class(message, screen, stacktrace) NoSuchElementException: Message: u'Unable to locate element: {"method":"id","selector":"id_list_table"}' ; Stacktrace: at FirefoxDriver.prototype.findElementInternal_ (file:///tmp/tmpVZoONB/extensions/fxdriver@googlecode.com/components/driver_component.js:8905) at fxdriver.Timer.prototype.setTimeout/<.notify (file:///tmp/tmpVZoONB/extensions/fxdriver@googlecode.com/components/driver_component.js:396) ---------------------------------------------------------------------- Ran 1 test in 17.221s FAILED (errors=1)
แก้ไขไฟล์ functional_tests.py.
# When she hits enter, the page updates, and now the page lists
# "1: Buy peacock feathers" as an item in a to-do list table
inputbox
.
send_keys
(
Keys
.
ENTER
)
import
time
time
.
sleep
(
10
)
table
=
self
.
browser
.
find_element_by_id
(
'id_list_table'
)
ทำการรันไฟล์ functional_test.py จะทำให้เกิด Error ดังนี้ คือ page จะแสดง CSRF Error
แก้ไขไฟล์ lists/templates/home.html เพื่อไม่ให้เกิด CSRF Error
<form
method=
"POST"
>
<input
name=
"item_text"
id=
"id_new_item"
placeholder=
"Enter a to-do item"
/>
{% csrf_token %}</form>
เมื่อทำการรันไฟล์ functional_test.py จะแสดง browser ขึ้นมา ทำให้เห็นว่าในช่องข้อความนั้นว่างเปล่า
และแสดงผลดังนี้ คือ ไม่พบรายการใหม่ในตาราง
$ python functional_tests.py F ====================================================================== FAIL: test_can_start_a_list_and_retrieve_it_later (__main__.NewVisitorTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "functional_tests.py", line 46, in test_can_start_a_list_and_retrieve_it_later "New to-do item did not appear in table" AssertionError: New to-do item did not appear in table ---------------------------------------------------------------------- Ran 1 test in 26.127s FAILED (failures=1)
แก้ไขไฟล์ functional_tests.py. โดยทำการลบ time.sleep ออก
# "1: Buy peacock feathers" as an item in a to-do list table
inputbox
.
send_keys
(
Keys
.
ENTER
)
table
=
self
.
browser
.
find_element_by_id
(
'id_list_table'
)
Processing a POST Request on the Server
จะเพิ่ม unit test อันใหม่สำหรับ home_page
แก้ไขไฟล์ lists/tests.py โดยจะแอด method เพิ่มเข้าไป ซึ่งก่อนหน้านี้ทำการปรับให้เพิ่มคำขอ POST และตรวจสอบการ return ของ HTML ว่าจะมีข้อความใหม่
def
test_home_page_returns_correct_html
(
self
):
[
...
]
def
test_home_page_can_save_a_POST_request
(
self
):
request
=
HttpRequest
()
request
.
method
=
'POST'
request
.
POST
[
'item_text'
]
=
'A new list item'
response
=
home_page
(
request
)
self
.
assertIn
(
'A new list item'
,
response
.
content
.
decode
())
ทำการรันไฟล์ test.py จะแสดงผลดังนี้คือ ไม่พบ A new list item
$ python manage.py test Creating test database for alias 'default'... F.. ====================================================================== FAIL: test_home_page_can_save_a_POST_request (lists.tests.HomePageTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/jutamas/Desktop/summer/superlists/lists/tests.py", line 37, in test_home_page_can_save_a_POST_request self.assertIn('A new list item', response.content.decode()) AssertionError: 'A new list item' not found in u'<html>\n <head>\n <title>To-Do lists</title>\n </head>\n <body>\n <h1>Your To-Do list</h1>\n <form method="POST">\n \t<input name="item_text" id="id_new_item" placeholder="Enter a to-do item" />\n \t\n\t</form>\n\n\t<table id="id_list_table">\n </table>\n </body>\n</html>\n' ---------------------------------------------------------------------- Ran 3 tests in 0.013s FAILED (failures=1) Destroying test database for alias 'default'...
เราจะทำการทดสอบให้ผ่านโดยการเพิ่มและให้ code path ที่แตกต่างกันสำหรับ POST request ในรูปแบบของ TDD เราจะเริ่มต้นด้วยการ return ค่า
แก้ไขไฟล์ lists/views.py
from
django.http
import
HttpResponse
from
django.shortcuts
import
render
def
home_page
(
request
):
if
request
.
method
==
'POST'
:
return
HttpResponse
(
request
.
POST
[
'item_text'
])
return
render
(
request
,
'home.html'
)
ทำการรันไฟล์ test.py จะแสดงผลการรันผ่านสำเร็จ
$ python manage.py test Creating test database for alias 'default'... ... ---------------------------------------------------------------------- Ran 3 tests in 0.005s OK Destroying test database for alias 'default'...
Passing Python Variables to Be Rendered in the Template
แก้ไขไฟล์ lists/templates/home.html เพื่อแสดง objects เป็นสตริง
<body>
<h1>
Your To-Do list</h1>
<form
method=
"POST"
>
<input
name=
"item_text"
id=
"id_new_item"
placeholder=
"Enter a to-do item"
/>
{% csrf_token %}</form>
<table
id=
"id_list_table"
>
<tr><td>
{{ new_item_text }}</td></tr>
</table>
</body>
แก้ไขไฟล์ lists/tests.py. ซึ่งจะทำการ render เป็นสตริง และทำการเปรียบเทียบกับ new item
self
.
assertIn
(
'A new list item'
,
response
.
content
.
decode
())
expected_html
=
render_to_string
(
'home.html'
,
{
'new_item_text'
:
'A new list item'
}
)
self
.
assertEqual
(
response
.
content
.
decode
(),
expected_html
)
ทำการรันไฟล์ test.py จะแสดงผล Error ดังนี้
$ python manage.py test Creating test database for alias 'default'... F.. ====================================================================== FAIL: test_home_page_can_save_a_POST_request (lists.tests.HomePageTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/jutamas/Desktop/summer/superlists/lists/tests.py", line 42, in test_home_page_can_save_a_POST_request self.assertEqual(response.content.decode(), expected_html) AssertionError: u'A new list item' != u'<html>\n <head>\n <title>To-Do lists</title>\n </head>\n <body>\n <h1>Your To-Do list</h1>\n <form method="POST">\n <input name="item_text" id="id_new_item" placeholder="Enter a to-do item" />\n \n </form>\n\n <table id="id_list_table">\n <tr><td>A new list item</td></tr>\n </table>\n </body>\n</html>\n' ---------------------------------------------------------------------- Ran 3 tests in 0.006s FAILED (failures=1) Destroying test database for alias 'default'...
แก้ไขไฟล์ lists/views.py
def
home_page
(
request
):
return
render
(
request
,
'home.html'
,
{
'new_item_text'
:
request
.
POST
[
'item_text'
],
})
รันไฟล์ test.py จะแสดง error ดังนี้คือ key error ที่ item_text
$ python manage.py test Creating test database for alias 'default'... .E. ====================================================================== ERROR: test_home_page_returns_correct_html (lists.tests.HomePageTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/jutamas/Desktop/summer/superlists/lists/tests.py", line 25, in test_home_page_returns_correct_html response = home_page(request) File "/home/jutamas/Desktop/summer/superlists/lists/views.py", line 6, in home_page 'new_item_text': request.POST['item_text'], KeyError: 'item_text' ---------------------------------------------------------------------- Ran 3 tests in 0.005s FAILED (errors=1) Destroying test database for alias 'default'...
แก้ไขไฟล์ lists/views.py เพื่อให้สามารถรันผ่าน
def
home_page
(
request
):
return
render
(
request
,
'home.html'
,
{
'new_item_text'
:
request
.
POST
.
get
(
'item_text'
,
''
),
})
ทำการรันไฟล์ test.py จะแสดงผลดังนี้ คือสามารถผ่าน
$ python manage.py test Creating test database for alias 'default'... ... ---------------------------------------------------------------------- Ran 3 tests in 0.007s OK Destroying test database for alias 'default'...
และทำการรันไฟล์ functional_test.py จะแสดงผลดังนี้คือ ไม่พบ New to-do item ไม่ปรากฏในตาราง
$ python functional_tests.py F ====================================================================== FAIL: test_can_start_a_list_and_retrieve_it_later (__main__.NewVisitorTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "functional_tests.py", line 44, in test_can_start_a_list_and_retrieve_it_later "New to-do item did not appear in table" AssertionError: New to-do item did not appear in table ---------------------------------------------------------------------- Ran 1 test in 5.958s FAILED (failures=1)
เราจะใช้ functional test เป็นเทคนิคการแก้ไขข้อผิดพลาด นี่อาจเป็นเทคนิคที่สร้างสรรค์ เพราะ การปรับปรุงข้อผิดพลาดจะอยู่รอบๆข้อความความ error และจะทำให้แก้ไขข้อผิดพลาดในอนาคตได้
แก้ไขไฟล์ functional_tests.py.
self
.
assertTrue
(
any
(
row
.
text
==
'1: Buy peacock feathers'
for
row
in
rows
),
"New to-do item did not appear in table -- its text was:
\n
%s
"
%
(
table
.
text
,
)
)
รันไฟล์ test.py จะแสดงผลดังนี้ คือ New to-do item ไม่พบในตาราง ข้อความจะเป็น Buy peacock feathers
$ python functional_tests.py F ====================================================================== FAIL: test_can_start_a_list_and_retrieve_it_later (__main__.NewVisitorTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "functional_tests.py", line 45, in test_can_start_a_list_and_retrieve_it_later table.text, AssertionError: New to-do item did not appear in table -- its text was: Buy peacock feathers ---------------------------------------------------------------------- Ran 1 test in 6.133s FAILED (failures=1)
ทำการแก้ไขไฟล์ functional_tests.py.
self
.
assertIn
(
'1: Buy peacock feathers'
,
[
row
.
text
for
row
in
rows
])
รันไฟล์ functional_test.py จะแสดงผลดังนี้
$ python functional_tests.py F ====================================================================== FAIL: test_can_start_a_list_and_retrieve_it_later (__main__.NewVisitorTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "functional_tests.py", line 42, in test_can_start_a_list_and_retrieve_it_later self.assertIn('1: Buy peacock feathers', [row.text for row in rows]) AssertionError: '1: Buy peacock feathers' not found in [u'Buy peacock feathers'] ---------------------------------------------------------------------- Ran 1 test in 6.205s FAILED (failures=1)
ทำการแก้ไขไฟล์ lists/templates/home.html. โดยใส่ข้อมูลเข้าไปในตาราง
<tr><td>
1: {{ new_item_text }}</td></tr>
ทำการรันไฟล์ functional_test.py จะแสดงผลดังนี้ คือจะรันผ่าน
$ python functional_tests.py F ====================================================================== FAIL: test_can_start_a_list_and_retrieve_it_later (__main__.NewVisitorTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "functional_tests.py", line 47, in test_can_start_a_list_and_retrieve_it_later self.fail('Finish the test!') AssertionError: Finish the test! ---------------------------------------------------------------------- Ran 1 test in 6.026s FAILED (failures=1)
ถ้าเราต้องการตรวจสอบรายการลำดับที่ 2 ในตาราง
ทำการแก้ไขไฟล์ functional_tests.py
# There is still a text box inviting her to add another item. She
# enters "Use peacock feathers to make a fly" (Edith is very
# methodical)
inputbox
=
self
.
browser
.
find_element_by_id
(
'id_new_item'
)
inputbox
.
send_keys
(
'Use peacock feathers to make a fly'
)
inputbox
.
send_keys
(
Keys
.
ENTER
)
# The page updates again, and now shows both items on her list
table
=
self
.
browser
.
find_element_by_id
(
'id_list_table'
)
rows
=
table
.
find_elements_by_tag_name
(
'tr'
)
self
.
assertIn
(
'1: Buy peacock feathers'
,
[
row
.
text
for
row
in
rows
])
self
.
assertIn
(
'2: Use peacock feathers to make a fly'
,
[
row
.
text
for
row
in
rows
]
)
# Edith wonders whether the site will remember her list. Then she sees
# that the site has generated a unique URL for her -- there is some
# explanatory text to that effect.
self
.
fail
(
'Finish the test!'
)
# She visits that URL - her to-do list is still there.
รันไฟล์ functional_test.py จะแสดงผลดังนี้
$ python functional_tests.py F ====================================================================== FAIL: test_can_start_a_list_and_retrieve_it_later (__main__.NewVisitorTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "functional_tests.py", line 55, in test_can_start_a_list_and_retrieve_it_later self.assertIn('1: Buy peacock feathers', [row.text for row in rows]) AssertionError: '1: Buy peacock feathers' not found in [u'1: Use peacock feathers to make a fly'] ---------------------------------------------------------------------- Ran 1 test in 6.297s FAILED (failures=1)
Three Strikes and Refactor
คำสั่ง git diff ดูการแก้ไขไฟล์
$ git diff diff --git a/functional_tests.py b/functional_tests.py index 5487abb..94ed2a3 100644 --- a/functional_tests.py +++ b/functional_tests.py @@ -36,19 +36,35 @@ class NewVisitorTest(unittest.TestCase): #1 # "1: Buy peacock feathers" as an item in a to-do list table inputbox.send_keys(Keys.ENTER) - table = self.browser.find_element_by_id('id_list_table') + table = self.browser.find_element_by_id('id_list_table') rows = table.find_elements_by_tag_name('tr') - self.assertTrue( - any(row.text == '1: Buy peacock feathers' for row in rows), - "New to-do item did not appear in table" - ) + self.assertIn('1: Buy peacock feathers', [row.text for row in rows]) # There is still a text box inviting her to add another item. She # enters "Use peacock feathers to make a fly" (Edith is very # methodical) - self.fail('Finish the test!') :
คำสั่ง git commit เพื่อคอมมิทการแก้ไขไฟล์
$ git commit -a [master 0cc6302] Test home page can save a POST request Committer: jutamas <jutamas@jutamas.(none)> Your name and email address were configured automatically based on your username and hostname. Please check that they are accurate. You can suppress this message by setting them explicitly: git config --global user.name "Your Name" git config --global user.email you@example.com After doing this, you may fix the identity used for this commit with: git commit --amend --reset-author 8 files changed, 110 insertions(+), 22 deletions(-)
กลับมาที่ functional test เราจะเพิ่ม method เข้าไปเพื่อช่วยในการจดจำ
แก้ไขไฟล์ functional_tests.py.
def
tearDown
(
self
):
self
.
browser
.
quit
()
def
check_for_row_in_list_table
(
self
,
row_text
):
table
=
self
.
browser
.
find_element_by_id
(
'id_list_table'
)
rows
=
table
.
find_elements_by_tag_name
(
'tr'
)
self
.
assertIn
(
row_text
,
[
row
.
text
for
row
in
rows
])
def
test_can_start_a_list_and_retrieve_it_later
(
self
):
[
...
]
แก้ไขไฟล์ functional_test.py
# When she hits enter, the page updates, and now the page lists
# "1: Buy peacock feathers" as an item in a to-do list table
inputbox.send_keys(Keys.ENTER)
self.check_for_row_in_list_table('1: Buy peacock feathers')
# There is still a text box inviting her to add another item. She
# enters "Use peacock feathers to make a fly" (Edith is very
# methodical)
inputbox = self.browser.find_element_by_id('id_new_item')
inputbox.send_keys('Use peacock feathers to make a fly')
inputbox.send_keys(Keys.ENTER)
# The page updates again, and now shows both items on her list
self.check_for_row_in_list_table('1: Buy peacock feathers')
self.check_for_row_in_list_table('2: Use peacock feathers to make a fly')
# Edith wonders whether the site will remember her list. Then she sees
[...]
รันไฟล์ functional_test.py จะแสดงผลดังนี้
$ python functional_tests.py F ====================================================================== FAIL: test_can_start_a_list_and_retrieve_it_later (__main__.NewVisitorTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "functional_tests.py", line 53, in test_can_start_a_list_and_retrieve_it_later self.check_for_row_in_list_table('1: Buy peacock feathers') File "functional_tests.py", line 17, in check_for_row_in_list_table self.assertIn(row_text, [row.text for row in rows]) AssertionError: '1: Buy peacock feathers' not found in [u'1: Use peacock feathers to make a fly'] ---------------------------------------------------------------------- Ran 1 test in 6.404s FAILED (failures=1)
คำสั่ง git diff เพื่อดูการแก้ไขไฟล์
$ git diff diff --git a/functional_tests.py b/functional_tests.py index 94ed2a3..d2643be 100644 --- a/functional_tests.py +++ b/functional_tests.py @@ -10,6 +10,11 @@ class NewVisitorTest(unittest.TestCase): #1 def tearDown(self): #3 self.browser.quit() + + def check_for_row_in_list_table(self, row_text): + table = self.browser.find_element_by_id('id_list_table') + rows = table.find_elements_by_tag_name('tr') + self.assertIn(row_text, [row.text for row in rows]) def test_can_start_a_list_and_retrieve_it_later(self): #4 # Edith has heard about a cool new online to-do app. She goes @@ -33,30 +38,20 @@ class NewVisitorTest(unittest.TestCase): #1 inputbox.send_keys('Buy peacock feathers') # When she hits enter, the page updates, and now the page lists - # "1: Buy peacock feathers" as an item in a to-do list table - inputbox.send_keys(Keys.ENTER) - :
คำสั่ง git commit คอมมิทการแก้ไขไฟล์
$ git commit -a [master 05d06bb] Three Strikes and Refactor Committer: jutamas <jutamas@jutamas.(none)> Your name and email address were configured automatically based on your username and hostname. Please check that they are accurate. You can suppress this message by setting them explicitly: git config --global user.name "Your Name" git config --global user.email you@example.com After doing this, you may fix the identity used for this commit with: git commit --amend --reset-author 2 files changed, 19 insertions(+), 19 deletions(-)
The Django ORM and Our First Model
แก้ไขไฟล์ lists/tests.py.
from
lists.models
import
Item
[
...
]
class
ItemModelTest
(
TestCase
):
def
test_saving_and_retrieving_items
(
self
):
first_item
=
Item
()
first_item
.
text
=
'The first (ever) list item'
first_item
.
save
()
second_item
=
Item
()
second_item
.
text
=
'Item the second'
second_item
.
save
()
saved_items
=
Item
.
objects
.
all
()
self
.
assertEqual
(
saved_items
.
count
(),
2
)
first_saved_item
=
saved_items
[
0
]
second_saved_item
=
saved_items
[
1
]
self
.
assertEqual
(
first_saved_item
.
text
,
'The first (ever) list item'
)
self
.
assertEqual
(
second_saved_item
.
text
,
'Item the second'
)
ทำการรันไฟล์ test.py จะแสดงผลดังนี้ คือ ไม่สามารถ import ชื่อ item ได้
$ python manage.py test Creating test database for alias 'default'... E ====================================================================== ERROR: lists.tests (unittest.loader.ModuleImportFailure) ---------------------------------------------------------------------- ImportError: Failed to import test module: lists.tests Traceback (most recent call last): File "/usr/lib/python2.7/unittest/loader.py", line 252, in _find_tests module = self._get_module_from_name(name) File "/usr/lib/python2.7/unittest/loader.py", line 230, in _get_module_from_name __import__(name) File "/home/jutamas/Desktop/summer/superlists/lists/tests.py", line 6, in <module> from lists.models import Item ImportError: cannot import name Item ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (errors=1) Destroying test database for alias 'default'...
แก้ไขไฟล์ lists/models.py.
from django.db import models class Item(object): pass
ทำการรันไฟล์ test.py จะแสดงผลดังนี้ คือ Item ไม่มี attribute 'save'
$ python manage.py test Creating test database for alias 'default'... ...E ====================================================================== ERROR: test_saving_and_retrieving_items (lists.tests.ItemModelTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/jutamas/Desktop/summer/superlists/lists/tests.py", line 50, in test_saving_and_retrieving_items first_item.save() AttributeError: 'Item' object has no attribute 'save' ---------------------------------------------------------------------- Ran 4 tests in 0.007s FAILED (errors=1) Destroying test database for alias 'default'...
แก้ไขไฟล์ lists/models.py.
from
django.db
import
models
class
Item
(
models
.
Model
):
pass
ทำการรันไฟล์ test lists จะแสดงผลดังนี้ คือ Item ไม่มี attribute 'text'
$ python manage.py test lists Creating test database for alias 'default'... ...E ====================================================================== ERROR: test_saving_and_retrieving_items (lists.tests.ItemModelTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/jutamas/Desktop/summer/superlists/lists/tests.py", line 61, in test_saving_and_retrieving_items self.assertEqual(first_saved_item.text, 'The first (ever) list item') AttributeError: 'Item' object has no attribute 'text' ---------------------------------------------------------------------- Ran 4 tests in 0.008s FAILED (errors=1) Destroying test database for alias 'default'...
แก้ไขไฟล์ lists/models.py.
class
Item
(
models
.
Model
):
text
=
models
.
TextField
()
ทำการรันไฟล์ test lists จะแสดงผลดังนี้ คือ รันผ่าน
$ python manage.py test lists Creating test database for alias 'default'... .... ---------------------------------------------------------------------- Ran 4 tests in 0.010s OK Destroying test database for alias 'default'...
ทำการเช็คสถานะไฟล์ แอด lists และ คอมมิทโดยใช้ชื่อ Model for list Items and associated migration
$ git status $ git diff $ git add lists $ git commit -m"
Model for list Items and associated migration"
Saving the POST to the Database
แก้ไขไฟล์ lists/tests.py. โดยเพิ่มฟังก์ชั่น test_home_page_can_save_a_POST_request(selft) เพื่อทดสอบว่าสามารถคำร้องขอได้หรือไม่
def
test_home_page_can_save_a_POST_request
(
self
):
request
=
HttpRequest
()
request
.
method
=
'POST'
request
.
POST
[
'item_text'
]
=
'A new list item'
response
=
home_page
(
request
)
self
.
assertEqual
(
Item
.
objects
.
count
(),
1
)
#
![]()
new_item
=
Item
.
objects
.
first
()
#
![]()
self
.
assertEqual
(
new_item
.
text
,
'A new list item'
)
#
![]()
self
.
assertIn
(
'A new list item'
,
response
.
content
.
decode
())
expected_html
=
render_to_string
(
'home.html'
,
{
'new_item_text'
:
'A new list item'
}
)
self
.
assertEqual
(
response
.
content
.
decode
(),
expected_html
)
ทำการรันไฟล์ test จะแสดงผลดังนี้ คือ 0 != 1
$ python manage.py test Creating test database for alias 'default'... F... ====================================================================== FAIL: test_home_page_can_save_a_POST_request (lists.tests.HomePageTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/jutamas/Desktop/summer/superlists/lists/tests.py", line 38, in test_home_page_can_save_a_POST_request self.assertEqual(Item.objects.count(), 1) #1 AssertionError: 0 != 1 ---------------------------------------------------------------------- Ran 4 tests in 0.009s FAILED (failures=1) Destroying test database for alias 'default'...
แก้ไขไฟล์ lists/views.py.
from
django.shortcuts
import
render
from
lists.models
import
Item
def
home_page
(
request
):
item
=
Item
()
item
.
text
=
request
.
POST
.
get
(
'item_text'
,
''
)
item
.
save
()
return
render
(
request
,
'home.html'
,
{
'new_item_text'
:
request
.
POST
.
get
(
'item_text'
,
''
),
})
ทำการรันไฟล์ test จะแสดงผลดังนี้คือ สามารถรันผ่าน
$ python manage.py test
Creating test database for alias 'default'...
....
----------------------------------------------------------------------
Ran 4 tests in 0.010s
OK
Destroying test database for alias 'default'...
แก้ไขไฟล์ lists/views.py.
return
render
(
request
,
'home.html'
,
{
'new_item_text'
:
item
.
text
})
ทำการรันไฟล์ test จะแสดงผลดังนี้ คือ รันผ่าน
$ python manage.py test Creating test database for alias 'default'... .... ---------------------------------------------------------------------- Ran 4 tests in 0.010s OK Destroying test database for alias 'default'...
แก้ไขไฟล์ lists/tests.py. ในคลาส HomePageTest เพิ่มฟังก์ชั่น test_home_page_only_saves_item_when_necessary(self):
class
HomePageTest
(
TestCase
):
[
...
]
def
test_home_page_only_saves_items_when_necessary
(
self
):
request
=
HttpRequest
()
home_page
(
request
)
self
.
assertEqual
(
Item
.
objects
.
count
(),
0
)
ทำการรันไฟล์ test จะแสดงผลดังนี้ คือ 1 != 0
$ python manage.py test Creating test database for alias 'default'... .F... ====================================================================== FAIL: test_home_page_only_saves_items_when_necessary (lists.tests.HomePageTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/jutamas/Desktop/summer/superlists/lists/tests.py", line 52, in test_home_page_only_saves_items_when_necessary self.assertEqual(Item.objects.count(), 0) AssertionError: 1 != 0 ---------------------------------------------------------------------- Ran 5 tests in 0.011s FAILED (failures=1) Destroying test database for alias 'default'...
แก้ไขไฟล์ lists/views.py.
def
home_page
(
request
):
if
request
.
method
==
'POST'
:
new_item_text
=
request
.
POST
[
'item_text'
]
#
![]()
Item
.
objects
.
create
(
text
=
new_item_text
)
#
![]()
else
:
new_item_text
=
''
#
![]()
return
render
(
request
,
'home.html'
,
{
'new_item_text'
:
new_item_text
,
#
![]()
})
ทำการรันไฟล์ test จะแสดงผลดังนี้ คือ สามารถรันผ่าน
$ python manage.py test Creating test database for alias 'default'... ..... ---------------------------------------------------------------------- Ran 5 tests in 0.012s OK Destroying test database for alias 'default'...
Redirect After a POST
def
test_home_page_can_save_a_POST_request
(
self
):
request
=
HttpRequest
()
request
.
method
=
'POST'
request
.
POST
[
'item_text'
]
=
'A new list item'
response
=
home_page
(
request
)
self
.
assertEqual
(
Item
.
objects
.
count
(),
1
)
new_item
=
Item
.
objects
.
first
()
self
.
assertEqual
(
new_item
.
text
,
'A new list item'
)
self
.
assertEqual
(
response
.
status_code
,
302
)
self
.
assertEqual
(
response
[
'location'
],
'/'
)
ทำการรันไฟล์ test จะแสดงผลดังนี้ คือ 200 != 302
$ python manage.py test Creating test database for alias 'default'... F.... ====================================================================== FAIL: test_home_page_can_save_a_POST_request (lists.tests.HomePageTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/jutamas/Desktop/summer/superlists/lists/tests.py", line 42, in test_home_page_can_save_a_POST_request self.assertEqual(response.status_code, 302) AssertionError: 200 != 302 ---------------------------------------------------------------------- Ran 5 tests in 0.010s FAILED (failures=1) Destroying test database for alias 'default'...
แก้ไขไฟล์ lists/views.py
from
django.shortcuts
import
redirect
,
render
from
lists.models
import
Item
def
home_page
(
request
):
if
request
.
method
==
'POST'
:
Item
.
objects
.
create
(
text
=
request
.
POST
[
'item_text'
])
return
redirect
(
'/'
)
return
render
(
request
,
'home.html'
)
ทำการรันไฟล์ test จะแสดงผลดังนี้ คือ รันผ่าน
$ python manage.py test Creating test database for alias 'default'... ..... ---------------------------------------------------------------------- Ran 5 tests in 0.012s OK Destroying test database for alias 'default'...
Better Unit Testing Practice: Each Test Should Test One Thing
แก้ไขไฟล์ lists/tests.py. def
test_home_page_can_save_a_POST_request
(
self
):
request
=
HttpRequest
()
request
.
method
=
'POST'
request
.
POST
[
'item_text'
]
=
'A new list item'
response
=
home_page
(
request
)
self
.
assertEqual
(
Item
.
objects
.
count
(),
1
)
new_item
=
Item
.
objects
.
first
()
self
.
assertEqual
(
new_item
.
text
,
'A new list item'
)
def
test_home_page_redirects_after_POST
(
self
):
request
=
HttpRequest
()
request
.
method
=
'POST'
request
.
POST
[
'item_text'
]
=
'A new list item'
response
=
home_page
(
request
)
self
.
assertEqual
(
response
.
status_code
,
302
)
self
.
assertEqual
(
response
[
'location'
],
'/'
)
ทำการรันไฟล์ test จะแสดงผลดังนี้คือ รันผ่าน
$ python manage.py test
Creating test database for alias 'default'...
......
----------------------------------------------------------------------
Ran 6 tests in 0.011s
OK
Destroying test database for alias 'default'...
Rendering Items in the Template
การแสดงรายการใน template
แก้ไขไฟล์ lists/tests.py
แก้ไขไฟล์ lists/tests.py
class
HomePageTest
(
TestCase
):
[
...
]
def
test_home_page_displays_all_list_items
(
self
):
Item
.
objects
.
create
(
text
=
'itemey 1'
)
Item
.
objects
.
create
(
text
=
'itemey 2'
)
request
=
HttpRequest
()
response
=
home_page
(
request
)
self
.
assertIn
(
'itemey 1'
,
response
.
content
.
decode
())
self
.
assertIn
(
'itemey 2'
,
response
.
content
.
decode
())
ทำการรันไฟล์ test จะแสดงผลดังนี้ คือ 'itemey 1' ไม่พบใน '<html>\n [...]
$ python manage.py test
Creating test database for alias 'default'...
.F.....
======================================================================
FAIL: test_home_page_displays_all_list_items (lists.tests.HomePageTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/jutamas/Desktop/summer/superlists/lists/tests.py", line 65, in test_home_page_displays_all_list_items
self.assertIn('itemey 1', response.content.decode())
AssertionError: 'itemey 1' not found in u'<html>\n <head>\n <title>To-Do lists</title>\n </head>\n <body>\n <h1>Your To-Do list</h1>\n <form method="POST">\n <input name="item_text" id="id_new_item" placeholder="Enter a to-do item" />\n \n </form>\n\n <table id="id_list_table">\n <tr><td>1: </td></tr>\n </table>\n </body>\n</html>\n'
----------------------------------------------------------------------
Ran 7 tests in 0.012s
FAILED (failures=1)
Destroying test database for alias 'default'...
แก้ไขไฟล์ lists/templates/home.html.
<table
id=
"id_list_table"
>
{% for item in items %}<tr><td>
1: {{ item.text }}</td></tr>
{% endfor %}</table>
แก้ไขไฟล์ lists/views.py.
def
home_page
(
request
):
if
request
.
method
==
'POST'
:
Item
.
objects
.
create
(
text
=
request
.
POST
[
'item_text'
])
return
redirect
(
'/'
)
items
=
Item
.
objects
.
all
()
return
render
(
request
,
'home.html'
,
{
'items'
:
items
})
เมื่อทำการรันไฟล์ functional_test แล้วจะมีหน้าบราวเซอร์ เด้งขึ้นมาดังรูป
และในโปรแกรมจะ Error ดังนี้
$ python functional_tests.py
F
======================================================================
FAIL: test_can_start_a_list_and_retrieve_it_later (__main__.NewVisitorTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "functional_tests.py", line 25, in test_can_start_a_list_and_retrieve_it_later
self.assertIn('To-Do', self.browser.title)
AssertionError: 'To-Do' not found in u'OperationalError at /'
----------------------------------------------------------------------
Ran 1 test in 5.945s
FAILED (failures=1)
Creating Our Production Database with migrate
การสร้างฐานข้อมูล
การสร้างฐานข้อมูล
แก้ไขไฟล์ superlists/settings.py
[
...
]
# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
DATABASES
=
{
'default'
:
{
'ENGINE'
:
'django.db.backends.sqlite3'
,
'NAME'
:
os
.
path
.
join
(
BASE_DIR
,
'db.sqlite3'
),
}
}
แก้ไขไฟล์ lists/templates/home.html.
{% for item in items %}<tr><td>
{{ forloop.counter }}: {{ item.text }}</td></tr>
{% endfor %}
ทำการลบดาต้าเบส และสร้างดาต้าเบสอันใหม่ขึ้นมาโดยใช้คำสั่ง
$ python manage.py syncdb
และทำการรันไฟล์ functional_tests จะมีหน้า browser เด้งขึ้นมาดังรูป
และโปรแกรมจะแสดงผลว่ารันผ่าน
$ python functional_tests.py
F
======================================================================
FAIL: test_can_start_a_list_and_retrieve_it_later (__main__.NewVisitorTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "functional_tests.py", line 59, in test_can_start_a_list_and_retrieve_it_later
self.fail('Finish the test!')
AssertionError: Finish the test!
----------------------------------------------------------------------
Ran 1 test in 7.346s
FAILED (failures=1)
ทำการคอมมิทโดยใช้ชื่อว่า "Redirect after Post, and sshow all item in template"
$ git commit -m"Redirect after Post, and show all items in template"
ไม่มีความคิดเห็น:
แสดงความคิดเห็น