Django开发实战之单元测试和集成测试之编写测试用例以及代码覆盖率统计分析

这里分为了两种情况:
E2E:接近真实使用情况,用例数量少
UT:执行速度快,用例数量多

1、整理测试点

1、注册功能
  • 允许匿名访问
  • URL:http://127.0.0.1:8000/accounts/register/
  • get请求:返回html
  • post请求:提交json参数,返回json响应
  • 用户名不能为空
  • 密码不能为空
  • 两次密码必须相同
  • 密码长度不能小于6
  • 用户名不能重复
  • 参数正确,则返回:注册成功
2、登录
  • 允许匿名访问

  • URL:http://127.0.0.1:8000/accounts/register/

  • get请求:返回html

  • post请求:提交表单,返回了重定向

  • 用户名不能为空

  • 密码不能为空

  • 密码不能错误

3、提交反馈
  • 不允许匿名访问

  • URL:http://127.0.0.1:8000/lili/submit/

  • GET:返回HTML

  • POST::提交json,返回json

    • 提交的数据会入库
    • 提交的数据会和用户关联
    • 同一用户,不可重复发布
4、反馈的结果
  • 允许匿名访问
  • URL:http://127.0.0.1:8000/lili/result/
  • 所有的请求返回:HTML

2、编写测试代码

主要学习两个部分的内容
1、django自带的测试组件
2、pytest-django插件

1、测试http请求

在这里插入图片描述
这个Client自己是一个客户端,同时也是一个服务端

import pytest
from django.http import HttpResponse
from django.test.client import Client

# Create your tests here.


@pytest.fixture
def client()->Client:
    return Client()


def test_register(client:Client):
    res:HttpResponse = client.get('/accounts/register/')
    assert res.status_code ==200
    html:str=res.content.decode('utf-8')
    assert "账号" in html
    assert "密码" in html
    assert "确认密码" in html

执行:pytest
得到下面的结果
在这里插入图片描述

2、测试db数据库
import pytest
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.test.client import Client


@pytest.fixture
def user(_django_db_helper):
    new_user = User.objects.create_user(
        username="lili01",
        password="123456",
        email="lili01@qq.com"
    )
    """这里是作为fixture的返回值,接下来创建测试用例"""
    return new_user


def test_user(user):
    """这样每个都需要加"""
    pass

其中_django_db_helper目的是为了进行数据准备,比如说在数据库中创建数据

import json

import pytest
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.test.client import Client

from lili.models import Feedback


# Create your tests here.


@pytest.fixture
def client()->Client:
    return Client()


def test_register(client:Client):
    res:HttpResponse = client.get('/accounts/register/')
    assert res.status_code ==200
    html:str=res.content.decode('utf-8')
    assert "账号" in html
    assert "密码" in html
    assert "确认密码" in html

@pytest.fixture
def user(_django_db_helper):
    new_user = User.objects.create_user(
        username="lili01",
        password="123456",
        email="lili01@qq.com"
    )
    """这里是作为fixture的返回值,接下来创建测试用例"""
    return new_user

@pytest.mark.parametrize("data,code,message",[
    ({"username":"lili02",
      "password":"",
       "password_confirm":"123456",
       "email":"lili02@qq.com"
      },-1,"password不能为空"),
({"username":"lili02",
      "password":"1234567",
       "password_confirm":"123456",
       "email":"lili02@qq.com"
      },-2,"两次密码必须相同"),
({"username":"lili02",
      "password":"12345",
       "password_confirm":"12345",
       "email":"lili02@qq.com"
      },-3,"密码长度必须大于等于6"),
({"username":"lili01",
      "password":"123456",
       "password_confirm":"123456",
       "email":"lili01@qq.com"
      },-4,"用户已经存在,请重新注册"),
])
def test_register_post(user, client:Client,data,code,message):
    """这样每个都需要加"""
    res:HttpResponse  = client.post('/accounts/register/',data=data,content_type='application/json')
    html = res.content.decode('utf-8')
    res_json = json.loads(html)
    assert res_json['code'] == code
    assert res_json['message'] == message

除此以外,我们也可以对数据库进行断言,比如断言用户等于1

@pytest.mark.parametrize("data,code,message", [
    ({"username": "lili02",
      "password": "",
      "password_confirm": "123456",
      "email": "lili02@qq.com"
      }, -1, "password不能为空"),
    ({"username": "lili02",
      "password": "1234567",
      "password_confirm": "123456",
      "email": "lili02@qq.com"
      }, -2, "两次密码必须相同"),
    ({"username": "lili02",
      "password": "12345",
      "password_confirm": "12345",
      "email": "lili02@qq.com"
      }, -3, "密码长度必须大于等于6"),
    ({"username": "lili01",
      "password": "123456",
      "password_confirm": "123456",
      "email": "lili01@qq.com"
      }, -4, "用户已经存在,请重新注册"),
])
def test_register_post(user, client: Client, data, code, message):
    # 断言用户等于1,
    user_list = list(User.objects.all())
    user_list_len = len(user_list)
    assert user_list_len == 1
    """这样每个都需要加"""
    res: HttpResponse = client.post('/accounts/register/', data=data, content_type='application/json')
    html = res.content.decode('utf-8')
    res_json = json.loads(html)
    assert res_json['code'] == code
    assert res_json['message'] == message
    if res_json['code'] == 0:
        user_list = list(User.objects.all())
        user_list_len = len(user_list)
        assert user_list_len == 4
3、自动登录

在这之前我们先测试下匿名访问这个功能,大概的思路是访问的时候返回的code不等于200,我之前的文有提到这里他会进行重定向,然后状态会变成302

def test_submit_anonymous(client: Client):
    res: HttpResponse = client.get('/lili/submit/')
    assert res.status_code == 302

开始执行,不想执行之前的用例,只执行test_submit_anonymous,可以用下面这个命令,

pytest -k test_submit_anonymous

那这种情况是没有登录的状态,接下来就来到重点,那么登录之后的状态是什么样的呢?具体要怎么做呢?请接着往下看
首先,我们需要用到@pytest.fixture,代码如下

tests.py
import json

import pytest
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.test.client import Client

from lili.models import Feedback


# Create your tests here.


@pytest.fixture
def client() -> Client:
    return Client()


def test_register(client: Client):
    res: HttpResponse = client.get('/accounts/register/')
    assert res.status_code == 200
    html: str = res.content.decode('utf-8')
    assert "账号" in html
    assert "密码" in html
    assert "确认密码" in html


@pytest.fixture
def user(_django_db_helper):
    new_user = User.objects.create_user(
        username="lili01",
        password="123456",
        email="lili01@qq.com"
    )
    """这里是作为fixture的返回值,在数据库里面创建数据,接下来创建测试用例"""
    return new_user

@pytest.fixture
def user_clien(client: Client,user):
    client.force_login(user)
    return client




@pytest.mark.parametrize("data,code,message", [
    ({"username": "lili02",
      "password": "",
      "password_confirm": "123456",
      "email": "lili02@qq.com"
      }, -1, "password不能为空"),
    ({"username": "lili02",
      "password": "1234567",
      "password_confirm": "123456",
      "email": "lili02@qq.com"
      }, -2, "两次密码必须相同"),
    ({"username": "lili02",
      "password": "12345",
      "password_confirm": "12345",
      "email": "lili02@qq.com"
      }, -3, "密码长度必须大于等于6"),
    ({"username": "lili01",
      "password": "123456",
      "password_confirm": "123456",
      "email": "lili01@qq.com"
      }, -4, "用户已经存在,请重新注册"),
])
def test_register_post(user, client: Client, data, code, message):
    # 断言用户等于1,
    user_list = list(User.objects.all())
    user_list_len = len(user_list)
    assert user_list_len == 1
    """这样每个都需要加"""
    res: HttpResponse = client.post('/accounts/register/', data=data, content_type='application/json')
    html = res.content.decode('utf-8')
    res_json = json.loads(html)
    assert res_json['code'] == code
    assert res_json['message'] == message
    if res_json['code'] == 0:
        user_list = list(User.objects.all())
        user_list_len = len(user_list)
        assert user_list_len == 4



def test_submit_anonymous(client: Client):
    res: HttpResponse = client.get('/lili/submit/')
    """没有登录会重定向到登录界面"""
    assert res.status_code == 302


def test_submit_login(user_clien: Client):
    res: HttpResponse = user_clien.get('/lili/submit/')
    html: str = res.content.decode('utf-8')
    assert "商品质量" in html
    assert "客服态度" in html
    assert res.status_code == 200

在这里插入图片描述
接下来result这个接口的测试,我们把所有的方法都涵盖进去:
代码就是

tests.py
import json

import pytest
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.test.client import Client

from lili.models import Feedback
@pytest.mark.parametrize("methond", ["get","post","delete","put"])
def test_result_all(client: Client,methond):
    res: HttpResponse = client.generic(methond.upper(),'/lili/result/')
    html: str = res.content.decode('utf-8')
    assert res.status_code == 200

然后控制台允许用例

 pytest -k test_result_all

3、分析和统计测试覆盖率

在pytets.ini这个文件里面加入这么一行内容

addopts = --cov=lili

在这里插入图片描述
然后终端执行:pytest
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如何知道有哪17行代码没有覆盖到呢
继续修改pytets.ini这个文件里面加入这么一行内容

addopts = --cov=lili --cov-report html

然后运行:pytest
在这里插入图片描述
打开路径:D:\cekai\xuexi\Tesla\htmlcov\index.html
在这里插入图片描述

  • 42
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值