溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Django項目使用CircleCI的方法示例

發(fā)布時間:2020-10-06 06:34:10 來源:腳本之家 閱讀:153 作者:卡瓦邦噶! 欄目:開發(fā)技術(shù)

自從認識了 CircleCI 之后,基本上都在用這個了。相比于之前用的travis-ci ,CircleCI 丑是丑了點,但是相比與 travis 有幾點好處:

  1. CircleCI 基于 docker image 的,怎么做隔離的不太清楚,有可能是在虛擬機上面執(zhí)行 docker 來做隔離的,而 travis 還是基于 VM。這樣好的好處是,CircleCI 提供了很多 image,你可以組合出來很多服務。比如 Django 項目用到了 redisMySQL,你只要在 yaml 里面加上這兩個 image 就好了,而 travis 要在 VM 里面處理好服務依賴。不僅不方便,每次執(zhí)行速度也慢很多。
  2. CircleCI 支持 private repo,travis 只支持開源 repo。

但要說缺點的話,CircleCI 用戶體驗實在不如 travis,配置比較復雜。每次用都會多少踩一些坑。這篇文章介紹一下一個 Django 項目接入的過程,和其中一些要注意的坑。

1. 設定好 Django 項目的測試和依賴

以前 Django 測試用的是 Django 自帶的 manage.py 里面的 test. 后來發(fā)現(xiàn)還是 pytest 比較好:插件多、模板代碼少些很多,fixture 的設計比較合理,測試中使用到 db 需要明確聲明,否則無法 access db,這樣更加 explicit,測試執(zhí)行的速度也更快。

除了 pytest,其他的還有一些依賴, test-requirements.txt 文件的內(nèi)容如下:

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

其中 pytest-django 是 pytest 繼承到 Django 中去了,pytest-cov 是追蹤測試覆蓋率的,factory_boy 是可以根據(jù) Django 的 ORM 自動生產(chǎn)測試需要的 Model (這個強烈推薦,如果不用這個的話,需要寫一推 json 來事先定義好測試用的 Model,后續(xù)維護也很費勁,如果改了一個不需要測試的 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

這個命令太長了,我們可以將環(huán)境變量和命令參數(shù)寫到 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 這個命令就可以了,參數(shù)和環(huán)境變量會自動設置。

解釋一下每個參數(shù)是干嘛用的:

  • 第一行是 Django 環(huán)境變量,用來區(qū)分測試使用的 django.conf.settings 和開發(fā)、生產(chǎn)用的;
  • –resuse-db :pytest 測試復用DB,不必每次都創(chuàng)建然后執(zhí)行 migrations,對測試執(zhí)行速度的提升非常明顯。但是在 CircleCI 上運行測試,由于每次 MySQL 都是一個新的鏡像實例,所以還是要每次新建數(shù)據(jù)庫,執(zhí)行 migrations 的。這個參數(shù)只是在本地執(zhí)行的時候有用;
  • –cov-config / –cov :這個是追蹤測試覆蓋率的 coverage.py 使用的配置文件,和要追蹤測試覆蓋率的文件夾;
  • –cov-report :生成測試覆蓋率的格式,每次運行完測試之后,生成覆蓋率測試的文件。在 CircleCI 上我們可以設置測試運行完之后將這些文件上傳至 artifacts 上去,可以在瀏覽器看這些文件;
  • –junitxml : 測試的 Summary,也可以在 CircleCI 上展示;

以上就是項目中測試的配置,現(xiàn)在運行 pytest 可以自動發(fā)現(xiàn)項目中的測試用例執(zhí)行了,并且測試完成后會生成測試報告。

接下來介紹如何在 CircleCI 上配置,實現(xiàn)每次 git push 之后自動執(zhí)行代碼。

2. 在 CircleCI 開啟 CI 和設置運行環(huán)境

接入的方式分兩步,根據(jù) CircleCI 的指引就可以:

  1. 用 Github 賬戶登陸 CircleCI,然后在 CircleCI 上導入 Github 的項目;
  2. 在項目中添加 .circleci/config.yml 配置文件,git push,就會自動觸發(fā) 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 代碼之類的就不需要自己實現(xiàn)了。

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

使用 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。因為本質(zhì)上這不是在同一個 image 啟動的,測試所在的容器并不會有這些服務的 sock 文件,實際上是啟動了不同的 image 然后通過 docker 的 network 放在一組,實現(xiàn)了訪問。

還有一個巨坑的地方是,有時候你依賴的服務還沒準備好,測試就開始執(zhí)行了。我用的時候發(fā)現(xiàn)有的時候訪問 MySQL 端口不通,有的時候卻是通的。解決的方式也很挫,就是 31-38 行,使用 dockerize block 住這個 step,不斷檢查端口是否接受連接了。端口通了才繼續(xù)執(zhí)行后面的步驟。

這里為了加快測試的執(zhí)行速度,可以將創(chuàng)建的 venv 緩存起來,參考上面的 restore cache 和 save cache 那一步。需要注意的是 key 加上了 checksum,這樣依賴文件更改的時候可以自動重新安裝。有個小坑的地方是 CircleCI 竟然沒提供刪除 cache 的功能,所以我的 key 加上了 v3 ,如果想棄用之前的 cache 的話,只要升級到 v4 就好了,cache 找不到自動安裝新的。

最后兩步是上傳測試 Summary 和覆蓋率文件。效果如下:

Django項目使用CircleCI的方法示例

test summary 展示

Django項目使用CircleCI的方法示例

測試覆蓋率文件

注意 venv 不要建立在 working_directory 下面,不然你的 venv 里面的庫也會被追蹤測試覆蓋率。

最后再吐槽一下 Artifacts 沒有自動打開 index.html 的按鈕,每次都需要自己找到這個文件點開,有點反人類。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI