Django项目使用CircleCI的方法示例

自从认识了 CircleCI之后,基本上都在用这个了。相比于之前用的travis-ci,CircleCI 丑是丑了点,但是相比与 travis 有几点好处:

  1. CircleCI 基于 docker image 的,怎么做隔离的不太清楚,有可能是在虚拟机上面执行 docker 来做隔离的,而 travis 还是基于 VM。这样好的好处是,CircleCI 提供了很多 image,你可以组合出来很多服务。比如 Django 项目用到了 redis 和 MySQL,你只要在 yaml 里面加上这两个 image 就好了,而 travis 要在 VM 里面处理好服务依赖。不仅不方便,每次执行速度也慢很多。
  2. CircleCI 支持 private repo,travis 只支持开源 repo。

但要说缺点的话,CircleCI 用户体验实在不如 travis,配置比较复杂。每次用都会多少踩一些坑。这篇文章介绍一下一个 Django 项目接入的过程,和其中一些要注意的坑。

1. 设定好 Django 项目的测试和依赖

以前 Django 测试用的是 Django 自带的 manage.py 里面的 test. 后来发现还是 pytest 比较好:插件多、模板代码少些很多,fixture 的设计比较合理,测试中使用到 db 需要明确声明,否则无法 access db,这样更加 explicit,测试执行的速度也更快。

除了 pytest,其他的还有一些依赖, test-requirements.txt 文件的内容如下:

 File: test-requirements.txt
 -r dev-requirements.txt
 factory_boy
 pytest-cov
 pytest-django

其中 pytest-django 是 pytest 继承到 Django 中去了,pytest-cov 是追踪测试覆盖率的,factory_boy 是可以根据 Django 的 ORM 自动生产测试需要的 Model (这个强烈推荐,如果不用这个的话,需要写一推 json 来事先定义好测试用的 Model,后续维护也很费劲,如果改了一个不需要测试的 Model 的 Field,这些 json 也需要维护)。

然后运行 Django 测试,使用 pytest 命令就好了:

$ DJANGO_SETTINGS_MODULE = myproject.settings.testing pytest --reuse-db --cov-config=.coveragerc --cov=. --cov-report=html --junitxml=test-reports/junit.xml

这个命令太长了,我们可以将环境变量和命令参数写到 pytest.ini 文件中去:

File: pytest.ini
 [pytest]
 DJANGO_SETTINGS_MODULE = easycron.settings.testing
 addopts = --reuse-db --cov-config=.coveragerc --cov=. --cov-report=html --junitxml=test-reports/junit.xml

这样每次测试,使用 pytest 这个命令就可以了,参数和环境变量会自动设置。

解释一下每个参数是干嘛用的:

  • 第一行是 Django 环境变量,用来区分测试使用的 django.conf.settings 和开发、生产用的;
  • –resuse-db :pytest 测试复用DB,不必每次都创建然后执行 migrations,对测试执行速度的提升非常明显。但是在 CircleCI 上运行测试,由于每次 MySQL 都是一个新的镜像实例,所以还是要每次新建数据库,执行 migrations 的。这个参数只是在本地执行的时候有用;
  • –cov-config / –cov :这个是追踪测试覆盖率的 coverage.py 使用的配置文件,和要追踪测试覆盖率的文件夹;
  • –cov-report :生成测试覆盖率的格式,每次运行完测试之后,生成覆盖率测试的文件。在 CircleCI 上我们可以设置测试运行完之后将这些文件上传至 artifacts 上去,可以在浏览器看这些文件;
  • –junitxml : 测试的 Summary,也可以在 CircleCI 上展示;

以上就是项目中测试的配置,现在运行 pytest 可以自动发现项目中的测试用例执行了,并且测试完成后会生成测试报告。

接下来介绍如何在 CircleCI 上配置,实现每次 git push 之后自动执行代码。

2. 在 CircleCI 开启 CI 和设置运行环境

接入的方式分两步,根据 CircleCI 的指引就可以:

  1. 用 Github 账户登陆 CircleCI,然后在 CircleCI 上导入 Github 的项目;
  2. 在项目中添加 .circleci/config.yml 配置文件,git push,就会自动触发 CircleCI 的 build 了。

其中配置文件以我的这个项目为例,配置文件如下(基本上是拿 CircleCI 的配置模板修改了一下,保留了注释):

# Python CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-python/ for more details
#
version: 2
jobs:
 build:
  docker:
   # specify the version you desire here
   # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers`
   - image: circleci/python:3.7.1

   # Specify service dependencies here if necessary
   # CircleCI maintains a library of pre-built images
   # documented at https://circleci.com/docs/2.0/circleci-images/
   # - image: circleci/postgres:9.4
   - image: circleci/redis:5.0.1
   - image: circleci/mysql:8.0.12
    environment:
     MYSQL_DATABASE: test_easycron_
     MYSQL_ROOT_HOST: "%"
     MYSQL_USER: easycron
     MYSQL_PASSWORD: 123
    command: [--default-authentication-plugin=mysql_native_password]

  working_directory: ~/repo

  steps:
   - checkout

   - run:
     name: install dockerize
     command: wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && sudo tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
     environment:
      DOCKERIZE_VERSION: v0.3.0
   - run:
     name: Wait for db
     command: dockerize -wait tcp://localhost:3306 -timeout 1m

   # Download and cache dependencies
   - restore_cache:
     keys:
      - v3-dependencies-{{ checksum "test-requirements.txt" }}
      # fallback to using the latest cache if no exact match is found
      - v3-dependencies-

   - run:
     name: install dependencies
     command: |
      python3 -m venv ~/venv
      . ~/venv/bin/activate
      pip install -r test-requirements.txt

   - save_cache:
     paths:
      - ~/venv
     key: v3-dependencies-{{ checksum "test-requirements.txt" }}

   # run tests!
   # this example uses Django's built-in test-runner
   # other common Python testing frameworks include pytest and nose
   # https://pytest.org
   # https://nose.readthedocs.io
   - run:
     name: run tests
     command: |
      . ~/venv/bin/activate
      pytest

   - store_test_results:
     path: test-reports

   - store_artifacts:
     path: htmlcov
     destination: htmlcov

前面说过 CircleCI 是基于 Docker 的,它的一个好处就是:如果你需要 MySQL、Redis 之类的服务,只要在 docker 这里声明就好了,CircleCI 在启动测试的时候会帮你启动这些容器。

build:docker 这里的配置就是用到的服务,用到哪个配置就写上 CircleCI 的 image就好了,常用的都有,比较丰富。后面的 steps 来定义 CI 的步骤,一些事先定义好的 steps 可以参考下 文档, 比如 clone 代码之类的就不需要自己实现了。

但是这里有一些挺坑的地方,需要注意。

使用 CircleCI 官方 MySQL 这个 image 需要设置验证方式,不然的话会遇到以下这个错误:

E MySQLdb._exceptions.OperationalError: (2059, "Authentication plugin 'caching_sha2_password' cannot be loaded: /usr/lib/x86_64-linux-gnu/mariadb18/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory")

MySQL,redis 等都不能通过 .sock 文件访问,访问的时候不要使用 localhost,使用 IP。因为本质上这不是在同一个 image 启动的,测试所在的容器并不会有这些服务的 sock 文件,实际上是启动了不同的 image 然后通过 docker 的 network 放在一组,实现了访问。

还有一个巨坑的地方是,有时候你依赖的服务还没准备好,测试就开始执行了。我用的时候发现有的时候访问 MySQL 端口不通,有的时候却是通的。解决的方式也很挫,就是 31-38 行,使用 dockerize block 住这个 step,不断检查端口是否接受连接了。端口通了才继续执行后面的步骤。

这里为了加快测试的执行速度,可以将创建的 venv 缓存起来,参考上面的 restore cache 和 save cache 那一步。需要注意的是 key 加上了 checksum,这样依赖文件更改的时候可以自动重新安装。有个小坑的地方是 CircleCI 竟然没提供删除 cache 的功能,所以我的 key 加上了 v3 ,如果想弃用之前的 cache 的话,只要升级到 v4 就好了,cache 找不到自动安装新的。

最后两步是上传测试 Summary 和覆盖率文件。效果如下:

test summary 展示

测试覆盖率文件

注意 venv 不要建立在 working_directory 下面,不然你的 venv 里面的库也会被追踪测试覆盖率。

最后再吐槽一下 Artifacts 没有自动打开 index.html 的按钮,每次都需要自己找到这个文件点开,有点反人类。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 教你如何将 Sublime 3 打造成 Python/Django IDE开发利器

    1. 安装 Sublime Text 3 虽然现在的 Sublime 3 还处于 beta 阶段, 但已经非常稳定了, 而且速度比 Sublime 2 得到了增强. Sublime 3 可以到官网下载并安装. Sublime 虽然是免费软件, 但如果有足够的经济能力, 可以考虑购买以表示支持. 2. 安装 Package Control Sublime Package Control 可以说是必须安装的插件, 因为其方便的提供了安装/升级/删除 Sublime 插件的功能, 安装方法见Packa

  • python Django连接MySQL数据库做增删改查

    1.下载安装MySQLdb类库http://www.djangoproject.com/r/python-mysql/2.修改settings.py 配置数据属性 复制代码 代码如下: DATABASES = {    'default': {        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.        'NAME': 'djang

  • 使用python Django做网页

    1 .创建一个django项目使用django-admin.py startproject MyDjangoSite 参考这里 2.建立视图from django.http import HttpResponsedef hello(request):    return HttpResponse("我的第一个简单的python django项目.")3.修改urls.py 我们为urlpatterns加上一行: (r'^hello/$', hello), 这行被称作URLpattern

  • python Django模板的使用方法(图文)

    模版基本介绍模板是一个文本,用于分离文档的表现形式和内容. 模板定义了占位符以及各种用于规范文档该如何显示的各部分基本逻辑(模板标签). 模板通常用于产生HTML,但是Django的模板也能产生任何基于文本格式的文档.来一个项目说明1.建立MyDjangoSite项目具体不多说,参考前面.2.在MyDjangoSite(包含四个文件的)文件夹目录下新建templates文件夹存放模版.3.在刚建立的模版下建模版文件user_info.html 复制代码 代码如下: <html>    <

  • 使用python搭建Django应用程序步骤及版本冲突问题解决

    首先你要确保你机器上面安装了python,其次,你还要确保你上面安装了Django.接下来,才能进入到搭建第一个Django应用程序很简单的操作,即在windows终端输入代码: 复制代码 代码如下: 1 django-admin.py startproject mysite 即可,如:我是在我电脑的   E:\Python33\python_workspace 目录下面创建项目的目录是你自己定的运行命令: 复制代码 代码如下: django-admin.py startproject mysi

  • Django框架中render_to_response()函数的使用方法

    通常的情况是,我们一般会载入一个模板文件,然后用 Context渲染它,最后返回这个处理好的HttpResponse对象给用户. 我们已经优化了方案,使用 get_template() 方法代替繁杂的用代码来处理模板及其路径的工作. 但这仍然需要一定量的时间来敲出这些简化的代码. 这是一个普遍存在的重复苦力劳动.Django为此提供了一个捷径,让你一次性地载入某个模板文件,渲染它,然后将此作为 HttpResponse返回. 该捷径就是位于 django.shortcuts 模块中名为 rend

  • Django中对数据查询结果进行排序的方法

    在你的 Django 应用中,你或许希望根据某字段的值对检索结果排序,比如说,按字母顺序. 那么,使用 order_by() 这个方法就可以搞定了. >>> Publisher.objects.order_by("name") [<Publisher: Apress>, <Publisher: O'Reilly>] 跟以前的 all() 例子差不多,SQL语句里多了指定排序的部分: SELECT id, name, address, city,

  • 教你安装python Django(图文)

    安装环境:python版本2.7.5 ,win7系统安装Djangohttps://www.djangoproject.com/download/ 官方下载Django-1.5.5.tar.gz1,解压后(我的目录是D:\myapp\Django-1.5.5)2,DOS命令到刚解压后的Django-1.5.5目录下执行命令 python setup.py install , 结果如下图: 说明:Django安装命令实际是将Django复制到本地Python安装目录D:\Python27\Lib\

  • Django中几种重定向方法

    这里使用的是django1.5 需求: 有一个界面A,其中有一个form B, 前台提交B之后,后台保存数据之后,返回界面A,如果保存失败需要在A界面提示错误. 这里就需要后台的重定向,而且需要可以带着参数,也就是error message 这里收集了几种方法,简答说下需要那些包,怎么简单使用. 一. 使用HttpResponseRedirect The first argument to the constructor is required – the path to redirect to

  • Django项目使用CircleCI的方法示例

    自从认识了 CircleCI之后,基本上都在用这个了.相比于之前用的travis-ci,CircleCI 丑是丑了点,但是相比与 travis 有几点好处: CircleCI 基于 docker image 的,怎么做隔离的不太清楚,有可能是在虚拟机上面执行 docker 来做隔离的,而 travis 还是基于 VM.这样好的好处是,CircleCI 提供了很多 image,你可以组合出来很多服务.比如 Django 项目用到了 redis 和 MySQL,你只要在 yaml 里面加上这两个 i

  • 获取Django项目的全部url方法详解

    在为一个项目添加权限时,遇到一个问题,就是为项目所有的url设置权限,但是一个一个手动输入太麻烦了,所以考虑用代码获取到一个项目所有的url 首先,考虑到项目最外层的urlpartterns,因为所有的url都要通过这里 urlpatterns = [ # url(r'^admin/', admin.site.urls), url(r'^arya/', site.urls), url(r'^index/', index), ] 先循环打印一下这个列表,看一下拿到的结果: <RegexURLRes

  • django上传图片并生成缩略图方法示例

    django 处理上传图片生成缩略图首先要注意form标签上必须有enctype="multipart/form-data"属性,另外要装好PIL库, 然后就很简单了,如下是实例代码: upload.html <div id="uploader"> <form id="upload" enctype="multipart/form-data" action="/ajax/upload/"

  • Vue-cli3生成的Vue项目加载Mxgraph方法示例

    使用Vue-cli3生成Vue项目,并等待项目创建成功. vue create [项目名] 安装mxgraph. cnpm install mxgraph --save 安装exports-loader. cnpm install exports-loader --save 安装script-loader. cnpm install script-loader --save 在项目根目录新建vue.config.js文件. 将以下内容复制到vue.config.js文件中. const path

  • Python3创建Django项目的几种方法(3种)

    Django是一种基于Python的Web开发框架 一.在命令行中创建Django项目(Windows平台.python3.6) 1.建立虚拟环境(创建一个独立的Python运行环境) 为项目新建一个目录learning_log,在终端切换到这个目录,并创建虚拟环境 这里运行了模块venv,并使用它创建一个名为ll_env的虚拟环境 注意:如果python是较早版本,则先安装virtualenv(pip3 install virtualenv)然后再创建虚拟环境(virtualenv ll_en

  • spring 项目实现限流方法示例

    目录 01.为什么AUSTIN项目需要限流 02.如何实现限流? 03.代码设计 04.总结 01.为什么AUSTIN项目需要限流 众所周知,服务器能处理的请求数是有限的,如果请求量特别大,我们就可能需要做限流. 限流处理的姿势:要么就让请求等待,要么就把请求给扔了 从系统架构来看,我们的统一处理入口在austin-api接入层上,austin-api接入层做完简单的参数校验以及参数拼接后,就将请求转发到消息队列上了 按正常来说,因为接了消息队列且接入层没有什么耗时的操作,那对外的接口压力不大的

  • Django框架模板的使用方法示例

    本文实例讲述了Django框架模板的使用方法.分享给大家供大家参考,具体如下: 创建模板文件夹 在项目下床架一个模板文件夹 在templates下面为了区分是哪一个应用的模板再建一个与应用同名的文件夹. 在setting.py的TEMLATES里配置模板文件的路径 在视图函数里return reder def index(request):#视图函数必须有一个参数 #进行处理,和M和T进行交互... # return HttpResponse('good') # #使用模板文件 # #1.加载模

  • 如何在Django中设置定时任务的方法示例

    Django 作为后端Web开发框架,有时候我们需要用到定时任务来或者固定频次的任务来执行某段代码,这时我们就要用到Celery了.Django中有一个中间件:Django-celery 环境: Python 3.6 Django为小于1.8版本 Celery为3.1版本 第一步安装:django-celery pip install django-celery 第二步:配置celery和任务 创建测试django环境: django-admin.py createproject test dj

  • Django实现组合搜索的方法示例

    一.实现方法 1.纯模板语言实现 2.自定义simpletag实现(本质是简化了纯模板语言的判断) 二.基本原理 原理都是通过django路由系统,匹配url筛选条件,将筛选条件作为数据库查询结果,返回给前端. 例如:路由系统中的url格式是这样: url(r'^article-(?P<article_type_id>\d+)-(?P<category_id>\d+).html',views.filter) 其中article_type_id和category_id和数据库中字段是

  • Django集成搜索引擎Elasticserach的方法示例

    1.背景 当用户在搜索框输入关键字后,我们要为用户提供相关的搜索结果.可以选择使用模糊查询 like 关键字实现,但是 like 关键字的效率极低.查询需要在多个字段中进行,使用 like 关键字也不方便,另外分词的效果也不理想. 全文检索方案 全文检索即在指定的任意字段中进行检索查询. 全文检索方案需要配合搜索引擎来实现. 搜索引擎原理 搜索引擎 进行全文检索时,会对数据库中的数据进行一遍预处理,单独建立起一份 索引结构数据 . 索引结构数据 类似字典的索引检索页 ,里面包含了关键词与词条的对

随机推荐