要做什么?
django自动化测试项目主要是为后端开发提供的,如果你只是单纯的测试人员,这篇可以跳过。正规的开发流程中,开发人员要写测试用例。根据不同的需求写出不同的测试用例来验证逻辑是否正确,是否能解决需求的所有问题。而gitlab CI就是每次我们提交代码,都自动跑一遍我们的测试,看看有没有问题。如果没有问题,就进行部署。如果有问题,就不能合并成功。
下面我分别就这两块举例说明:
首先创建一个django项目。初始化一个student_app的类,设置一下model,当然你还需要设置数据库. 然后写一些简单的逻辑,比如查询学生,删除学生。
编写简单的代码逻辑
比如model就是下面这样。
from django.db import models
# Create your models here.
class Student(models.Model):
"""
学生表
"""
id = models.AutoField(max_length=12, primary_key=True)
name = models.CharField("学生名", max_length=64, blank=True)
age = models.IntegerField("学生年龄", max_length=3)
gender_choice = ((1,"男"), (2, "女"))
sex = models.SmallIntegerField("学生性别",choices=gender_choice, default=1)
class Meta:
db_table = "student"
view 就是这样。
from django.shortcuts import render
from .models import Student
from .services import StudentService
from django.http import HttpResponse, JsonResponse
from django.views.generic import View
import json
import traceback
# logger = logging.getLogger('django')
# Create your views here.
class studentDetailView(View):
def get(self, request):
try:
age = request.GET.get("age")
detail = StudentService().get_data(age)
return JsonResponse(dict(status=0, data=detail))
except Exception as e:
print(traceback.format_exc())
return JsonResponse(dict(status=1, data="studentDetail Error"))
class insertStudentView(View):
def post(self, request):
try:
data = json.loads(request.body)
age, name, sex = [data.get(i) for i in ["age", "name", "sex"]]
detail = StudentService().insert_student(age, name, sex)
return JsonResponse(dict(status=0, data=detail))
except Exception as e:
print(traceback.format_exc())
return JsonResponse(dict(status=1, data="insertStudent Error"))
而logic是这样
from .models import Student
class StudentService(object):
def get_data(self, age):
detail = list(Student.objects.filter(age=age).values())
return detail
def insert_student(self, age, name, sex):
s = Student(age=age, name=name, sex=sex)
r = s.save()
return s.id
编写测试用例
这些是我们的开发逻辑,下面我要开始写测试用例了。测试用例是卸载tests.py文件里面的。
这里面用到的setup 和setdown上篇文章已有提及,就是做一些初始连接,数据准备及完成测试之后的收尾工作。
这里的每个测试用例,都需要以test开头,比如test_create_student, 我这里是直接调用接口。
用的是django.test里面自带的Client. 这里我分别给了一个get和post请求。
如果类型是json, 就要设置content_type=‘application/json’.
# 当前项目基于Python3
# 单元测试参考https://django-testing-docs.readthedocs.io/en/latest/basic_unittests.html
from django.test import TestCase
from django.test import Client
from .models import Student
# Create your tests here.
class StudentTestCase(TestCase):
def setup(self):
Student(age="10", name="小明", sex=1).save()
Student(age="14", name="小红", sex=2).save()
Student(age="12", name="小李", sex=1).save()
def test_create_student(self):
r = Student.objects.create(age="12", name="小李", sex=1)
c = Client()
response = c.post('/api/student/insertstudent', data= {"name":'鸿臻', "age":14, "sex":1}, content_type="application/json")
status = response.json()['status']
self.assertEquals(status, 0, "create student error")
def test_query_student_by_age(self):
c = Client()
res = c.post('/api/student/insertstudent', data= {"name":'鸿臻', "age":14, "sex":1}, content_type="application/json")
response = c.get('/api/student/studentdetail?age=14')
data = response.json()['data']
# 这里就用到了assertNotEqual, 如果相等的时候pass,否则返回报错信息。默认是第三个参数。
self.assertEquals(data[0]['name'], "鸿臻", "query student error")
def test_fail(self):
c = Client()
res = c.post('/api/student/insertstudent', data= {"name":'鸿臻', "age":14, "sex":1}, content_type="application/json")
response = c.get('/api/student/studentdetail?age=14')
data = response.json()['data']
# 这里就用到了assertNotEqual, 如果不相等的时候pass.
self.assertNotEqual(data[0]['name'], "鸿臻1", "query student error")
def tearDown(self):
Student.objects.filter(age=10).delete()
Student.objects.create(age=12).delete()
pass
这些都做完了之后,我们自己测试一下,就是python manage.py test
这里的test我们是可以指定app的,比如我这里可以指定 student_app, python manage.py test student_app
配置.gitlab-ci.yml
当我们测完觉得没问题了,接下来就该配置一个叫.gitlab-ci.yml
的文件了。
这个文件在提交到gitlab的时候,gitlab会识别出来,然后对它进行执行.这里我可以简单的举个例子。
test_job:
stage: test
before_script:
- mysql -uroot -pzhangkong -e 'DROP DATABASE IF EXISTS test_djangoTest;'
- pipenv --python 3.6
- pipenv install --ignore-pipfile
- pipenv run python manage.py makemigrations
script:
- pipenv run python manage.py test *_app
# 这个是进行服务器的部署
deploy_staging:
stage: deploy
when: on_success
dependencies: [test_job]
script:
- echo "Deploy to staging server"
- ssh server.com 'cd ~/server/djangoTest; git checkout develop; git pull'
- ssh server.com 'cd ~/server/djangoTest; pipenv install --ignore-pipfile'
- ssh server.com 'cd ~/server/djangoTest; pipenv run python manage.py makemigrations'
- ssh server.com 'cd ~/server/djangoTest; pipenv run python manage.py migrate'
- ssh server.com 'killall -9 uwsgi;uwsgi --ini ~/server/djangoTest/djangoTest.ini --daemonize /var/log/uwsgi/djangoTest --pidfile2 /home/guo/server/djangoTest/djangoTest.pid'
environment:
name: staging
only:
- develop
具体配置的含义,我会在下篇详细解释。这里可以先看代码。
配置runner
然后我们要配置一个runner, runner就是一个服务,当你有提交代码到远程操作的情况的时候,runner会被调用,来执行我们编写的gitlab-ci.yml文件,这里怎么用呢?
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
sudo yum install gitlab-runner
sudo gitlab-runner register
这里输入地址,地址就是你gitlab的域名或者ip.
获取token, 可以从gitlab当前的[这个项目,不是用户]的Settings/CI/CD 里面的Runners settings里面获取token.
然后输入runner的描述,这个随便写。
然后给runner打标签,可以随便设置。
是否runner锁定到当前项目, 这个不需要锁定,false
最后是输入runner的执行者,这里选shell.
然后runner就被配置好了,gitlab-ci-multi-runner 相关的知识也很多,比如如何管理runner, 如何开启服务,关闭服务之类的,可以参考。
https://blog.csdn.net/frankcheng5143/article/details/79838414
https://www.cnblogs.com/jiukun/p/7481287.html
这个时候,我们再提交新的代码的时候,就会自动拉起runner, 实现自动化代码测试。