Django項目使用CircleCI的方法示例
自從認識了 CircleCI 之后,基本上都在用這個了。相比于之前用的travis-ci ,CircleCI 丑是丑了點,但是相比與 travis 有幾點好處:
- CircleCI 基于 docker image 的,怎么做隔離的不太清楚,有可能是在虛擬機上面執(zhí)行 docker 來做隔離的,而 travis 還是基于 VM。這樣好的好處是,CircleCI 提供了很多 image,你可以組合出來很多服務(wù)。比如 Django 項目用到了 redis 和 MySQL,你只要在 yaml 里面加上這兩個 image 就好了,而 travis 要在 VM 里面處理好服務(wù)依賴。不僅不方便,每次執(zhí)行速度也慢很多。
- CircleCI 支持 private repo,travis 只支持開源 repo。
但要說缺點的話,CircleCI 用戶體驗實在不如 travis,配置比較復(fù)雜。每次用都會多少踩一些坑。這篇文章介紹一下一個 Django 項目接入的過程,和其中一些要注意的坑。
1. 設(shè)定好 Django 項目的測試和依賴
以前 Django 測試用的是 Django 自帶的 manage.py 里面的 test. 后來發(fā)現(xiàn)還是 pytest 比較好:插件多、模板代碼少些很多,fixture 的設(shè)計比較合理,測試中使用到 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è)置。
解釋一下每個參數(shù)是干嘛用的:
- 第一行是 Django 環(huán)境變量,用來區(qū)分測試使用的 django.conf.settings 和開發(fā)、生產(chǎn)用的;
- –resuse-db :pytest 測試復(fù)用DB,不必每次都創(chuàng)建然后執(zhí)行 migrations,對測試執(zhí)行速度的提升非常明顯。但是在 CircleCI 上運行測試,由于每次 MySQL 都是一個新的鏡像實例,所以還是要每次新建數(shù)據(jù)庫,執(zhí)行 migrations 的。這個參數(shù)只是在本地執(zhí)行的時候有用;
- –cov-config / –cov :這個是追蹤測試覆蓋率的 coverage.py 使用的配置文件,和要追蹤測試覆蓋率的文件夾;
- –cov-report :生成測試覆蓋率的格式,每次運行完測試之后,生成覆蓋率測試的文件。在 CircleCI 上我們可以設(shè)置測試運行完之后將這些文件上傳至 artifacts 上去,可以在瀏覽器看這些文件;
- –junitxml : 測試的 Summary,也可以在 CircleCI 上展示;
以上就是項目中測試的配置,現(xiàn)在運行 pytest 可以自動發(fā)現(xiàn)項目中的測試用例執(zhí)行了,并且測試完成后會生成測試報告。
接下來介紹如何在 CircleCI 上配置,實現(xiàn)每次 git push 之后自動執(zhí)行代碼。
2. 在 CircleCI 開啟 CI 和設(shè)置運行環(huán)境
接入的方式分兩步,根據(jù) CircleCI 的指引就可以:
- 用 Github 賬戶登陸 CircleCI,然后在 CircleCI 上導(dǎo)入 Github 的項目;
- 在項目中添加 .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 之類的服務(wù),只要在 docker 這里聲明就好了,CircleCI 在啟動測試的時候會幫你啟動這些容器。
build:docker 這里的配置就是用到的服務(wù),用到哪個配置就寫上 CircleCI 的 image 就好了,常用的都有,比較豐富。后面的 steps 來定義 CI 的步驟,一些事先定義好的 steps 可以參考下 文檔 , 比如 clone 代碼之類的就不需要自己實現(xiàn)了。
但是這里有一些挺坑的地方,需要注意。
使用 CircleCI 官方 MySQL 這個 image 需要設(shè)置驗證方式,不然的話會遇到以下這個錯誤:
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 啟動的,測試所在的容器并不會有這些服務(wù)的 sock 文件,實際上是啟動了不同的 image 然后通過 docker 的 network 放在一組,實現(xiàn)了訪問。
還有一個巨坑的地方是,有時候你依賴的服務(wù)還沒準備好,測試就開始執(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 和覆蓋率文件。效果如下:
test summary 展示
測試覆蓋率文件
注意 venv 不要建立在 working_directory 下面,不然你的 venv 里面的庫也會被追蹤測試覆蓋率。
最后再吐槽一下 Artifacts 沒有自動打開 index.html 的按鈕,每次都需要自己找到這個文件點開,有點反人類。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
pyecharts繪制各種數(shù)據(jù)可視化圖表案例附效果+代碼
這篇文章主要介紹了pyecharts繪制各種數(shù)據(jù)可視化圖表案例并附效果和代碼,文章圍繞主題展開詳細的內(nèi)容介紹,感興趣的小伙伴可以參考一下2022-06-06Python虛擬環(huán)境virtualenv的安裝與使用詳解
virtualenv可以用來管理互不干擾的獨立python虛擬環(huán)境,在有些場景下非常有用,下面這篇文章主要給大家介紹了Python虛擬環(huán)境virtualenv安裝與使用的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。2017-05-05Python flask框架定時任務(wù)apscheduler應(yīng)用介紹
Flask是Python社區(qū)非常流行的一個Web開發(fā)框架,本文將嘗試將介紹APScheduler應(yīng)用于Flask之中實現(xiàn)定時任務(wù),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-10-10小白教你PyCharm從下載到安裝再到科學(xué)使用PyCharm2020最新激活碼
這篇文章主要介紹了PyCharm最新版從下載到安裝再到科學(xué)使用PyCharm2020最新激活碼,需要的朋友可以參考下2020-09-09使用python編寫批量卸載手機中安裝的android應(yīng)用腳本
該腳本的功能是卸載android手機中安裝的所有第三方應(yīng)用,主要是使用adb shell pm、adb uninstall 命令,需要的朋友可以參考下2014-07-07python游戲?qū)崙?zhàn)項目之童年經(jīng)典超級瑪麗
史上十大最經(jīng)典小霸王游戲中魂斗羅只能排在第二,那么第一是誰?最經(jīng)典最風(fēng)靡的當(dāng)屬超級瑪麗,那個戴帽子的大胡子穿著背帶褲的馬里奧哪個不認得,小編帶你用python實現(xiàn)超級瑪麗緬懷童年2021-09-09