Django(10)-项目实战-对发布会管理系统进行测试并获取测试覆盖率

在发布会签到系统中使用django开发了发布会签到系统,
本文对该系统进行测试。

django.test

django.test是Django框架中的一个模块,提供了用于编写和运行测试的工具和类。

django.test模块包含了一些用于测试的类和函数,如:

  • TestCase:这是一个基类,用于编写Django测试用例。继承自unittest.TestCase,提供了一些额外的功能和方法,用于处理Django应用程序的测试环境。

  • SimpleTestCase:这是一个更轻量级的测试基类,适用于没有数据库或网络访问的简单测试场景。

  • Client:这是一个模拟HTTP请求的客户端类,用于在测试中模拟用户请求和验证响应结果。

  • RequestFactory:这是一个用于创建HTTP请求对象的工厂类,用于在测试中生成HTTP请求实例。

  • 其他辅助函数和装饰器,如override_settings用于在测试过程中临时覆盖Django设置,tag用于给测试用例添加标签等。

通过使用django.test模块,你可以编写单元测试、集成测试和功能测试等来验证和确保Django应用程序的正确性和稳定性。

下面是一个简单的示例代码,演示如何使用django.test模块编写一个测试用例类:

from django.test import TestCaseclass MyTestCase(TestCase):def test_my_function(self):# 编写测试逻辑result = my_function()self.assertEqual(result, expected_result)

总结来说,django.test模块提供了一套用于编写和运行Django应用程序测试的工具和类,能够帮助开发者验证和确保应用程序的正确性和稳定性。

测试index视图

在这里插入图片描述

import os,django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "guest.settings")
import django
django.setup()
from django.test import TestCase
class IndexPageTest(TestCase):def test_index_page_renders_index_template(self):response = self.client.get("/index/")self.assertEqual(response.status_code,200)self.assertTemplateUsed(response,'index.html')

测试类徐亚集成TestCase,使用client实例可以请求get和post HTTP请求
获取response后断言状态码,
并使用assertTemplateUsed方法断言该请求是否使用index.html模板

测试login视图

import osos.environ.setdefault("DJANGO_SETTINGS_MODULE", "guest.settings")from django.contrib.auth.models import User
from django.test import TestCase
class LoginActionTest(TestCase):def setUp(self) -> None:User.objects.create_user("admin1","admin@mail.com","admin123456") #创建用户def test_add_admin(self):user=User.objects.get(username="admin1")#查询self.assertEqual(user.username,"admin1")self.assertEqual(user.email, "admin@mail.com")def test_login_action_username_password_null(self):"""测试密码为空"""test_data={'username':'','password':''}response=self.client.post('/login/',data=test_data) #使用self的client可以对urls进行测试self.assertEqual(response.status_code,200)self.assertIn(b"username or password error",response.content)def test_error_password(self):test_data = {'username': 'abc', 'password': ''}response = self.client.post('/login/', data=test_data)  # 使用self的client可以对urls进行测试self.assertEqual(response.status_code, 200)self.assertIn(b"username or password error", response.content)def test_login_success(self):test_data = {'username': 'admin', 'password':'admin123456'}response = self.client.post('/login/', data=test_data)  # 使用self的client可以对urls进行测试self.assertEqual(response.status_code, 302)

在第一个测试方法中对User进行了测试,查询数据库是否新建了该账号
在2,3,4测试方法里则是测试了/login/请求,通过传入不同的参数,校验响应。

注意b:在Python中,字符串前面加上b表示这是一个字节字符串(bytes string)。字节字符串是一种以字节为单位表示的字符串,它可以包含任意的二进制数据。

在上述代码中,response.content被认为是一个字节字符串。将b"username or password error"作为参数传递给elf.assertIn()函数,表示期望的"username or password error"字符串是以字节的形式存在的。

使用字节字符串的一个常见场景是在进行文本匹配或者通过网络传输二进制数据时,通常需要使用字节字符串来处理二进制数据以及非ASCII字符集。

与之相对,普通的字符串(字符字符串)在Python中使用引号括起来,例如"username or password error"。它们是以Unicode字符为单位表示的字符串,适用于大多数文本处理任务。

需要注意的是,对于编写测试用例来说,根据实际情况选择使用字节字符串或字符字符串,确保与被测试代码中的数据类型一致。

测试模型


from datetime import datetime
import os,django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "guest.settings")# project_name 项目名称
django.setup()
from django.test import TestCase
from sign.models import Event,Guestfrom django.test.utils import setup_test_environment
setup_test_environment()
time=datetime.now()
class ModelTest(TestCase):def setUp(self) -> None:Event.objects.create(id=4,name="oneplus 3 event",status=True,limit=2000,address="shenzhen",start_time=time)Guest.objects.create(id=4, event_id=4,realname="zhangsan",phone="13276766666",email="zhangsan@qq.com",sign=False,create_time=time)def test_event_models(self):result=Event.objects.get(name="oneplus 3 event")self.assertEqual(result.address,"shenzhen")self.assertTrue(result.status)def test_guest_models(self):result=Guest.objects.get(phone="13276766666")self.assertEqual(result.realname,"zhangsan")self.assertFalse(result.sign)

测试模型时需要先在setup里创建模型,然后在测试方法里调用查询方法校验是否创建成功,

测试event_manage

import os,django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "guest.settings")
django.setup()
from datetime import datetimefrom django.contrib.auth.models import Userfrom sign.models import Event
time=datetime.now()import django
django.setup()
from django.test import TestCase
class EventManageTest(TestCase):def setUp(self) -> None:"""测试event_manage和搜索方法,需要先登录,所以在setup里先登录"""User.objects.create_user("admin1", "admin@mail.com", "admin123456")test_data = {'username': 'admin', 'password': 'admin123456'}response = self.client.post('/login/', data=test_data)Event.objects.create(id=4, name="oneplus 3 event", status=True, limit=2000, address="shenzhen", start_time=time)def test_event(self):response = self.client.get("/event_manage/")self.assertEqual(response.status_code, 200)self.assertIn(b"oneplus", response.content) #response.contentself.assertIn(b"shenzhen", response.content)def test_search(self):"""测试搜索"""testdata={"search_name":"oneplus"}response = self.client.get("/search_name/",data=testdata)self.assertEqual(response.status_code, 200)self.assertIn(b"oneplus", response.content) #response.contentself.assertIn(b"shenzhen", response.content)

因为event_manage请求在登录后才能调用,所以在setup里请求了登录接口。
在测试方法里调用了对应接口,并校验结果。

测试签到功能

import os,django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "guest.settings")
django.setup()
from datetime import datetimefrom django.contrib.auth.models import Userfrom sign.models import Event, Guesttime=datetime.now()import django
django.setup()
from django.test import TestCase
class SignTest(TestCase):def setUp(self) -> None:"""测试event_manage和搜索方法,需要先登录,所以在setup里先登录"""User.objects.create_user("admin1", "admin@mail.com", "admin123456")test_data = {'username': 'admin', 'password': 'admin123456'}response = self.client.post('/login/', data=test_data)Event.objects.create(id=5, name="oneplus 3 event", status=True, limit=2000, address="shenzhen", start_time=time)Event.objects.create(id=4, name="oneplus 3 event", status=True, limit=2000, address="shenzhen", start_time=time)# Event.objects.create(id=4, name="oneplus 3 event", status=True, limit=2000, address="shenzhen", start_time=time)Guest.objects.create(id=4, event_id=4, realname="lisi", phone="13276766666", email="lisi@qq.com",sign=False,create_time=time)Guest.objects.create(id=5, event_id=5, realname="lisi", phone="13276609878", email="lisi@qq.com",sign=True,create_time=time)def test_sign_1(self):response = self.client.get("/sign_index/4/")print(response.content)self.assertEqual(response.status_code, 200)self.assertIn(b"oneplus 3 event", response.content) #response.contentdef test_sign_phone_error(self):response = self.client.post("/sign_index_action/4/",{"phone":"1321761766666"})self.assertEqual(response.status_code, 200)self.assertIn(b"phone error", response.content) #response.contentdef test_sign_phone_not_match(self):response = self.client.post("/sign_index_action/4/",{"phone":"13276609878"})self.assertEqual(response.status_code, 200)self.assertIn(b"event id or phone error", response.content) #response.contentdef test_sign_phone_success(self):response = self.client.post("/sign_index_action/4/",{"phone":"13276766666"})self.assertEqual(response.status_code, 200)self.assertIn(b"sign in success", response.content) #response.contentdef test_sign_phone_has_sign(self):response = self.client.post("/sign_index_action/5/",{"phone":"13276609878"})self.assertEqual(response.status_code, 200)self.assertIn(b"user has sign in", response.content) #response.content

因为签到功能需要先有发布会和客户,所以需要在setup里先创建对应模型,然后在测试方法中传入不同的参数,校验结果。
可以看到使用django.test进行测试,即测试了网页路由,也测试了对应的视图函数。

测试数据库

在Django中,当你运行测试用例时,测试框架会自动为你创建一个专用的测试数据库,该数据库是在测试运行期间被使用的临时数据库。当测试完成后,测试框架会清除该数据库。

在进行模型测试时,如果你在测试用例中创建了模型实例并保存到数据库中,测试框架会确实在测试数据库中创建相应的表以及保存模型对象的记录。

示例代码:

from django.test import TestCase
from myapp.models import MyModelclass ModelTestCase(TestCase):def test_create_model(self):# 创建并保存模型对象MyModel.objects.create(name="Example")# 断言模型对象是否在测试数据库中存在self.assertTrue(MyModel.objects.exists())

当你运行上述测试用例时,测试框架会在测试数据库中创建一个MyModel表,并将模型对象保存在该表中。注意,测试中的模型数据不会影响你的开发或生产环境数据库,它们只是在测试期间使用的临时数据。

需要注意的是,测试数据库是独立于你的开发或生产数据库的,并且在每次运行测试时都会自动创建和销毁。这样可以确保测试的可靠性和独立性。
在这里插入图片描述
如图,在运行发布会测试文件时,显示创建了数据库,在测试结束时,数据库被销毁。
所以在进行测试时,用户和数据库表等信息,都需要创建。
如果在运行测试,发现状态码返回是302,需要注意是否创建用户,并使用该用户登录。

运行测试

python manage.py test tests
可以使用tests目录下的所有测试文件
在这里插入图片描述
可以看到运行了16个用例都通过了

测试覆盖率

测试覆盖率是一种度量软件测试程度的指标,它衡量了测试代码中有多少部分被执行了。

要计算测试覆盖率,可以使用以下公式:

测试覆盖率 = (已执行的代码行数 / 总代码行数) * 100

具体的计算步骤可以分为以下几个步骤:

  1. 确定要计算覆盖率的代码范围。这可以是整个项目、单个文件、单个函数等。

  2. 运行测试套件。执行针对代码范围的测试,确保已经执行了尽可能多的代码路径。

  3. 收集执行信息。使用测试覆盖率工具(如 coverage)来跟踪代码的执行情况,并记录已经执行的代码行。

  4. 统计覆盖率数据。根据执行信息统计已经执行的代码行数和总代码行数。

  5. 计算覆盖率百分比。根据统计的数据,使用上述公式计算测试覆盖率百分比。

测试覆盖率可以根据需要进行细分,如语句覆盖率(Statement Coverage)、分支覆盖率(Branch Coverage)、条件覆盖率(Condition Coverage)等。具体的计算方式和度量指标可能会有所不同,但基本原理是相似的。

需要注意的是,测试覆盖率并不能完全衡量代码的质量,它只能指示测试是否已经覆盖了一定程度的代码。在计算测试覆盖率时,应该根据项目的实际情况和需求来确定合适的目标和阈值。

总结来说,测试覆盖率是通过统计已执行的代码行数与总代码行数之比来计算的。使用测试覆盖率工具可以帮助收集和分析执行信息,从而得出测试覆盖率的百分比。测试覆盖率可以帮助评估测试的完整程度,但它并不能完全代表代码的质量。

coverage获取测试覆盖率

在Python中,你可以使用第三方库 coverage 来获取测试覆盖率数据。coverage 是一个广泛使用的代码覆盖率工具,可以统计你的测试用例对代码的覆盖情况。

下面是一个简单的示例,展示了如何使用 coverage 来获取测试覆盖率数据:

  1. 安装 coverage 库:

    pip install coverage
    
  2. 在终端中运行测试并收集覆盖率数据:

    
    

    这里 myapp 是你要测试的应用程序的名称。--source 参数用于指定要收集覆盖率数据的代码路径。

  3. 生成覆盖率报告:

    coverage report
    

    运行该命令后,coverage 将会产生一个简单的文本报告,显示每个文件和每个文件中被测试的代码行的覆盖情况。

你也可以使用 coverage html 命令生成一个 HTML 格式的覆盖率报告,该报告能够更直观地展示代码覆盖情况。

注意:在运行测试之前,确保你的代码已经被正确安装和配置,并且拥有相应的测试用例。

总结来说,通过使用 coverage 库,你可以轻松地获取你的Python代码的测试覆盖率数据,并生成相应的报告来帮助你分析和评估你的测试质量。
在这里插入图片描述

运行coverage

coverage run --source=sign manage.py test
这里–source后面是目录,意思是统计sign目录下文件的代码执行覆盖率,即sign下每个文件里的代码在执行时运行了几行。
在这里插入图片描述
在这里插入图片描述
可以看到,apps里代码一共3行,miss 3行,说明3行代码都没有执行到,
总的测试覆盖率是95%,也就是代码行覆盖率是95%

也可以不指定目录,则会计算根路径下所有文件代码执行覆盖率。
coverage run manage.py test
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/117143.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

每日一题 1372二叉树中的最长交错路径

题目 给你一棵以 root 为根的二叉树,二叉树中的交错路径定义如下: 选择二叉树中 任意 节点和一个方向(左或者右)。如果前进方向为右,那么移动到当前节点的的右子节点,否则移动到它的左子节点。改变前进方…

vscode 清除全部的console.log

在放页面的大文件夹view上面右键点击在文件夹中查找 console.log.*$ 注意:要选择使用正则匹配 替换为 " " (空字符串)

跨模态可信感知

文章目录 跨模态可信感知综述摘要引言跨协议通信模式PCP网络架构 跨模态可信感知跨模态可信感知的概念跨模态可信感知的热点研究场景目前存在的挑战可能改进的方案 参考文献 跨模态可信感知综述 摘要 随着人工智能相关理论和技术的崛起,通信和感知领域的研究引入了…

ELK日志收集系统(四十九)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、概述 二、组件 1. elasticsearch 2. logstash 2.1 工作过程 2.2 INPUT 2.3 FILETER 2.4 OUTPUTS 3. kibana 三、架构类型 3.1 ELK 3.2 ELKK 3.3 ELFK 3.5 EF…

VScode远程连接主机

一、前期准备 1、Windows安装VSCode&#xff1b; 2、在VSCode中安装PHP Debug插件&#xff1b; 3、安装好Docker 4、在容器中安装Xdebug ①写一个展现phpinfo的php文件 <?php phpinfo(); ?>②在浏览器上打开该文件 ③复制所有信息丢到Xdebug: Installation instr…

【C进阶】深度剖析数据在内存中的存储

目录 一、数据类型的介绍 1.类型的意义&#xff1a; 2.类型的基本分类 二、整形在内存中的存储 1.原码 反码 补码 2.大小端介绍 3.练习 三、浮点型在内存中的存储 1.一个例子 2.浮点数存储规则 一、数据类型的介绍 前面我们已经学习了基本的内置类型以及他们所占存储…

封装(个人学习笔记黑马学习)

1、格式 #include <iostream> using namespace std;const double PI 3.14;//设计一个圆类&#xff0c;求圆的周长 class Circle {//访问权限//公共权限 public://属性//半径int m_r;//行为//获取圆的周长double calculateZC() {return 2 * PI * m_r;} };int main() {//通…

Linux 学习笔记(1)——系统基本配置与开关机命令

目录 0、起步 0-1&#xff09;命令使用指引 0-2&#xff09;查看历史的命令记录 0-3&#xff09;清空窗口内容 0-4&#xff09;获取本机的内网 IP 地址 0-5&#xff09;获取本机的公网ip地址 0-6&#xff09;在window的命令行窗口中远程连接linux 0-7&#xff09;修改系…

VScode 国内下载源 以及 nvm版本控制器下载与使用

VScode 国内下载源 进入官网 https://code.visualstudio.com/ 点击下载 复制下载链接到新的浏览器标签 将地址中的/stable前的az764295.vo.msecnd.net换成vscode.cdn.azure.cn&#xff0c;再回车就会直接在下载列表啦。 参考大神博客 2.使用nvm 对 node 和npm进行版本控制…

ARM编程模型-内存空间和数据

ARM属于RISC体系&#xff0c;许多指令单周期指令&#xff0c;是32位读取/存储架构&#xff0c;对内存访问是32位&#xff0c;Load and store的架构&#xff0c;只有寄存器对内存&#xff0c;不能内存对内存存储&#xff0c;CPU通过寄存器对内存进行读写操作。 ARM的寻址空间是线…

go Session的实现(一)

〇、前言 众所周知&#xff0c;http协议是无状态的&#xff0c;这对于服务器确认是哪一个客户端在发请求是不可能的&#xff0c;因此为了能确认到&#xff0c;通常方法是让客户端发送请求时带上身份信息。容易想到的方法就是客户端在提交信息时&#xff0c;带上自己的账户和密…

17.看楼房

目录 Description Input Output Notes 思路 注意事项 C完整代码&#xff08;含详细注释&#xff09; Description 小张在暑假时间进行了暑期社会调查。调查的内容是楼房的颜色如何影响人们的心情。于是他找到了一个楼房从左到右排成一排的小区&#xff0c;这个小区一共有…

51单片机项目(7)——基于51单片机的温湿度测量仿真

本次做的设计&#xff0c;是利用DHT11传感器&#xff0c;测量环境的温度以及湿度&#xff0c;同时具备温度报警的功能&#xff1a;利用两个按键&#xff0c;设置温度阈值的加和减&#xff0c;当所测温度大于温度阈值的时候&#xff0c;蜂鸣器就会响起&#xff0c;进行报警提示。…

安卓 tcp 客户端

安卓 tcp 客户端 Server:8888 是Qt 写的Tcp 服务器 ip 是 192.168.2.103 port是8888 安卓手机运行 kotlin 语法的Tcp Client &#xff0c;连接&#xff0c;收发数据 效果如下图 Tcpclient package com.example.myapplicationimport android.os.Handler import android.os.Loo…

【leetcode 力扣刷题】数学题之计算次幂//次方:快速幂

利用乘法求解次幂问题—快速幂 50. Pow(x, n)372. 超级次方 50. Pow(x, n) 题目链接&#xff1a;50. Pow(x, n) 题目内容&#xff1a; 题目就是要求我们去实现计算x的n次方的功能函数&#xff0c;类似c的power()函数。但是我们不能使用power()函数直接得到答案&#xff0c;那…

ARM Cortex-M 的 SP

文章目录 1、栈2、栈操作3、Cortex-M中的栈4、MDK中的SP操作流程5、Micro-Lib的SP差别1. 使用 Micro-Lib2. 未使用 Micro-Lib 在嵌入式开发中&#xff0c;堆栈是一个很基础&#xff0c;同时也是非常重要的名词&#xff0c;堆栈可分为堆 (Heap) 和栈 (Stack) 。 栈(Stack): 一种…

EG1164大功率同步整流升压模块开源,最高效率97%

EG1164大功率同步整流Boost升压电源模块&#xff0c;最高效率97%&#xff0c;输入电压8~50V&#xff0c;输出电压8~60V可调&#xff0c;最大功率300瓦以上&#xff0c;开关频率219kHz。 白嫖了张嘉立创的彩色丝印券就随便画了个板试试&#xff0c;第一次打彩色丝印。 因为我测…

flutter plugins插件【一】【FlutterJsonBeanFactory】

1、FlutterJsonBeanFactory 在Setting->Tools->FlutterJsonBeanFactory里边自定义实体类的后缀&#xff0c;默认是entity 复制json到粘贴板&#xff0c;右键自己要存放实体的目录&#xff0c;可以看到JsonToDartBeanAction Class Name是实体名字&#xff0c;会默认加上…

基于硬件隔离增强risc-v调试安全1_问题描述

安全之安全(security)博客目录导读 2023 RISC-V中国峰会 安全相关议题汇总 说明&#xff1a;本文参考RISC-V 2023中国峰会如下议题&#xff0c;版权归原作者所有。

每日一题 2511. 最多可以摧毁的敌人城堡数目

难度&#xff1a;简单 翻译&#xff1a;寻找距离最远的 1 和 -1 的组合&#xff0c;要求它们之间只有0 class Solution:def captureForts(self, forts: List[int]) -> int:res, t 0, -1for i, fort in enumerate(forts):if fort -1 or fort 1:if t > 0 and fort ! f…