专栏首页用户6517667的专栏基于Django的电子商务网站开发(连载25)

基于Django的电子商务网站开发(连载25)

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: return len(request.COOKIES)-1...

在本书第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>查看购物车&lt;font color=&quot;#FF0000&quot;&gt;1&lt;/font&gt;&lt;/a&gt;</CheckWord> </case>

在这里注意对于XML中的特殊字符,需要进行转义,进行转义的字符同HTML,总结如下。

(1)&(逻辑与)——>&amp;。

(2)<(小于)——> &lt;。

(3)>(大于)——> &gt;。

(4)"(双引号)——> &quot;。

(5)'(单引号)——> &apos;。

转义的时候需要注意。

(1)转义序列各字符间不能有空格。

(2)转义序列必须以";"结束。

(3)单独的"&"不被认为是转义开始。

(4)注意区分大小写。

在这里“查看购物车&lt;fontcolor=&quot;#FF0000&quot;&gt;1&lt;/font&gt;&lt;/a&gt;”为“查看购物车<fontcolor="#FF0000">1</font></a>”。

3)测试代码

chartinfoTest.py

#!/usr/bin/env python#coding:utf-8import unittest,requestsfrom 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("--------测试结束--------")...

详见代码中的粗体字部分。

星云测试

http://www.teststars.cc

奇林软件

http://www.kylinpet.com

联合通测

http://www.quicktesting.net

本文分享自微信公众号 - 软件测试培训(iTestTrain),作者:顾翔

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-01-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 基于Django的电子商务网站开发(连载33)

    顾翔老师开发的bugreport2script开源了,希望大家多提建议。文件在https://github.com/xianggu625/bug2testscr...

    小老鼠
  • 基于Django的电子商务网站开发(连载17)

    接下来再对测试程序以及配置文件进行优化,把loginConfig.xml和registerConfig.xml这两个文件进行合并,形成loginRegConfi...

    小老鼠
  • 基于Django的电子商务网站开发(连载16)

    (1)通过循环语句formylist in self.mylists:遍历所有测试用例。

    小老鼠
  • python爬虫学习,爬取豆瓣各分类书单

    初学python会比较困难,但是只要坚定自己的信念,不轻易认输,敢于面对,成功迟早会笑脸相迎。

    python学习教程
  • pythonpcap原生python读取

    本文代码都由python编写,无需安装第三方拓展库,代码更新:https://github.com/mengdj/python

    py3study
  • 【AlphaGo Zero 核心技术-深度强化学习教程代码实战06】给Agent添加记忆功能

    【导读】Google DeepMind在Nature上发表最新论文,介绍了迄今最强最新的版本AlphaGo Zero,不使用人类先验知识,使用纯强化学习,将价值...

    WZEARW
  • python高级编程第二讲:类与对象深度问题与解决技巧

    将上面的代码我们进行改造,引入内存跟踪的类,并且将2个类分别实例化100000次,并打印相应的内存大小

    小海怪的互联网
  • 数据结构之——Python实现循环队列

    栈是先入后出,与之相反的是队列,队列是先进先出的线性结构。队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。允许插入的一端称为队尾,允许删除的一端...

    py3study
  • python pyqt5 QStatusBar 常用

    import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.Qt...

    用户5760343
  • python模块:win32com用法详解

    import win32com from win32com.client import Dispatch, constants

    菲宇

扫码关注云+社区

领取腾讯云代金券