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.mzph.cn/news/63479.shtml

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

相关文章

【数据结构】带头双向循环链表及其实现

目录 1.带头双向循环链表 2.带头双向循环链表实现 2.1初始化 2.2销毁 2.3头插 2.4链表打印 2.5头删数据 2.6尾插数据 2.7尾删数据 2.8链表判空 2.9查找一个数据 2.10在pos位置前插入数据 2.11删除pos位置 2.12求链表的长度 2.顺序表和链表的比较 1.带头双向循环…

stable diffusion实践操作-CLIP

系列文章目录 stable diffusion实践操作 文章目录 系列文章目录前言一、CLIP是什么?1.1 定义:1.2 作用 二、使用步骤2.1 设置使用2.1 跳过层对比图: 三、总结 前言 学习本章之前,先看SD生图原理 stable diffusion实践操作-SD原理…

YOLOv5算法改进(12)— 替换主干网络之Swin Transformer

前言:Hello大家好,我是小哥谈。Swin Transformer是一种基于Transformer的深度学习模型,它在视觉任务中表现出色。与之前的Vision Transformer(ViT)不同,Swin Transformer具有高效和精确的特性,并…

B081-Lucene+ElasticSearch

目录 认识全文检索概念lucene原理全文检索的特点常见的全文检索方案 Lucene创建索引导包分析图代码 搜索索引分析图代码 ElasticSearch认识ElasticSearchES与Kibana的安装及使用说明ES相关概念理解和简单增删改查ES查询DSL查询DSL过滤 分词器IK分词器安装测试分词器 文档映射(字…

Windows NUMA编程实践 – 处理器组、组亲和性、处理器亲和性及版本变化

Windows在设计之初没有考虑过对大数量的多CPU和NUMA架构的设备的支持,大部分关于CPU的设计按照64个为上限来设计。核心数越来越多的多核处理器的进入市场使得微软不得不做较大的改动来进行支持,因此Windows 的进程、线程和NUMA API在各个版本中行为不一样…

Vue:关于声明式导航中的 跳转、高亮、以及两个类名的定制

声明式导航-导航链接 文章目录 声明式导航-导航链接router-link的两大特点(能跳转、能高亮)声明式导航-两个类名定制两个高亮类名 实现导航高亮,实现方式其实,css,JavaScript , Vue ,都可以实现。其实关于路由导航&…

【计算机组成 课程笔记】3.2 算数运算和逻辑运算的硬件实现

课程链接: 计算机组成_北京大学_中国大学MOOC(慕课) 3 - 2 - 302-门电路的基本原理(11-39--)_哔哩哔哩_bilibili 现代计算机的CPU和其他很多功能部件都是基于晶体管的集成电路,想要了解计算机组成的基本原理,还是需要有…

苹果macOS 14开发者预览版Beta 7发布 新增超过100款视频壁纸和屏保

8 月 31 日,苹果向 Mac 电脑用户推送了 macOS 14 开发者预览版 Beta 7 更新(内部版本号:23A5337a),本次更新距离上次发布隔了 8 天。 苹果发布 Beta 7 更新的同时,还发布了第 6 个公测版,正式版…

【UIPickerView-UIDatePicker-应用程序对象 Objective-C语言】

一、今天我们来学习三个东西 1.UIPickerView-UIDatePicker-应用程序对象 1.首先,来看数据选择控件 数据选择控件, 大家对这个数据选择控件,是怎么理解的, 1)数据选择控件,首先,是不是得有数据, 2)然后呢,你还得让用户能够选择, 3)最后,你还得是一个控件儿 那…

IP子网的划分

文章目录 一、子网掩码1. 产生背景2. 定义3. 分类 二、VLSM算法1. 得出下列参数2. 计算划分结果3. 举例子计算 三、常见子网划分对应关系四、练习IP编址题目需求解题1. 192.168.1.100/282. 172.16.0.58/263. 25.83.149.222/254. 100.100.243.18/205. 10.100.100.100/10 首先可以…

代码随想录笔记--栈与队列篇

目录 1--用栈实现队列 2--用队列实现栈 3--有效的括号 4--删除字符串中的所有相邻重复项 5--逆波兰表达式求值 6--滑动窗口的最大值 7--前k个高频元素 1--用栈实现队列 利用两个栈&#xff0c;一个是输入栈&#xff0c;另一个是输出栈&#xff1b; #include <iostrea…

NodeJS的简介以及下载和安装

本章节会带大家下载并安装NodeJs 以及简单的入门&#xff0c;配有超详细的图片&#xff0c;一步步带大家进行下载与安装 NodeJs简介关于前端与后端Node是什么&#xff1f;为什么要学习NodeNodeJS的优点&#xff1a; NodeJS的下载与安装NodeJS的下载&#xff1a; NodeJS的快速入…

剑指 Offer 49. 丑数(C++实现)

剑指 Offer 49. 丑数https://leetcode.cn/problems/chou-shu-lcof/ 对每个丑数 分别乘2、乘3、乘5 即可得到后续丑数 其中只需要对计算出来的丑数结果进行去重即可 int nthUglyNumber(int n) {// base caseif (n < 1){return -1;}if (n 1){return 1;}vector<int> res…

记1次前端性能优化之CPU使用率

碰到这样的一个问题&#xff0c;用户反馈页面的图表一直加载不出来&#xff0c;页面还卡死 打开链接页面&#xff0c;打开控制台 Network 看到有个请求一直pending&#xff0c;结合用户描述&#xff0c;页面一直loading,似乎验证了我的怀疑&#xff1a;后端迟迟没有相应。 但是…

LINQ详解(查询表达式)

什么是LINQ&#xff1f; LINQ(语言集成查询)是将查询功能直接集成到C#中。数据查询表示简单的字符串&#xff0c;在编译时不会进行类型检查和IntelliSense(代码补全辅助工具)支持。 在开发中&#xff0c;通常需要对不同类型的数据源了解不同的查询语句&#xff0c;如SQL数据库…

Redis项目实战——商户查询缓存

目录 为什么要用Redis实现商户查询缓存&#xff1f;用Redis实现商户查询缓存的基本思路&#xff1f;使用Redis缓存的问题及解决方法&#xff1f;一、如何保持数据库数据和Redis缓存数据的一致性&#xff1f;1 内存淘汰机制2 超时剔除机制3 主动更新机制&#xff08;胜&#xff…

sql:SQL优化知识点记录(七)

&#xff08;1&#xff09;索引优化5 &#xff08;2&#xff09;索引优化6 &#xff08;3&#xff09;索引优化7 查询*&#xff0c; 百分号加右边&#xff0c;否则索引会失效 没建立索引之前都是全表扫描 没建立索引 建立索引&#xff1a; 建立索引 id是主键&#xff0c;他也…

全新UI站长在线工具箱系统源码带后台开源版

该系统的全开源版本可供下载&#xff0c;并且支持暗黑模式。 系统内置高达72种站长工具、开发工具、娱乐工具等功能。此系统支持本地调用API&#xff0c;同时还自带免费API接口&#xff0c; 是一个多功能性工具程序&#xff0c;支持后台管理、上传插件、添加增减删功能。 环…

WPF实战项目十三(API篇):备忘录功能api接口、优化待办事项api接口

1、新建MenoDto.cs /// <summary>/// 备忘录传输实体/// </summary>public class MemoDto : BaseDto{private string title;/// <summary>/// 标题/// </summary>public string Title{get { return title; }set { title value; OnPropertyChanged();…

python爬虫-数据解析BeautifulSoup

1、基本简介 BeautifulSoup简称bs4,BeautifulSoup和lxml一样是一个html的解析器&#xff0c;主要功能也是解析和提取数据。 BeautifulSoup和lxml类似&#xff0c;既可以解析本地文件也可以响应服务器文件。 缺点&#xff1a;效率没有lxml的效率高 。 优点&#xff1a;接口设…