问题思考
在接口测试过程中,由于有些接口类型并不是安全的,比如DELETE
类型,上一次请求之后下一次再请求结果就不一样了。甚至有时接口之间的数据还会相互干扰, 导致接口断言失败时不能断定到底是接口程序引起的错误,还是测试数据变化引起的错误,那么该如何有效解决这个问题呢?
解决思路
通过测试数据库,每轮测试之前将数据初始化,这样避免数据干扰。
Django数据库管理
在之前我们的接口项目django_resutful
使用的数据库是Python自带的SQLite3
。
Django还支持以下几种数据库:
接下来我们将会以Mysql来进行演示。
mysql简介
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件。
mysql下载安装
下载地址:https://dev.mysql.com/downloads/installer/
安装教程:自学网-Mysql教程
Navicat
Navicat是一套数据库管理工具,专为简化数据库的管理及降低系统管理成本而设。Navicat 是以直觉化的图形用户界面而建的,让你可以以安全并且简单的方式创建、组织、访问并共用信息。
Django迁移MySql
修改Setting配置
首先打开setting.py
将DATABASES
修改如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16DATABASES = {
'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE':'django.db.backends.mysql',
'HOST':'127.0.0.1',
'PORT':'3306',
'NAME':'django_restful',
'USER':'root',
'PASSWORD':'',
'OPTIONS':{
'isolation_level':None,
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", },
}
}
也就是将原来sqllite
换成Mysql
安装MySQLdb驱动
再打开django_restful
中的__init__.py
,添加如下代码:
1 | import pymysql |
上面代码表示安装MySQLdb驱动。
连接数据库
使用Navicat连接数据库如下所示:
然后创建数据库django_restful
创建Models
Django提供了完善的模型(model)层来创建和存取数据,它包含你所储存数据的必要字段和行为。通常,每个模型对应数据库中唯一的一张表。
打开api
中的models.py
创建如下代码:
1 | from django.db import models |
上面代码表示创建数据库的表,一个是User
,另外一个是Group
其中def __str__()
的作用是美化字段的显示,方便查看。如果没有__st__
方法,显示的结果是类似<__main__.Test object at 0x0000022D6D1387B8>
Django模型字段常用类型
导入Models
创建好Model后需要分别在serializers.py
和views.py
来导入,同时去掉danjo默认的数据库。
serializers.py1
2
3# from django.contrib.auth.models import User,Group
from rest_framework import serializers
from api.models import User,Group
views.py
1 | # from django.contrib.auth.models import User,Group |
数据库迁移
1 | python manage.py makemigrations api |
迁移完成之后需要重新设置一个超级管理员账户,然后登录。
1 | python manage.py createsuperuser |
数据库初始化
封装初始化操作
数据初始化操作主要包括:数据库连接,数据清除、数据插入、关闭数据库。
在api
项目下面新建一个目录test_project
然后创建文件:mysql_action.py
扩展资料:SQL命令教程
1 | from pymysql import connect |
封装初始化数据
我们将初始化数据使用Yaml来封装,可以将数据与代码分离,方便测试数据的维护。在test_project
目录中创建datas.yaml
数据内容如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16api_user:
- id: 1
username: sutune
email: sutune@163.com
groups: http://127.0.0.1:8000/groups/1/
- id: 2
username: 51zxw
email: 51zxw@163.com
groups: http://127.0.0.1:8000/groups/2/
api_group:
- id: 1
name: Developer
- id: 2
name: Tester
扩展资料: Appium yaml教程 5-1~5-4
执行初始化后数据如下:
测试用例封装
在test_project
下面创建一个测试模块test_diango_restful.py
test_django_restful.py1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import requests
import unittest
from mysql_action import DB
import yaml
class UserTest(unittest.TestCase):
def setUp(self):
self.base_url='http://127.0.0.1:8000/users'
self.auth=('51zxw','zxw20182018')
def test_001_get_user(self):
r=requests.get(self.base_url+'/1/',auth=self.auth)
result=r.json()
self.assertEqual(result['username'],'sutune')
self.assertEqual(result['email'],'sutune@163.com')
# @unittest.skip('skip add user')
def test_002_add_user(self):
form_data={'id':3,'username':'zxw666','email':'zxw666@qq.com','groups':'http://127.0.0.1:8000/groups/2/'}
r=requests.post(self.base_url+'/',data=form_data,auth=self.auth)
result=r.json()
self.assertEqual(result['username'],'zxw666')
# @unittest.skip('skip test_delete_user')
def test_003_delete_user(self):
r=requests.delete(self.base_url+'/2/',auth=self.auth)
self.assertEqual(r.status_code,204)
def test_004_update_user(self):
form_data={'email':'zxw2018@163.com'}
r=requests.patch(self.base_url+'/1/',auth=self.auth,data=form_data)
result=r.json()
self.assertEqual(result['email'],'zxw2018@163.com')
def test_005_no_auth(self):
r=requests.get(self.base_url)
result=r.json()
self.assertEqual(result['detail'],'Authentication credentials were not provided.')
class GroupTest(unittest.TestCase):
def setUp(self):
self.base_url='http://127.0.0.1:8000/groups'
self.auth=('51zxw','zxw20182018')
def test_001_group_developer(self):
r=requests.get(self.base_url+'/1/',auth=self.auth)
result=r.json()
self.assertEqual(result['name'],'Developer')
def test_002_add_group(self):
form_data={'name':'Pm'}
r=requests.post(self.base_url+'/',auth=self.auth,data=form_data)
result=r.json()
self.assertEqual(result['name'],'Pm')
def test_003_update_group(self):
form_data={'name':'Boss'}
r=requests.patch(self.base_url+'/2/',auth=self.auth,data=form_data)
result=r.json()
self.assertEqual(result['name'],'Boss')
def test_004_detele_group(self):
r=requests.delete(self.base_url+'/1/',auth=self.auth)
self.assertEqual(r.status_code,204)
if __name__ == '__main__':
db=DB()
f = open('datas.yaml', 'r')
datas = yaml.load(f)
db.init_data(datas)
unittest.main()
这样每次迭代回归测试就不用担心数据环境相互干扰的问题了。
执行用例&测试报告
在test_project
目录下面创建reports
目录,然后新建run.py
模块。
1 | import unittest |
最后生成的测试报告如下:
日志配置
在自动化测试项目中,日志是非常重要的一个部分,特别是当运行出现错误时,需要查看日志来分析定位解决问题。
在test_project
目录下面创建日志配置文件 log.conf
下面日志配置文件,定义的日志的输出格式,输出路径等信息。然后创建文件夹logs
存放日志信息。
1 | [loggers] |
扩展资料: Appium教程5-6~5-10
在run.py
引入配置文件
1 | import unittest |
在mysql_action.py
添加日志
1 | from pymysql import connect |
最后在test_django_restful.py
添加日志。
1 | import requests |
运行完成之后可以在logs
目录里面看到如下log:
1 | 2018-08-20 11:25:57,456 mysql_action.py[line:7] INFO =============init data================= |
集成Jenkins
使用Jenkins持续集成平台我们可以自动定时执行自动化任务,自动发送邮件推送测试报告,这样会有效提高自动化测试执行效率。
打开Jenkins创建项目django_restful_api
然后在构建中选择 “执行Windows批处理”
填入如下内容:
1 | d: |
执行完成后可以查看到控制台输出
最后在对应的报告文件夹可以看到生成对应的测试报告。
Jenkins定时构建语法
1 | * * * * * |
(五颗星,中间用空格隔开)
- 第一个*表示分钟,取值0~59
- 第二个*表示小时,取值0~23
- 第三个*表示一个月的第几天,取值1~31
- 第四个*表示第几月,取值1~12
- 第五个*表示一周中的第几天,取值0~7,其中0和7代表的都是周日
使用案例
每天下午18点定时构建一次
1 | 0 18 * * 1-5 |
每天早上8点构建一次
1 | 0 8 * * * |
每30分钟构建一次:
1 | H/30 * * * * |
Python邮件发送
参考资料:Selenium教程7-1~7-4