3.5 购物车模块
购物车模块包括“购物车中所有商品的显示”“添加商品进入购物车”“删除购物车中某种商品”“删除购物车中所有的商品”和“修改购物车中某种商品的数量”。
在程序中采取cookie的形式来存储购物车中的内容,大家都知道,一个cookie是一个值参对,在参数中存放商品的id,通过商品的id从数据库中查询对应的商品信息。在值中存放商品的数量,初始化的时候为1,然后在查看购物车中内容页面中提供修改购物车内商品数量的功能。
购物车模块不具有数据模型。
3.5.1把商品放入购物车
1. urls.py
... url(r'^add_chart/(?P<good_id>[0-9]+)/(?P<sign>[0-9]+)/$', views.add_chart), ...
(1)good_id为商品的id。
(2) sign=1表示从商品列表添加进入的商品,sign=2表示从商品详情添加进入的商品。
2. views.py
... # 放入购物车 def add_chart(request,good_id,sign): util = Util() username = util.check_user(request) if username=="": uf = LoginForm() return render(request,"index.html",{"error":"请登录后再进入"}) else: #获得商品详情 good = get_object_or_404(Goods,id=good_id) #如果sign=="1",返回商品列表页面 if sign=="1": response = HttpResponseRedirect('/goods_view/') #否则返回商品详情页面 else: response = HttpResponseRedirect('/view_goods/'+good_id) #把当前商品添加进购物车,参数为商品id,值为购买商品的数量,默认为1,有效时间为一年 response.set_cookie(str(good.id),1,60*60*24*365) return response ...
(1)注册用户登录以后,通过语句good = get_object_or_404(Goods,id=good_id)获取添加进购物车中商品的信息变量。
(2)通过语句response.set_cookie(str(good.id),1,60*60*24*365)把商品放入购物车,实现方式是利用cookie,其中cookie的key为商品的id。str(good.id) 为购物车中商品的初始数量,默认为1、有效时间为一年,即60*60*24*365(单位为秒)。
(3)把商品添加进购物车后,页面通过语句count = util.cookies_count(request)来实现自动更新当前购物车中的商品数量。
在goods/util.py中cookies_count()方法的具体代码。
... #返回购物车内商品的个数 def cookies_count(self,request): #返回本地所有的cookie cookie_list = request.COOKIES #只要进入网站,系统中就会产生一个名为sessionid的cookie #如果后台同时在运行,会产生一个名为csrftoken的cookie if "csrftoken" in cookie_list: return len(request.COOKIES)-2 else:
在本书第1.3.4节中已经介绍了sessionId,现在再回顾一下。sessionId是一个会话的key,目的是解决原始HTTP协议的无状态性。浏览器在第一次访问服务器的时候会在服务器端生成一个session,并且有一个sessionId和它对应。不同的Web服务器对于sessionId有着不同的解释,比如Tomcat生成的sessionId叫做jsessionId。当客户端第一次请求session对象时,服务器会为客户端创建一个session,并将通过特殊算法算出一个session的ID,用来标识该session对象。另外还有一个系统可能产生的cookie名为csrftoken,当setting.py中启动CSRF防御的时候,这个cookie就会产生。所以代码在计算购物车中商品数量的时候要将这两个cookie给去除,其中sessionId的cookie是肯定会产生的,所以直接去除就可以了,而csrftoken的cookie是需要开启CSRF防御的时候才会产生,所以通过条件语句if "csrftoken" in cookie_list来进行判断。
3.模板
放入购物车以后,在页面上会自动更新显示购物车中商品的数量,在这里不需要提供专门的模板,在任何登录后的菜单栏中均可以显示。如图3-14,在菜单“查看购物车”右边所示。
图3-14显示购物车内商品的数量
4.接口测试
1)测试用例
表3-7为放入购物车的测试用例,通过商品列表页面或者商品详细页面把商品放入购物车,购物车内的商品数量是否会有相应地增加。
表3-7 放入购物车测试用例
编号 |
描述 |
期望结果 |
1 |
添加一个商品进购物车 |
添加成功,购物车内的商品数量会有相应地增加 |
在这里测试思想是这样的。
(1)初始化建立的用户登录信息。
(2)为了保证测试的有效性,删除购物车中的所有记录。
(3)把初始化建立的商品信息添加到购物车中。
(4)检查显示购物车商品数量是否为1。
2)XML数据文件
chartConfig.xml
<? xml version="1.0" encoding="UTF-8"?> <node> <case> <login>1</login> </case> <!--- 添加商品进购物车,查看显示购物车内商品数量的变化 --> <case> <TestId>chart-testcase001</TestId> <Title>购物车</Title> <Method>get</Method> <Desc>添加进购物车</Desc> <Url>http://127.0.0.1:8000/add_chart/0/1/</Url> <InptArg></InptArg> <Result>200</Result> <CheckWord>查看购物车<font color="#FF0000">1</font></a></CheckWord> </case>
在这里注意对于XML中的特殊字符,需要进行转义,进行转义的字符同HTML,总结如下。
(1)&(逻辑与)——>&。
(2)<(小于)——> <。
(3)>(大于)——> >。
(4)"(双引号)——> "。
(5)'(单引号)——> '。
转义的时候需要注意。
(1)转义序列各字符间不能有空格。
(2)转义序列必须以";"结束。
(3)单独的"&"不被认为是转义开始。
(4)注意区分大小写。
在这里“查看购物车<fontcolor="#FF0000">1</font></a>”为“查看购物车<fontcolor="#FF0000">1</font></a>”。
3)测试代码
chartinfoTest.py
#!/usr/bin/env python #coding:utf-8 import unittest,requests from util import GetXML,DB,Util class charttest(unittest.TestCase): def setUp(self): print("--------测试开始--------") xmlfile = "chartConfig.xml" #建立GetXML对象变量 xmlInfo = GetXML() #获得是否需要登录的信息 self.sign = xmlInfo.getIsLogin(xmlfile) #获得所有测试数据 self.mylists = xmlInfo.getxmldata(xmlfile) #建立DB变量 self.dataBase = DB() #建立util变量 self.util =Util() #初始化用户记录 self.userTable = "goods_user" self.userValues = self.util.inivalue(self.dataBase,self.userTable,"0") #初始化商品记录 self.goodTable = "goods_goods" self.goodValues = self.util.inivalue(self.dataBase,self.goodTable,"1") #开始测试 def test_chart_info(self): #初始化购物车,把购物车中所有内容均删除 data = self.util.initChart() for mylist in self.mylists: data = self.util.run_test(mylist,self.userValues,self.sign) #验证返回码 self.assertEqual(mylist["Result"],str(data.status_code)) self.assertIn(mylist["CheckWord"],str(data.text)) print (mylist["TestId"]+" is passsing!") def tearDown(self): #删除在测试过程中在购物车中加入的商品信息 self.util.tearDownByCookie() #删除setup建立的商品 self.util.tearDown(self.dataBase,self.goodTable,self.goodValues) #删除setup建立的用户 self.util.tearDown(self.dataBase,self.userTable,self.userValues) #关闭数据库连接 self.dataBase.close() print("--------测试结束--------") if __name__=='__main__': #构造测试集 suite=unittest.TestSuite() suite.addTest(charttest("test_chart_info")) #运行测试集合 runner=unittest.TextTestRunner() runner.run(suite)
注意两处粗体字部分,在进行测试的时候,通过 Util.initChart()方法来清除购物车中的所有商品记录,在interface/util.py中initChart()方法的实现方法如下。
def initChart(): s = requests.Session() data = s.get("http://127.0.0.1:8000/remove_chart_all/")
在这里调用了产品代码view.py中的remove_chart_all()方法来实现。注意:当测试完毕记住一定要把测试中建立购物车中的商品信息删除,同样在interface/util.py中tearDownByCookie()调用产品代码views.py中的remove_chart ()方法来实现。
def tearDownByCookie(): s = requests.Session() data = s.get("http://127.0.0.1:8000/remove_chart/0/")
在这里再对测试程序进行进一步的优化。现在测试与开发是在一台机器上进行的,所以这里用到的地址均为http://127.0.0.1:8000,为了测试代码的易维护性,把它作为Util类的成员变量,在初始化的时候声明。
... class Util: def __init__(self): self.url = "http://127.0.0.1:8000" ...
然后在下面几个地方就可以这样使用了。
... Login_url = self.url+"/login_action/" #login_Url为登录的URL ... data = s.get(self.url+"/remove_chart_all/") ... data = s.get(self.url+"/remove_chart/0/") ...
并且,interface/util.py的Util类中所有方法都加上一个self的参数。
... def insertTable(self,dataBase,table,values): ... def run_test(self,mylist,values,sign): ... def initChart(self): ... def tearDownByCookie(self): ... def tearDown(self,dataBase,table,values): ...
最后还要改测试代码中的使用,比如在goodsInfoTest.py中这样使用。
... self.util =Util() self.util.insertTable(self.dataBase,self.userTable,self.userValues) #定义商品数据库表名 self.Goodstable = "goods_goods" #获得商品初始化信息 self.goodvalues = xmlInfo.getGoodInitInfo() #建立商品记录 self.util.insertTable(self.dataBase,self.Goodstable,self.goodvalues) #开始测试 def test_goods_info(self): for mylist in self.mylists: data = self.util.run_test(mylist,self.userValues,self.sign) ... def tearDown(self): self.util. tearDown(self.dataBase,self.Goodstable,self.goodvalues) self.util.tearDown(self.dataBase,self.userTable,self.userValues) print("--------测试结束--------") ...
详见代码中的粗体字部分。
星云测试
奇林软件
联合通测
顾翔凡言:
软件测试正在生病,而且病得不轻,自动化测试被要不吹得太火,要不一点都不会,自动化比不过开发、测试又找不到缺陷,丢了西瓜也捡不到芝麻。