您好,登錄后才能下訂單哦!
自從認識了 CircleCI 之后,基本上都在用這個了。相比于之前用的travis-ci ,CircleCI 丑是丑了點,但是相比與 travis 有幾點好處:
但要說缺點的話,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 這個命令就可以了,參數和環境變量會自動設置。
解釋一下每個參數是干嘛用的:
以上就是項目中測試的配置,現在運行 pytest 可以自動發現項目中的測試用例執行了,并且測試完成后會生成測試報告。
接下來介紹如何在 CircleCI 上配置,實現每次 git push 之后自動執行代碼。
2. 在 CircleCI 開啟 CI 和設置運行環境
接入的方式分兩步,根據 CircleCI 的指引就可以:
其中配置文件以我的這個項目為例,配置文件如下(基本上是拿 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 的按鈕,每次都需要自己找到這個文件點開,有點反人類。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。