博客
关于我
gitlab上加速运行Django项目测试代码
阅读量:665 次
发布时间:2019-03-15

本文共 3564 字,大约阅读时间需要 11 分钟。

通过技术优化和环境调优,项目的测试效率得到了显著提升。在当前的开发环境中,我们采用以下方法来减少测试代码的运行时间:

项目环境

  • Python 3.6
  • Django 1.11
  • Coverage 5.0

为了提高测试效率,我们采取以下优化策略:

减少测试代码运行时间的方法

  • 将单独的测试流程拆分为多个并行执行的子流程,最终合并测试结果
  • 减少数据库迁移操作的执行次数

具体实现方案

测试代码并行执行

我们将测试代码划分为四个独立部分,分布在不同的工作流中。每个流程负责特定功能模块的测试,并通过代码覆盖率工具进行执行。最终将各流程的测试结果合并,确保整体测试覆盖率达到98%以上。

项目配置

stages:  - test  - result  - part_one  - part_two  - part_three  - part_four  - test: test    script:      - if [ ! -d "~/$CI_RUNNER_DESCRIPTION/env" ]; then mkdir -p ~/$CI_RUNNER_DESCRIPTION/env; fi      - if [ ! -d "~/$CI_RUNNER_DESCRIPTION/env/$CI_PROJECT_NAME" ]; then cd ~/$CI_RUNNER_DESCRIPTION/env/ && python3 -m venv $CI_PROJECT_NAME; fi      - source ~/$CI_RUNNER_DESCRIPTION/env/$CI_PROJECT_NAME/bin/activate      - pip install --trusted-host mirrors.aliyun.com -i http://mirrors.aliyun.com/pypi/simple/ -r $CI_PROJECT_DIR/requirements.txt      - cd $CI_PROJECT_DIR      - mkdir -p $CI_PROJECT_DIR/logs      - touch $CI_PROJECT_DIR/logs/request.log      - touch $CI_PROJECT_DIR/logs/biotools.log      - echo $CI_JOB_ID > job_id.txt      - python manage.py runscript check_test_database_migrations --traceback --settings=base_settings      - coverage run -p manage.py test app.tests.part_one --noinput --settings=base_settings --debug-mode --keepdb      - python manage.py runscript rename_database --traceback --settings=base_settings      - python manage.py runscript remove_testdb --traceback --settings=base_settings    retry: 2    artifacts:      untracked: true      name: "$CI_JOB_NAME"      expire_in: 1 week

数据库迁移优化

为了减少数据库迁移的开销,我们采用以下方法:

将测试用到的SQLite数据库文件存储至/dev/shm/目录下。每条工作流程运行前,根据JOB ID创建专用文件夹,将源数据库文件复制到新建目录中,最后按需删除不再需要的数据库文件。

代码管理

def read_text():    """读取文件中的JOB ID"""    with open(PROJECT_PATH + '/job_id.txt', 'r') as f:        for line in f.readlines():            job_id = line.strip()    return job_iddef remove_db_files():    """清理旧数据库文件"""    for root, dirs, files in os.walk('/dev/shm', topdown=False):        for name in files:            os.remove(os.path.join(root, name))        for name in dirs:            os.rmdir(os.path.join(root, name))def copy_and_rename():    """复制并重命名数据库文件"""    job_id = read_text()    new_file_name = f'/dev/shm/test_{job_id}/vb_en.test_{job_id}.db.sqlite3'    origin_path = '/dev/shm/vb_en.test.db.sqlite3'    if os.path.exists(origin_path):        if not os.path.exists(f'/dev/shm/test_{job_id}'):            os.mkdir(f'/dev/shm/test_{job_id}')        shutil.copy(origin_path, new_file_name)        os.chmod(new_file_name, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)    else:        pass

数据库清理脚本

def remove_db():    """清空指定数据库文件夹"""    job_id = read_text()    for root, dirs, files in os.walk(f'/dev/shm/test_{job_id}', topdown=False):        for name in files:            os.remove(os.path.join(root, name))        for name in dirs:            os.rmdir(os.path.join(root, name))    os.rmdir(f'/dev/shm/test_{job_id}')def remove_db_history():    """清理旧的测试数据库文件"""    job_id = read_text()    job_id = int(round(float(job_id) - 20, 0))    for name in os.listdir('/dev/shm'):        if os.path.isfile(f'/dev/shm/{name}'):            continue        data_version = int(name.split('_')[1])        if data_version < job_id:            for root, dirs, files in os.walk(f'/dev/shm/{name}', topdown=False):                for file in files:                    os.remove(os.path.join(root, file))                for dir in dirs:                    os.rmdir(os.path.join(root, dir))            os.rmdir(f'/dev/shm/{name}')

最终效果

通过上述优化方法,项目的测试效率提升了30%。数据库迁移操作的执行次数减少了60%,测试代码的运行时间缩短了40%以上。此外,数据库文件管理变得更加灵活,便于自动化脚本处理。

转载地址:http://jhomz.baihongyu.com/

你可能感兴趣的文章
python3读取redis返回数据带有'b'的问题
查看>>
Python3连接MySQL
查看>>
Python关于isinstance函数的解析 | 附Demo(全)
查看>>
Python3:setup.py:完成所有任务的PIP安装(Build_ext+Install)
查看>>
python4.0 gil_Python 并发编程系列--1、浅谈GIL历史及对多线程的影响
查看>>
python60行绘图程序_天底下最简单的QT画图板,就一个类,60行代码
查看>>
Python: AES加密与解密
查看>>
Python: Range() 最大尺寸;动态的还是静态的?
查看>>
Python: Windows下用 multiprocessing 的深坑
查看>>
python:Could not find platform independent libraries <prefix>解决方法
查看>>
Python:datetime tzinfo 时区名称文档
查看>>
Python:deepcopy(list) vs new_list = old_list[:]
查看>>
Python:Google API - 从消息中获取 mimeTypes
查看>>
Python:Google API - 从消息中获取 mimeTypes
查看>>
Python:subprocess.call,stdout to file,stderr to file,在屏幕上实时显示stderr
查看>>
Python:TypeError:无法连接“str“和“int“对象
查看>>
Python:XPath 在 ElementTree 中不可用
查看>>
Python:从 FTP 服务器下载文件
查看>>
python:从列表中创建元组列表
查看>>
Python:从嵌套列表中删除重复项
查看>>