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