前段時間讀到一篇優秀的文章《前端開源項目持續集成三劍客》,就想試着運用到本身的項目中去。(好吧,老實說,我只是個徽章收集愛好者。)html
持續集成,這個概念對後端來講應該並不陌生,甚至能夠說是司空見慣吧。可是,這對曾經(除了那些大廠)單元測試都不必定要寫的前端來講,或許是個陌生的詞。前端
然而,隨着前端飛速地發展,不斷吸收後端長久以來積累的經驗,以及前端對單元測試愈來愈重視,持續集成做爲前端工程化中的一項也漸漸進入人們的視野。node
那麼,持續集成到底是什麼?react
持續集成(英語:Continuous integration,縮寫爲 CI),一種軟件工程流程,將全部工程師對於軟件的工做複本,天天集成數次到共用主線(mainline)上。 —— wikipedialinux
簡單來講,就是以必定的頻率將代碼整合到一塊兒。git
使用持續集成能使項目:github
保持可測試和可發佈的狀態web
易於追蹤錯誤,當集成產生錯誤時,能將錯誤產生的縮小範圍到上次成功集成以後的提交chrome
版本回滾也變得垂手可得npm
在《前端開源項目持續集成三劍客》中,做者推薦了 2 個集成工具,分別是:travis-ci 和 circleci。
額...該選哪一個哪?
分別粗略地瞭解了這兩個產品,它倆的網站的都很是簡潔,文檔也很清晰,功能上也大體相同。雖然,circleci 比 travis-ci 多了 Bitbucket 源碼庫的支持,可是,有一大硬傷 circleci 只對一個 container 免費,並且,若使用 OS X 須要額外收費。與之相反,travis-ci 只要是 Github 上的開源項目所有免費,且支持在 OS X 運行。
Travis-ci。
註冊 travis 只需一步,點擊 Sign In 按鈕綁定 Github。登陸後,執行 travis 只需如下 3 步:
添加須要 travis 管理的項目
爲項目添加 .travis.yml 配置文件
提交代碼
與此同時,travis 的配置也極其簡單。若是沒有什麼特別的需求,那麼,只需配置運行語言類型及其版本就行。
// .travis.yml language: node_js node_js: - "6"
這樣,一個簡單、可用的 travis 配置就完成了。
Travis 構建過程主要分爲兩步:
install:安裝依賴,在 node 環境下,默認運行 npm install
stript:運行構建命令,在 node 環境下,默認運行 npm test
那麼,上面的代碼就等價於:
language: node_js node_js: - "6" install: npm install script: npm test
固然,travis 不止這兩個生命週期,額外的配置需求均可以到官網查看。
OK。提交代碼試試吧。
travis 的運行信息均可以在 Job log 中看到。
若是運行成功,你就能夠經過 https://img.shields.io/travis... 或 https://img.shields.io/travis... 來給你的項目添加 badge 了,就像這樣 。
Tips:其中的 USER, REPO, BRANCH 都要替換成我的信息。
有了構建的徽章,接着再弄一個測試覆蓋率的徽章。三劍客文章中用的是 coveralls,但進入它的官網發現,它和當今網站那種簡潔風格不一樣,畫風有點 classic 啊~文檔也不太詳細,比較簡單,就查了下有沒有其餘更好的?
因而,發現了 codecov。
乾淨、免費,我喜歡。
文檔也相對於 coveralls 更清晰、詳細。在嘗試以後,更是以爲個人選擇是明智的。^_^
codecov 的使用至關簡單,甚至不用看文檔就能夠輕易配置。
首先,登陸首頁,根據本身源碼的存儲位置選擇相應的登陸按鈕,這裏我選擇 Github,第一次登陸會須要你的受權。
受權成功以後,就能看到相似下面的圖,分別對應你的我的帳戶以及你所加入的組織。
第一次使用時,默認是沒有 repository 的,須要經過點擊 + Add my first repository
來添加須要 codecov 管理的 repository。
選擇相應的 repository 以後,你能夠看到一個相似下面的頁面。固然,數據什麼確定是沒有的。
前幾個 tab 是用來展現信息的,在配置完成並運行以前是沒有信息的,配置的時候只須要看最後一個 setting tab。
切換左側的菜單,就能分別看到 setting 和 badge 的信息,是否是超級贊?
不管 codecov 仍是 coveralls,它自身都不會去運行測試用例來得到項目代碼的覆蓋率,而是經過收集覆蓋率報告及其餘關鍵信息來靜態分析。
codecov 能夠接收 lcov, gcov 以及正確的 json 數據格式做爲輸入信息。
因而,若是你使用 JEST 做爲測試框架,並開啓測試覆蓋率(collectCoverage),因爲,JEST 使用 istanbul 生成覆蓋率報告,即 lcov。那麼,上傳報告就異常簡單了。只需安裝 codecov
npm install codecov --save-dev
而後,在 CI 執行以後,上傳報告就行。好比,像這樣
language: node_js node_js: - "6" cache: directories: node_modules script: - npm run test:coverage # 這裏我沒有全局安裝 codecov,因此要經過 npm 來運行 codecov - npm run codecov os: - linux - osx
此次的 badge 如何獲取上面有寫到,這裏就再也不展現了。
跨瀏覽器測試一樣有 2 個選擇,此次我同三劍客的做者站在了同一戰線,選擇使用 SAUCELABS。
SAUCELABS 開源免費帳號註冊方式隱藏得比較好,找不到的能夠點這裏。
不過,因爲 JEST 不支持 end-to-end 測試,因此,爲了作跨瀏覽器測試咱們不得不尋求其餘的測試框架來幫助完成這一工做。這裏我並不打算使用 karma,即便是 karma 同 SAUCELABS 有現成的集成插件 karma-sauce-launcher 可使用。
不要問我爲何,就是這麼任(jue)性(jiang)。
你真不問麼?那我就說了吧。由於現有的測試框架 JEST 已經能夠完成 karma 的大部分工做,單純爲 end-to-end 測試單獨引入 karma 就沒有必要了。
通過一番資料收集和比較以後,我選擇 Nightwatch 來解決跨瀏覽器測試的問題。
What's Nightwatch?
Nightwatch.js is an automated testing framework for web applications and websites, written in Node.js and using the W3C WebDriver API (formerly Selenium WebDriver).
It is a complete browser (End-to-End) testing solution which aims to simplify the process of setting up Continuous Integration and writing automated tests.
能夠從官網的介紹中看到,Nightwatch 對咱們當前想解決的問題簡直是正中下懷啊!(若是你的項目使用的是 Angular,那麼,你也能夠試試 Protractor)
在查資料時,發現 nightwatch 的第一個 issue 居然是尤大大提的。
走得越遠,越是發現一路都是大大們留下的足跡。
膜拜大大。
回到正題,使用 nightwatch 創建 e2e 測試也是至關容易的,這裏就簡要說一下流程。
首先,使用 npm 進行安裝,這就很少說了。
而後,在根目錄下添加配置文件,能夠是 nightwatch.conf.js,也能夠是 nightwatch.json。
接着,寫對應的測試,API 參考官網。
最後,跑測試命令就行了。
主要是來看看,怎麼將 nightwatch 的測試同 saucelabs 以及 travis-ci 整合到一塊兒。先看看測試文件。
// nightwatch.conf.js module.exports = { src_folders: ['tests/e2e'], // 測試文件目錄 output_folder: 'tests/reports', // 測試報告地址 custom_commands_path: 'tests/saucelabs', // 自定義命令,這裏用來更新測試信息到 saucelabs custom_assertions_path: '', page_objects_path: '', globals_path: '', test_workers: { enabled: true, workers: 'auto' }, test_settings: { default: { launch_url: 'http://localhost:8080', // 目標地址,用於測試中讀取 selenium_port: 4445, // selenium server 的端口(selenium server 由 saucelabs 提供) selenium_host: 'localhost', // selenium server 的地址(selenium server 由 saucelabs 提供) username: process.env.SAUCE_USERNAME, access_key: process.env.SAUCE_ACCESS_KEY, silent: true, screenshots: { enabled: false, path: '' }, globals: { waitForConditionTimeout: 15000 }, // 如下重要!!! desiredCapabilities: { build: `build-${process.env.TRAVIS_JOB_NUMBER}`, public: 'public', 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER } }, // 如下是不一樣環境的配置 chrome: { desiredCapabilities: { browserName: 'chrome' } }, firefox: { desiredCapabilities: { browserName: 'firefox' } }, internet_explorer_10: { desiredCapabilities: { browserName: 'internet explorer', version: '10' } }, internet_explorer_11: { desiredCapabilities: { browserName: 'internet explorer', version: '11' } }, edge: { desiredCapabilities: { browserName: 'MicrosoftEdge' } } } };
這裏要注意如下幾點:(重要!!!這些折磨了我近一週)
運行 localhost 測試,要開啓 sauce connect
開啓 sauce connect 以後,設置運行環境 selenium_port: 4445
, selenium_host: 'localhost'
以上幾點是本地測試時需注意的,下面是連通 travis 時需注意的:
配置 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER
,其中 process.env.TRAVIS_JOB_NUMBER
是 travis 運行時的全局變量
配置 process.env.SAUCE_USERNAME
和 process.env.SAUCE_ACCESS_KEY
,後面細講
配置 build
和 public
屬性,分別用於標識測試和查看權限,這兩點對最後生成 browser matrix badge 有用,這兩點在三劍客的文章中也有提到
配置好了 nightwatch 同 saucelabs,再修改下 travis 的配置,將 saucelabs 整合進去。
// .travis.yml language: node_js node_js: - '6' cache: directories: node_modules # 用於打包,並在 travis 上啓動本地服務,用於 e2e test before_script: - npm run build - node server.js & script: - npm run test:coverage - npm run codecov - npm run test:e2e os: - linux - osx env: global: - secure: v6CRj4CKMqxEQ9MSYKAkbmrBgIBZvoppICx6JyjQXhexPOVQKBvboCgdL0lOOZdGZ9rEqSMXvud97kBAFYd1sdP/kSwXdUct5BOMIT3a5GLtY5aQfOocBwR6IvmZpO2U+4VhrCwkzdaq2Ehq0fAXF1pkxDj9YkJZmwDNhTdfDGkib+AwDyr4TLQFC1QrD/4vmrULb3NZdW1KadFYjLzVF8FMa2tDSYMFFVymYu5nuCa/Z0dqSfFy8McYwBMzThDkDRHMT/sf4zKDPyxUwN7xGfC6T88xzCEaltN6K7MGMGKvl7Y0p7VjYW/+rO38936kj6xuPU6J7Vh2yKPJhhT2LtM7ucuo0XSpIxCxaKXWeEmYl2KkCMWNHgrWACE//WBFRNx/JQHimw+abr1Zt/3V9QmSEvnB3hHB0NQgJ2nVrVDjk51RSVaiP4sfQ8GVqEwr1+wJqe4wz7fV+jvRB9uUGgGsjsBbZi6ZycoMtOBoJ+miviRCjZvf9sOZKfIDjcuE5vETQcE37d/++yplCG0N83Kx+q67mbWXirfNj2CfXp7pwHTN+n21v1BSicXqQ6+jaNzD/pcN/GTHgZ5A+VkdcjSmEziuQTO035i1nnCB9TQdFeRdGdfo6DAiq8YOfyVkQ1lml6lWqbPqa4QWokRUD2yA/hAIzNWe5BeLF2JFQBc= - secure: S0vWVM74eiAHhk+kqqvym9aIgqaaGyGz9H3rfmEZoG4iuvXjXRaHOOSHxIRVsh5RYXr0PWHAj24fpN5AyUOlu5NQiwACBqmpw9KZBgVekWFshA5uYmpNpCG9w5/UAQa9q2+EcndOCM4lAyuT2wVJ5WfsHRzIA5jUpK1YmUYtuVICTSkumRoEaxfPkwzcGLF7f6aP7mG1YRKeO1F9+RhBfaGN1kYordxIk/fniH8OFB0XiLZ5OIovaAIYFKic0P1wUFwa78jU2fovdObS8JySl2LP19eaLX0MgAFoPB7oLFPxFBN7FCID41TEodDdZtcNnKJT4uQ/iWRqww2BOwVQM9whyBTg8J4kJZALicR4CzGCuUbdyQd2kh/hNZ9d9SKb6YXdcZElFmh3FY6zgfgv5PAx+jDlkfzmgBh7OD5OM4GVrsCsjnaAlmTUNtRPx9B4ps0gbr25F1PxuNy+MXfwSYJdliL+N01BTpiGyts/EXAraWvEm5YkhWfTnbgc8osd3cX9vwB0QHksK+BpkaEs6XCwU6kGMxAJIlafRv6RslREdTPBpYaXB4sGqdYXWY+YFqNxsAwTB3KWIq/uhZmSkou1jZfZa2QonMuVot68U11U7afmPzX8KOVeO2IEcUjt6I4eCYQ+31xO/wSLIQ1uoRySQ2S9VCzr+yzDpu0KVps= addons: sauce_connect: true
你確定會詫異 global
下面的那兩串長?是什麼東西。它們其實就是在 nightwatch.conf.js 中用到的 process.env.SAUCE_USERNAME
和 process.env.SAUCE_ACCESS_KEY
。
那它們是怎麼來的哪?
首先,安裝 travis 工具 gem install travis
;
而後,使用 github 帳戶登陸 travis login
;
登陸後,就能夠分別使用 travis encrypt SAUCE_USERNAME=saucelabs用戶名 --add
和 travis encrypt SAUCE_ACCESS_KEY=saucelabs的access_key --add
將 username 和 access_key 加密,--add
參數會自動將結果追加到 .travis.yml 文件中。因此,已徹底不用擔憂字符貼錯或貼漏。
這樣整個跨瀏覽器測試就同 CI 集成好了,配置信息比較多,有興趣的能夠結合項目一塊兒看。(點這裏)
最後,不要忘(tian)了(jia)初(hui)衷(zhang)。這能夠在 saucelabs 的 Dashboard -> Automated Builds 下看到。
總的來講,nigthwatch + saucelabs + travis 來作跨瀏覽器自動測試仍是比較方便的,只是一開始不熟悉,相應的資料也比較少,saucelabs 的文檔也不夠友好,耗費了些時間。覆蓋率測試時, JEST 佔的那點小便宜全都還回來了。
看到這裏,你是否是覺得 CI 只是幫你跑跑測試、顯示覆蓋率?那你就錯了。
CI 並非單單隻能幫你跑測試,它還能夠將構建成功的代碼發佈到服務器上。試想一下,當你將代碼合併到主分支以後,CI 不但幫你運行測試,還將測試經過以後的代碼發佈到了你的服務器上,而不須要你人工進行額外的操做。這是否是很 cool!
這裏就舉一個經過 Travis-ci 將代碼發佈到 github.io 上的例子。
再修改一下上面 .travis.yml 文件。
language: node_js node_js: - '6' cache: directories: node_modules before_script: - npm run build - node server.js & script: - npm run test:coverage - npm run codecov - npm run test:e2e after_success: - bash ./deploy.sh os: - linux - osx env: global: - USER_NAME: Disciple_D - USER_EMAIL: disciple.ding@gmail.com - GIT_DEPLOY_KEY: XXXXXXXX - secure: v6CRj4CKMqxEQ9MSYKAkbmrBgIBZvoppICx6JyjQXhexPOVQKBvboCgdL0lOOZdGZ9rEqSMXvud97kBAFYd1sdP/kSwXdUct5BOMIT3a5GLtY5aQfOocBwR6IvmZpO2U+4VhrCwkzdaq2Ehq0fAXF1pkxDj9YkJZmwDNhTdfDGkib+AwDyr4TLQFC1QrD/4vmrULb3NZdW1KadFYjLzVF8FMa2tDSYMFFVymYu5nuCa/Z0dqSfFy8McYwBMzThDkDRHMT/sf4zKDPyxUwN7xGfC6T88xzCEaltN6K7MGMGKvl7Y0p7VjYW/+rO38936kj6xuPU6J7Vh2yKPJhhT2LtM7ucuo0XSpIxCxaKXWeEmYl2KkCMWNHgrWACE//WBFRNx/JQHimw+abr1Zt/3V9QmSEvnB3hHB0NQgJ2nVrVDjk51RSVaiP4sfQ8GVqEwr1+wJqe4wz7fV+jvRB9uUGgGsjsBbZi6ZycoMtOBoJ+miviRCjZvf9sOZKfIDjcuE5vETQcE37d/++yplCG0N83Kx+q67mbWXirfNj2CfXp7pwHTN+n21v1BSicXqQ6+jaNzD/pcN/GTHgZ5A+VkdcjSmEziuQTO035i1nnCB9TQdFeRdGdfo6DAiq8YOfyVkQ1lml6lWqbPqa4QWokRUD2yA/hAIzNWe5BeLF2JFQBc= - secure: S0vWVM74eiAHhk+kqqvym9aIgqaaGyGz9H3rfmEZoG4iuvXjXRaHOOSHxIRVsh5RYXr0PWHAj24fpN5AyUOlu5NQiwACBqmpw9KZBgVekWFshA5uYmpNpCG9w5/UAQa9q2+EcndOCM4lAyuT2wVJ5WfsHRzIA5jUpK1YmUYtuVICTSkumRoEaxfPkwzcGLF7f6aP7mG1YRKeO1F9+RhBfaGN1kYordxIk/fniH8OFB0XiLZ5OIovaAIYFKic0P1wUFwa78jU2fovdObS8JySl2LP19eaLX0MgAFoPB7oLFPxFBN7FCID41TEodDdZtcNnKJT4uQ/iWRqww2BOwVQM9whyBTg8J4kJZALicR4CzGCuUbdyQd2kh/hNZ9d9SKb6YXdcZElFmh3FY6zgfgv5PAx+jDlkfzmgBh7OD5OM4GVrsCsjnaAlmTUNtRPx9B4ps0gbr25F1PxuNy+MXfwSYJdliL+N01BTpiGyts/EXAraWvEm5YkhWfTnbgc8osd3cX9vwB0QHksK+BpkaEs6XCwU6kGMxAJIlafRv6RslREdTPBpYaXB4sGqdYXWY+YFqNxsAwTB3KWIq/uhZmSkou1jZfZa2QonMuVot68U11U7afmPzX8KOVeO2IEcUjt6I4eCYQ+31xO/wSLIQ1uoRySQ2S9VCzr+yzDpu0KVps= addons: sauce_connect: true
能夠看到,我又給它添加了一個 after_success 的配置,只有當以前的測試運行成功以後,才運行以後的命令。固然你也能夠選用其餘的配置,好比:deploy
。
要將代碼發佈到 github.io 上,就勢必要 push 代碼至倉庫的 gh-pages 分支。然而,若是要經過 travis-ci 向 github 提交代碼,那麼,就要首先創建 ssh 連接。由於,這裏是發佈特定的倉庫代碼,因此,我推薦你們經過給 repository 設置 deploy key 的方式來給 travis-ci 受權,而不是 access token。
那麼,如何設置 deploy key?
本地新建一個 ssh key(不清楚的點這裏)
進入 github 你要發佈的倉庫中,選擇 settings -> Deploy keys -> Add deploy key,並將你剛剛生成的 key.pub 文件中的內容複製到輸入框中,記得勾選 Allow write access,再點擊 Add key。這樣就設置好了 deploy key,但確定不能將 key 直接放到 github 上,須要先加密。
使用 travis 工具加密 deploy key travis encrypt-file key
,這會生成一個 key.enc 文件,將這個文件加入到代碼倉庫中就行,不要向代碼庫提交生成的 key 和 key.pub 文件
加密完成後,控制檯會輸出一串日誌,其中有相似這樣的一條 openssl aes-256-cbc -K $encrypted_c7881d9cb8b5_key -iv $encrypted_c7881d9cb8b5_iv -in key.enc -out key -d
,這就是用來創建 ssh 連接的。將其中 $encrypted_..._key
之間的字符提取出來,做爲系統運行變量,也就是以前 .travis.yml 中的 GIT_DEPLOY_KEY: XXXXXXXX
,這樣發佈腳步中就能使用這個變量
OK。這樣 deploy key 就準備好了,下面是發佈腳本。
#!/bin/bash set -e # Exit with nonzero exit code if anything fails # Git variables TARGET_PATH="build/" TARGET_BRANCH="gh-pages" # Travis encrypt variables ENCRYPTED_KEY="encrypted_${GIT_DEPLOY_KEY}_key" ENCRYPTED_IV="encrypted_${GIT_DEPLOY_KEY}_iv" # Save some useful information REPO=`git config remote.origin.url` SSH_REPO=${REPO/https:\/\/github.com\//git@github.com:} SHA=`git rev-parse --verify HEAD` # Build source npm run build # Set committer git info git config user.name $USER_NAME git config user.email $USER_EMAIL # Force add build folder to git git add -f $TARGET_PATH # Commit the build code, that is a local commit for git subtree split git commit -m "Deploy to GitHub Pages: ${SHA}" # Split build file as a $TARGET_BRANCH of git git subtree split -P $TARGET_PATH -b $TARGET_BRANCH # Add ssh authorization openssl aes-256-cbc -K ${!ENCRYPTED_KEY} -iv ${!ENCRYPTED_IV} -in deploy_key.enc -out deploy_key -d # Change the deploy_key mod to fix ssh permissions too open error chmod 600 deploy_key eval `ssh-agent -s` ssh-add deploy_key # Push code to git git push -f $SSH_REPO $TARGET_BRANCH
這個腳本只需簡單的變量改動就能適應你的項目,固然,你也能夠爲本身的項目編寫本身的發佈腳本。
以上說的都是源代碼放在 Github 上的開源代碼,但我相信你們接觸得更多的應該是本身公司的私有代碼,好比和 Jira 相關的 Stash。
首先,Stash 現已更名爲以前提到過的 Bitbucket,那麼,只要將 travis-ci 替換成 circleci 就能夠了,其他兩個插件都是支持 Bitbucket 的。
其次,若是項目倉庫,既不是 Github, 也不是 Bitbucket 或 Gitlab,不要着急,這時候就須要祭出萬金油 Jenkins 了。
Jenkins 那成千上萬的 Plugin,相信總有一款適合你。好比,老版的 stash 就能夠參照這篇文章來配置。
最後,回顧一下整個 CI 流程。
當代碼被提交到 github 分支上時,travis-ci 會被觸發開始整套的測試及發佈。
首先,安裝項目依賴;
而後,運行測試,其中包括 UT 和 e2e test;
測試無誤後,自動將打包後的代碼發佈到 gh-pages 分支;
因而,就能夠經過 https://用戶名.github.io/項目名 訪問項目了。
完成~
來看當作(hui)果(zhang)吧。查看源碼點這裏。
全部的徽章信息均可以在 shields.io 中查看,甚至能夠自定義徽章,就像這樣 。哈哈哈~
少年們,想要集徽章麼?快把測試補起來吧~
參考文章: