วันพุธที่ 10 กุมภาพันธ์ พ.ศ. 2559

Test-Driven Development with Python - Chapter. 4

What Are We Doing with All These Tests?

      - ทำการแก้ไขไฟล์ functional_tests.py

 
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import unittest

class NewVisitorTest(unittest.TestCase):

    def setUp(self):
        self.browser = webdriver.Firefox()
        self.browser.implicitly_wait(3)

    def tearDown(self):
        self.browser.quit()

    def test_can_start_a_list_and_retrieve_it_later(self):
        # Edith has heard about a cool new online to-do app. She goes
        # to check out its homepage
        self.browser.get('http://localhost:8000')

        # She notices the page title and header mention to-do lists
        self.assertIn('To-Do', self.browser.title)
        header_text = self.browser.find_element_by_tag_name('h1').text
        self.assertIn('To-Do', header_text)

        # She is invited to enter a to-do item straight away
        inputbox = self.browser.find_element_by_id('id_new_item')
        self.assertEqual(
                inputbox.get_attribute('placeholder'),
                'Enter a to-do item'
        )

        # She types "Buy peacock feathers" into a text box (Edith's hobby
        # is tying fly-fishing lures)
        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)

        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)
        )

        # 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!')

        # The page updates again, and now shows both items on her list

if __name__ == '__main__':  
    unittest.main()  
 
ภาพ(ผลการrun functional_tests.py)

      - ใช้คำสั่ง git commit

 
$ git diff # should show changes to functional_tests.py  
$ git commit -am "Functional test now checks we can input a to-do item"
        
 ภาพ(ผลการใช้คำสั่ง git commit)   

  
  • The “Don’t Test Constants” Rule, and Templates to the Rescue

      - ทำการทดสอบ list/tests.py 

 
$ python manage.py test
        

ภาพ(ผลการทดสอบไฟล์ test.py)  

      - ทำการสร้างสร้างโฟล์เดอร์ใหม่ชื่อ templates ใน list และสร้างไฟล์ home.html และทำการแก้ไขไฟล์ list/templates/home.html ดังนี้ 
 
<html>
    <title>To-Do lists</title>
</html>
        
       - ทำการแก้ไขไฟล์ lists/views.py เพื่อจะใช้ทำการ render ไฟล์ home.html ขึ้นเป็นหน้า page html      
 
from django.shortcuts import render

def home_page(request):
    return render(request, 'home.html')
        
           - ทดสอบไฟล์ test

 ภาพ(ผลการทดสอบไฟล์ test.py) 

       - แก้ไขไฟล์ superlists/settings.py โดยการเพิ่ม list เข้าไป
 
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'lists',
)
        
           - ทำการทดสอบไฟล์ test  จะพบว่ามี Error เนื่องจากต้องมี </html>  
    ภาพ(ผลการทดสอบไฟล์ test.py)
        - แก้ไขไฟล์ lists/tests.py
 
from django.core.urlresolvers import resolve  
from django.test import TestCase  
from django.http import HttpRequest  
from lists.views import home_page  
class HomePageTest(TestCase):  
    def test_root_url_resolves_to_home_page_view(self):  
        found = resolve('/')  
        self.assertEqual(found.func, home_page) 

    def test_home_page_returns_correct_html(self):  
        request = HttpRequest() 
        response = home_page(request)  
        self.assertTrue(response.content.startswith(b'<html>')) 
        self.assertIn(b'<title>To-Do lists</title>', response.content)  
        #self.assertTrue(response.content.endswith(b'</html>')) 
        self.assertTrue(response.content.strip().endswith(b'</html>')) 
        
        - ทำการทดสอบไฟล์ test จะพบว่าการทำงานผ่านแล้ว 
 ภาพ(ผลการทดสอบไฟล์ test.py)

        - แก้ไขไฟล์ lists/tests.py เพื่อเป็นการเรียกใช้ไฟล์ templates
    ใน Django จะมีฟังก์ชั่น render_to_string ให้เรียกใช้ เพื่อให้บันทึกผลเป็น String
 
from django.template.loader import render_to_string
[...]

    def test_home_page_returns_correct_html(self):
        request = HttpRequest()
        response = home_page(request)
        expected_html = render_to_string('home.html')
        self.assertEqual(response.content.decode(), expected_html)
        
  • On Refactoring 
- ใช้คำสั่ง git status เพื่อดูสถานะไฟล์
- ใช้คำสั่ง git commit เพื่อ commit ว่า "Refactor home page view to use a template"
 
 $ git status # see tests.py, views.py, settings.py, + new templates folder  
 $ git add . # will also add the untracked templates folder  
 $ git diff --staged # review the changes we're about to commit  
 $ git commit -m"Refactor home page view to use a template"  
        



 ภาพ(ผลการใช่คำสั่งดังกล่าว)
  • A Little More of Our Front Page  
        - แก้ไขไฟล์ lists/templates/home.html
 
<html>
    <head>
        <title>To-Do lists</title>
    </head>
    <body>
        <h1>Your To-Do list</h1>
    </body>
</html>
        
             - ทำการทดสอบไฟล์ functional_tests.py  จะปรากฎหน้าต่าง browser ขึ้นมาและโปรแกรมจะแสดงผล Error ดังนี้ 
 
 $ python functional_tests.py
        
ภาพ(ผลการrun functional_tests.py)
 ภาพ(ผลการrun functional_tests.py) 

          - แก้ไขไฟล์ lists/templates/home.html
 
<html>
 <head>
  <title>To-Do lists</title>
 </head>
 <body>
  <h1>Your To-Do list</h1>
  <input id="id_new_item" />
 </body>
</html>
        
ภาพ(ผลการrun functional_tests.py) 

          - แก้ไขไฟล์ lists/templates/home.html
 
<html>
 <head>
  <title>To-Do lists</title>
 </head>
 <body>
  <h1>Your To-Do list</h1>
  <input id="id_new_item" placeholder="Enter a to-do item" />
 </body>
</html>
        
ภาพ(ผลการrun functional_tests.py)

 ภาพ(ผลการrun functional_tests.py)

          - แก้ไขไฟล์ lists/templates/home.html
 
<html>
 <head>
  <title>To-Do lists</title>
 </head>
 <body>
  <h1>Your To-Do list</h1>
  <input id="id_new_item" placeholder="Enter a to-do item" />
                <table id="id_list_table">
  </table>
 </body>
</html>
ภาพ(ผลการrun functional_tests.py)

          - ทำการ commit
 
 $ git diff
 $ git commit -am"Front page HTML now generated from a template"
           
ภาพ(ผลการ run $ git diff)


   - - - - - - - - - -