从这一章就要学习
学习关键TDD技术: 使用递增的步进方式修改现有代码,保证代码在修改前后能正常运行。
回顾一下:现在我们的功能达成情况: 可以录入清单,可以查看清单(但是别人的清单也能查看)
1、来回顾目前我们的功能测试代码:
function_test.py
#coding=utf-8
from selenium import webdriver
from django.test import LiveServerTestCase
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import WebDriverException
MAX_WAIT = 10
import time
class NewVisitorTest(LiveServerTestCase):
def setUp(self):
self.browser = webdriver.Firefox()
def tearDown(self):
self.browser.quit()
def wait_for_row_in_list_table(self,row_text):
start_time = time.time()
while True:
try:
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]
)
return
except(AssertionError,WebDriverException) as e:
if time.time()-start_time > MAX_WAIT:
raise e
time.sleep(0.5)
def test_can_start_a_list_and_retrieve_it_later(self):
#小花听说有一个待办事项的网站很好
#她去看了这个应用的首页
self.browser.get(self.live_server_url)
#她注意到这个首页的标题和头部包含“To-Do”
self.assertIn("To-Do",self.browser.title)
header_text = self.browser.find_element_by_tag_name('h1').text
self.assertIn('To-Do',header_text)
#应用邀请她输入一个待办事项
inputbox = self.browser.find_element_by_id('id_new_item')
self.assertEqual(
inputbox.get_attribute("placeholder"),
'Enter a to-do item'
)
#她在文本框输入了"Buy woolen yarn " (购买毛线)
#她的爱好是织毛衣
#按回车键页面更新了
inputbox.send_keys("Buy woolen yarn")
inputbox.send_keys(Keys.ENTER)
# 待办事项中显示“1:Buy woolen yarn”
self.wait_for_row_in_list_table( "1:Buy woolen yarn")
#页面中又显示了一个文本框,可以输入其他待办事项
#她输入了"Knit a sweater with wool”(使用毛线织m毛衣)
inputbox = self.browser.find_element_by_id('id_new_item')
inputbox.send_keys("Knit a sweater with wool")
inputbox.send_keys(Keys.ENTER)
#页面再次跟新,他的清单中显示了这两个待办事项
# 待办事项中显示 1:Buy woolen yarn
# 2:Knit a sweater with wool
self.wait_for_row_in_list_table( "1:Buy woolen yarn")
self.wait_for_row_in_list_table( "2:Knit a sweater with wool")
self.fail("Finish the test")
#[..]
单元测试 test.py
from django.test import TestCase
from lists.models import Item
class HomePageTest(TestCase):
def test_uses_home_template(self):
response= self.client.get('/')
self.assertTemplateUsed(response,"home.html")
def test_can_save_a_POST_request(self):
response = self.client.post("/", data={'item_text':'A new list item'})
self.assertEqual(Item.objects.count(),1)
new_item = Item.objects.first()
self.assertEqual(new_item.text ,'A new list item')
def test_redirects_after_POST(self):
response = self.client.post('/',data={'item_text':'A new list item'})
self.assertEqual(response.status_code,302)
self.assertEqual(response['location'],'/')
def test_only_saves_items_when_necessary(self):
self.client.get('/')
self.assertEqual(Item.objects.count(), 0)
def test_displays_all_list_item(self):
Item.objects.create(text='itemey 1')
Item.objects.create(text='itemey 2')
response = self.client.get('/')
self.assertIn('itemey 1',response.content.decode())
self.assertIn('itemey 2',response.content.decode())
class ItemModelTest(TestCase):
def test_saving_and_retring_items(self):
first_item = Item()
first_item.text = "The first item list"
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 item list')
self.assertEqual(second_saved_item.text ,'Item the second')
views 视图代码:
from django.shortcuts import render, redirect
# Create your views here.
from lists.models import Item
def home_page(request):
if request.method == 'POST':
new_item_text = request.POST['item_text']
Item.objects.create(text=new_item_text)
return redirect('/')
items = Item.objects.all()
return render(request,'home.html',{'items':items})
login.html 文件
<html>
<head>
<title>To-Do list</title>
</head>
<body>
<h1> your To-Do list</h1>
<form method="POST">
{% csrf_token %}
<input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/>
</form>
<table id="id_list_table">
{% for item in items %}
<tr><td>{{ forloop.counter }}:{{ item.text }}</td></tr>
{% endfor %}
</table>
</body>
</html>