2016-04-13 56 views
2

下面是一個link項目和輸出,您可以使用它來重現我在下面描述的問題。多個python版本的tox覆蓋率

我正在使用覆蓋範圍tox針對多個版本的python。我tox.ini文件看起來是這樣的:

[tox] 
envlist = 
    py27 
    py34 

[testenv] 
deps = 
    coverage 

commands = 
    coverage run --source=modules/ -m pytest 
    coverage report -m 

我的問題是覆蓋範圍將運行僅使用一個版本的Python(在我的情況,py27),但不能同時py27和PY34。這是一個問題,每當我有代碼的執行依賴於Python版本,例如:

def add(a, b): 
    import sys 
    if sys.version.startswith('2.7'): 
     print('2.7') 
    if sys.version.startswith('3'): 
     print('3') 
    return a + b 

運行覆蓋對上面的代碼會錯誤地報告線6(「打印(‘3’)」)的「失蹤」 py27和py34。它應該只是py34的缺失。

我知道這是爲什麼發生:覆蓋範圍安裝在我的基本操作系統(它使用python2.7)。因此,運行tox時,它注意到覆蓋範圍已經安裝並繼承了基本操作系統的覆蓋範圍,而不是將其安裝在它創建的virtualenv中。

這對於py27來說很好,並且很好看,但是會在py34的覆蓋率報告中導致不正確的結果。我有一個冒險的臨時解決方法:我需要稍微早一點的覆蓋範圍(相對於我的基本操作系統上安裝的版本),以便tox將被迫在virtualenv中安裝單獨的覆蓋副本。例如。

[testenv] 
deps = 
    coverage==4.0.2 
    pytest==2.9.0 
    py==1.4.30 

我不喜歡這個解決方法,但這是我現在發現的最好的。任何建議強制tox將其當前版本的覆蓋率安裝到其virtualenv中,即使我已經在我的基本操作系統上安裝了它。

+0

我不能重現此:覆蓋範圍是告訴我它丟失了py27 ENV線8條,第6行的py35 ENV。我安裝了一個全局的'coverage'命令(一個Python 3.5腳本)。唯一的區別是我添加了'pytest'作爲額外的依賴項,否則我得到一個'InvocationError'(我沒有安裝全局的'pytest'命令)。 – Evert

+0

謝謝你的嘗試。我已經上傳了**應該能夠重現此問題的代碼以及運行tox(和其他工具)的輸出以幫助進行調試。此內容位於[此處](https://drive.google.com/open?id=0B0bHr4crS9cpaWlockpxcmJxelE)。我在OS X 10.11.4上運行這個。只需在「test_project」目錄中運行「tox」,並且(手指交叉),您應該看到與我的結果類似的結果。 – user3188632

+0

奇怪的是,Tox virtualenv默認不應該繼承網站包。檢查Tox ['sitepackages'](http://crospeak.net/tox/config.html#confval-sitepackages=True|False)選項,也許它設置在某個地方。或者,也許你有一些非常古老的virtualenv(IIRC古代版本需要顯式地指定「--no-site-packages」)? – drdaeman

回答

0

我不明白爲什麼tox不會在每個virtualenv正確安裝覆蓋。你應該得到兩個不同的報道報道,一個是py27,一個是py35。更好的選擇可能是製作一份合併報告。使用coverage run -p記錄每次運行的單獨數據,然後在報告前合併它們。

+0

我的理解是,tox檢查要求(-dev).txt文件與主機上已安裝的內容。如果主機上已經安裝了模塊,則不會將其安裝到virtualenv中,因爲這會佔用更多的磁盤空間。查看我發佈的[link](https://drive.google.com/folderview?id=0B0bHr4crS9cpSDd3YjI0Qk8tdjQ&usp=drive_web&tid=0B0bHr4crS9cpaWlockpxcmJxelE)中的tox日誌文件(py27-1.log)。 (繼續下面...) – user3188632

+0

(續)你會看到它聲明「Requirement already satisfied(use --upgrade to upgrade):coverage in /Library/Python/2.7/site-packages」,這基本上意味着tox表示「我看到你已經在你的主機上安裝了覆蓋範圍,所以我不會將它安裝在virtualenv中;我只是使用主機的覆蓋範圍代替「。如果我將需求更改爲覆蓋率== 4.0.2,則日誌文件中的此行會發生更改。然後tox說:「嗯,你已經在主機上安裝了覆蓋v4.0.3,並且不能滿足安裝v4.0.2,所以我會在virtualenv中安裝一個安裝覆蓋率v4.0.2。」 – user3188632

0

今天我遇到了這個問題,但找不到一個簡單的答案。所以,爲了將來的參考,這裏是我提出的解決方案。

  1. 創建包含Python中的每個版本將要測試和cov定製ENV的envlist
  2. 對於所有版本的Python,設置COVERAGE_FILE環境變量以將.coverage文件存儲在{envdir}中。
  3. 對於cov env我使用兩個命令。
    1. coverage combine,結合了報告,並
    2. coverage html生成報告,如有必要,測試失敗。
  4. 創建一個.coveragerc文件,其中包含一個[paths]部分以列出source=位置。
    1. 第一行是找到實際源代碼的地方。
    2. 後續行是將通過「coverage coverage」消除的子路徑。

tox.ini:

[tox] 
envlist=py27,py36,py35,py34,py33,cov 

[testenv] 
deps= 
    pytest 
    pytest-cov 
    pytest-xdist 
setenv= 
    py{27,36,35,34,33}: COVERAGE_FILE={envdir}/.coverage 
commands= 
    py{27,36,35,34,33}: python -m pytest --cov=my_project --cov-report=term-missing --no-cov-on-fail 
    cov: /usr/bin/env bash -c '{envpython} -m coverage combine {toxworkdir}/py*/.coverage' 
    cov: coverage html --fail-under=85 

.coveragerc:

[paths] 
source= 
    src/ 
    .tox/py*/lib/python*/site-packages/ 

該結構的最特有的部分是coverage combine調用。下面是命令的崩潰:

  • tox不處理shell擴展{toxworkdir}/py*/.coverage,所以我們需要調用一個shell(bash -c),以獲得必要的拓展。
    • 如果一個人傾斜,你可以只輸入了所有的路徑,單獨,而不是通過所有這些箍跳,但會增加維護和.coverage文件相關的每個pyNN ENV。
  • /usr/bin/env bash -c '...'確保我們獲得bash的正確版本。使用env的完整路徑可以避免設置whitelist_externals
  • '{envpython} -m coverage ...'確保我們爲cov env調用正確的pythoncoverage
  • NOTE:此解決方案的不幸問題是cov env是依賴於調用py{27,36,35,34,33},它有一些不那麼理想的副作用。
    • 我的建議是隻調用covtox
    • 決不調用tox -ecov因爲,無論是
      • 它可能會失敗,原因是缺少.coverage文件,或
      • 它可以給奇怪的結果(結合不同的測試)。
    • 如果您必須調用它作爲一個子集(tox -epy27,py36,cov),然後全殲.tox目錄第一(rm -rf .tox),以避免丟失.coverage文件的問題。