(四) 使用Travis CI集成單元測試

前言

git pre-push hook 實踐一二 一文中,咱們實踐瞭如何使用pre-hook執行單元測試以影響push操做的結果。但這種方式也有很多缺點,如沒法hook pr,沒法在提交版本里記錄和共享顯示測試的結果。Travis CI做爲github官方支持的service,免費爲開源項目提供了一個優秀的持續集成環境。關於Travis CI的簡介和使用,能夠參考這篇 EyreFree: 利用 Travis CI 讓你在 GitHub 上的 Xcode 項目持續構建。下面,咱們將簡介如何集成iOS的單元測試和測試的代碼覆蓋率工具。html

單元測試

咱們已經知道,在工程目錄下執行xcodebuild test命令,能夠啓動xcode 的單元測試,在持續集成環境下依然如此。在根目錄的.travis.yml文件中配置相關操做。git

.travis.yml
osx_image: xcode9
language: objective-c

cache: cocoapods
podfile: Example/Podfile

env:
  global:
    - LANG=en_US.UTF-8
    - LC_ALL=en_US.UTF-8
    - WORKSPACE_NAME=`sudo find ./Example -name "*.xcworkspace" -maxdepth 1 |while read var; do echo $(basename $var .xcworkspace); done`
    # the file named '*.xcworkspace' should be created by 'pod lib create...'

before_install:
  - gem install xcpretty --no-rdoc --no-ri --no-document --quiet
  - gem install cocoapods --pre --no-rdoc --no-ri --no-document --quiet
  #- gem install slather --pre --no-rdoc --no-ri --no-document --quiet
  - pod install --project-directory=Example
  - rvm use $RVM_RUBY_VERSION

script:
  - set -o pipefail
  - echo $WORKSPACE_NAME
  #- xcodebuild -workspace "$XCODE_WORKSPACE" -scheme "$SCHEME" -configuration Debug clean build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO | xcpretty -c
  #- xcodebuild -workspace "$XCODE_WORKSPACE" -scheme "$SCHEME" -configuration Release clean build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO | xcpretty -c
  - xcodebuild test -enableCodeCoverage YES -workspace Example/$WORKSPACE_NAME.xcworkspace -scheme $WORKSPACE_NAME-Example -destination 'platform=iOS Simulator,OS=latest,name=iPhone 8'  -destination 'platform=iOS Simulator,OS=10.3.1,name=iPhone 7' -destination 'platform=iOS Simulator,OS=9.3,name=iPhone 6s'
  - pod lib lint --allow-warnings --verbose

after_success:
  - slather
  - bash <(curl -s https://codecov.io/bash) #-f Example/cobertura.xml -X coveragepy -X gcov -X xcode -t
  - sleep 3

複製代碼
xcodebuild test
- xcodebuild test -enableCodeCoverage YES -workspace Example/$WORKSPACE_NAME.xcworkspace -scheme $WORKSPACE_NAME-Example 
 -destination 'platform=iOS Simulator,OS=latest,name=iPhone 8'  
 -destination 'platform=iOS Simulator,OS=10.3.1,name=iPhone 7' 
 -destination 'platform=iOS Simulator,OS=9.3,name=iPhone 6s'
複製代碼

以上代碼會在三個不一樣的destination上進行單元測試併產生代碼覆蓋率記錄,iOS11可選擇最新的系統版本,較舊版本能夠在環境提供的列表中選擇。對於cocoapods建立的包含demo的庫,可使用sudo find ./Example -name "*.xcworkspace" -maxdepth 1 |while read var; do echo $(basename $var .xcworkspace); done 自動肯定workspace的文件名及補全scheme,這對統一快捷配置CI的yml文件是有益的,固然,咱們也能夠本身手動配置與工程名及路徑相關的參數。github

測試結果日誌

pr操做頁-check結果爲成功

pr操做頁-check結果爲失敗

test failed時,總體會exit with 0,check爲失敗。此外, pod lib lint操做等也會影響check結果。這對審閱者合併pr有必定的參考意義。

測試的代碼覆蓋率

運行編寫的測試用例時,可能存在如下狀況: 某個方法的if/switch分支沒有執行到,甚至某個類的整個方法未被調用。這就造成了 所謂的測試覆蓋率問題,可靠有效的測試結果應該創建在足夠高代碼覆蓋率的測試用例上。下面介紹三種查看測試覆蓋率的方式。objective-c

1. xcode

當test設置勾上code coveragexcodebuild test -enableCodeCoverage YES時,將產生覆蓋率記錄文件。xcode

勾選代碼覆蓋

如上圖,咱們能夠查看到全部文件的代碼覆蓋率。點擊類名,能夠查看到標紅即未被覆蓋到的代碼。bash

固然,咱們通常須要的是庫中類文件的代碼覆蓋率。

2. Slather

Generate test coverage reports for Xcode projects & hook it into CI.
slather是一個專業用於xcode生成測試代碼覆蓋率報告的工具。安裝可參見github。當咱們運行單元測試後,可在根目錄執行:curl

slather coverage  --scheme LPDCNetwork-Example 
--workspace Example/LPDCNetwork.xcworkspace Example/LPDCNetwork.xcodeproj
複製代碼

結果爲:工具

也能夠執行:

$ slather coverage --html --show  
--scheme LPDCNetwork-Example --workspace ./LPDCNetwork.xcworkspace ./LPDCNetwork.xcodeproj
複製代碼

自動生成並打開html形式的覆蓋率報告。 post

另外,能夠調整工程目錄結構和修改 .slather.yml文件配置,執行 slather在自定義目錄下生成覆蓋率的xml文件,可用於上傳到一些覆蓋率服務生成報告集成pr界面。可用 --ignore命令或yml文件ignre下配置忽略不計入平均覆蓋率的文件路徑。

.slather.yml
coverage_service: cobertura_xml
workspace: Example/PopoverObjC.xcworkspace
xcodeproj: Example/PopoverObjC.xcodeproj
scheme: PopoverObjC-Example
source_directory: Example/
output_directory: Example/
ignore:
複製代碼

3. codecov

codecov對github有着良好的支持,當咱們在CI中執行完單元測試後,可執行以下代碼自動上傳xcode代碼覆蓋率文件,或者上傳前文slather相關命令生成的xml文件。單元測試

bash <(curl -s https://codecov.io/bash) #-f Example/cobertura.xml -X coveragepy -X gcov -X xcode -t
複製代碼

日誌:

3.93s$ bash <(curl -s https://codecov.io/bash)
==> Travis CI detected.

    project root: .

    Yaml not found, that is ok! Learn more at http://docs.codecov.io/docs/codecov-yaml

==> Processing Xcode plists

    Found plist file at /Users/travis/Library/Developer/Xcode/DerivedData/PopoverObjC-byqecvztvcxucabbetxyjvpkugpa/Logs/Test/E6D08998-FE45-47F6-B63C-1A81F39A7CF5.xccoverage

==> Running gcov in . (disable via -X gcov)

==> Python coveragepy not found

==> Searching for coverage reports in:

    + .

    -> Found 4 reports

==> Detecting git/mercurial file structure

==> Appending build variables

    + TRAVIS_OS_NAME

    + TRAVIS_RUBY_VERSION

==> Reading reports

    + ./344206B7-9176-4963-8C93-EE67C319FEE8.xccoverage.plist bytes=13127261

    + ./DD06A5DE-7636-4E63-BC90-A70235D4E1D2.xccoverage.plist bytes=222002

    + ./E6D08998-FE45-47F6-B63C-1A81F39A7CF5.xccoverage.plist bytes=221932

    + ./Example/cobertura.xml bytes=6036

==> Appending adjustments

    http://docs.codecov.io/docs/fixing-reports

    + Found adjustments

==> Gzipping contents

==> Uploading reports

    url: https://codecov.io

    query: branch=testCI&commit=98933100ae86b02345de549f28783167d6ce3ebc&build=99.1&build_url=&name=&tag=&slug=Assuner-Lee%2FPopoverObjC&service=travis&flags=&pr=false&job=318459810

    -> Pinging Codecov

    -> Uploading

    -> View reports at https://codecov.io/github/Assuner-Lee/PopoverObjC/commit/98933100ae86b02345de549f28783167d6ce3ebc
複製代碼

覆蓋率報告:

覆蓋率報告的信息仍是很豐富的,能夠獲得每一個commit的覆蓋率數值,各個分支間的對比,相比於基準值的對比等。此外,咱們一樣能夠在 codecov.yml文件中設置要忽略的文件路徑,以獲得更準確的平均覆蓋率。
一樣,在pr頁面能夠看到codecov的覆蓋率概覽報告。

經過CI集成單元測試及代碼覆蓋率、lint等結果信息到pull,pr頁面,這對於代碼審閱,控制代碼質量有着必定的積極做用。

謝謝觀看,水平有限,若有錯誤,請多指教。

參考資料:

juejin.im/post/5a3215…
github.com/SlatherOrg/…

系列文章

(一) 初探 iOS 單元測試
(二) kiwi 實踐一二
(三) git pre-push hook 實踐一二

相關文章
相關標籤/搜索