Django UT

3 篇文章 0 订阅
3 篇文章 0 订阅

本质上是继承UnitTest实现,可轻松实现

  • 数据隔离
    • 执行前自动创建测试数据库,默认为test_xxx,可通过'TEST':{'name':'自定义'}
    • 执行时settings.debug恒等于false
    • 执行后自动销毁测试数据库
      • 异常中断时不会删除,下次执行前需要手动确认
      • 自动确认
        • python3 manage.py  test --noinput
  • 自动发现
    • test_*开头的模块
    • UT的子类
      • 无序!!
  • API test
    • 只需要写路由,不启动服务便可直接测view
    • 依赖服务需要能联通,比如db, redis等
      • 本地容器可加入桥接网络

结合UT,融入CI

  1. 注册gitlab runner
    1. shell形式
      1. 安装python
        1. 不要通过apt install python
          1. 安装空间将近1G,却没有pip
        2. 推荐源码安装
    2. 记得对应路径下,存放测试需要的资源
  2. 编写yml
    1. lint-job:
        tags:
            - test
      
      
        stage:  build
        script:
          - echo "Hello, $GITLAB_USER_LOGIN!"
          - pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
          - pip3 install -r requirements.txt
          - export PATH=/home/gitlab-runner/.local/bin:$PATH
          - cd {django project目录}/
          - echo "start lint---$PATH"
          - pylint  {django project目录}/  --fail-under=9
          - echo "end lint---"
          
      
      test-job:
        tags:
            - test
        stage: test
        script:
          - echo "This job tests something:$DEMO_VALUE"
          - cd {django project目录}
          - echo "start test---"
          - python3 manage.py makemigrations && python3 manage.py migrate && python3 manage.py  test --noinput 
          - echo "end test---"
      
      

3. 编写UT

​
'''
继承TestCase 就创建了一个测试样例。下述二个独立的测试是二个类的方法,
这些方法的命名都以 test 开头。 这个命名约定告诉测试运行者类的哪些方法表示测试。

每个测试的关键是:调用 assertEqual() 来检查预期的输出; 调用 assertTrue() 或 assertFalse() 来验证一个条件;
调用 assertRaises() 来验证抛出了一个特定的异常。使用这些方法而不是 assert 语句是为了让测试运行者能聚合所有的测试结果并产生结果报告。

通过 setUp() 和 tearDown() 方法,可以设置测试开始前与完成后需要执行的指令。 在 组织你的测试代码 中,对此有更为详细的描述。
'''
from django.test import TestCase, Client
from statusTask.models import UserModel, DetectionTaskModel
from utils.fb_enum import TaskEnum


class  DemoTestCase(TestCase):
    def login(self):
        '''
        适配自造轮子的登录逻辑
        '''
        client = Client()
        data = {"username": self.name, "password": self.pwd}
        response = client.post('/task_admin/login', data, content_type='application/json')
        # self.assertEqual(response.status_code, 200)
        # 获取返回值
        res = response.json()
        print(f'login:{res}')
        session_id = res.get('data').get('session_id')
        return session_id
    
    def setUp(self):
        self.ok_series_id = 'seriesid'
        self.SUGGESTION = ''
        self.name = 'admin1'
        self.pwd = '1'
        
        # 造数据
        self.user = UserModel.objects.create_user(username=self.name, password=self.pwd)
        DetectionTaskModel.objects.create(id='task_id', series_id=self.ok_series_id, path='path', week=30, name='name', status=TaskEnum.SUCCESS.value)

        # 认证
        sid = self.login()
        self.cli = Client(HTTP_AUTHORIZATION=sid)
        
        
    def test_ok(self):
        url = '/information'
        # res = requests.get(url, timeout=2) # 请勿使用,不然UT中临时创建的DB会无效
        res = self.cli.get(url)
        print(res.json())
        self.assertTrue(res.status_code==200)

    def test_404(self):
        url = '/not/exit/'
        # res = requests.get(url, timeout=2) # 请勿使用,不然UT中临时创建的DB会无效
        res = self.cli.get(url,timeout=0.5)
        print('>>>>>>>>>>>', res)
        self.assertTrue(res.status_code==404)
    
    def test_query_one_ok_report(self):
        '''
        查询已完成的任务
        若需要成功,需要把报告数据拷贝到runner容器的对应路径下
        '''
        url = '/task_admin/test_report'
        # res = requests.get(url, timeout=2) # 请勿使用,不然UT中临时创建的DB会无效
        res = self.cli.get(url, {'task_status':TaskEnum.SUCCESS.value,'page':1,'psize':1})
        print(res.json())
        self.assertTrue(res.status_code==200)
        res = res.json()
        self.assertTrue(len(res['data']['list'])==1)
        self.ok_series_id = res['data']['list'][0]['series_id']
        print(f'{self.__class__.__name__}--sid---{self.ok_series_id}')

    def test_post_suggest(self):
        '''
        修改建议
        '''
        url='/suggestion'
        self.SUGGESTION = 'haha'
        print(f'{self.__class__.__name__}--sid---{self.ok_series_id}')
        res = self.cli.post(url,{'series_id': self.ok_series_id,'suggestion': self.SUGGESTION}, content_type='application/json')
        print(res.json())
        self.assertTrue(res.status_code==200)
        
    def test_get_suggest(self):
        '''
        获取建议
        '''
        url='result'
        res = self.cli.get(url,{'series_id': self.ok_series_id})
        print(f'{self.__class__.__name__}--sid---{self.ok_series_id}')
        print('test_get_suggest', res.json())
        self.assertTrue(res.status_code==200)
        res = res.json()
        self.assertTrue(res['data']['doctor']['suggestion']==self.SUGGESTION)

​

有以下几点需要特别注意

  • 请求一定要使用from django.test import Client,否则测试数据会污染正式的数据库

  • Client设置hearder传参,比如像设置header的Authorization

    • 必须传HTTP_AUTHORIZATION=xxx

  • case中的test_*方法执行是无序的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值