溫故OpenStack中的測試(by Joshua)
版權宣告:可以任意轉載,轉載時請務必以超連結形式標明文章原始出處和作者資訊及本版權宣告 (作者:張華 發表於:2018-03-15)
- 沿用tox呼叫virtualenv自動建立的虛擬環境(virtualenv -p python3.5 .tox/py35)
source .tox/py35/bin/activate
sudo pip install --upgrade -r requirements.txt
sudo pip install --upgrade -r test-requirements.txt
- 使用unittest和nose執行測試。nose是對unittest的擴充套件,使得python的測試更加簡單,nose自動發現測試程式碼並執行,nose提供了大量的外掛,比如覆蓋報表等。
python -m unittest -v unit_tests.test_neutron_utils.TestNeutronUtils.test_get_packages_ovs_newton
.tox/py35/bin/python nosetests -v unit_tests/test_neutron_utils.py:TestNeutronUtils.test_get_packages_ovs_newton
注意:上面採用nosetests執行時會報錯,因為我們的測試採用了python3, 所以需要在安裝了python3-nose之後(sudo apt-get install python3-nose python3-mock)再採用下列三種方式之一執行:
nosetests3 -v unit_tests/test_neutron_utils.py:TestNeutronUtils.test_restart_map_ovs_odl /bak/work/charms/neutron-gateway/.tox/py35/bin/python /usr/local/bin/nosetests -v unit_tests/test_neutron_utils.py:TestNeutronUtils.test_get_packages_ovs_newton python -m nose unit_tests/test_neutron_utils.py:TestNeutronUtils.test_restart_map_ovs_odl
但實際上仍然找不找nose模組,那是因為nose與virtualenv結合地不大好,在這個網頁找著了答案(https://stackoverflow.com/questions/864956/problems-using-nose-in-a-virtualenv) - You need to have a copy of nose installed in the virtual environment. In order to force installation of nose into the virtualenv, even though it is already installed in the global site-packages, run pip install with the -I flag: pip install nose -I
- 上面使用unittest與nose執行測試的方式只是將結果輸出到stdout,不便於分析。所以可以使用python-subunit模組來執行測試,並將測試結果通過subunit協議輸出到檔案中便於日後分析。因為subunit是基於二進位制的不便於人眼看,所以可使用subunit2pyunit工具將其人類可讀化。
python -m subunit.run discover |subunit2pyunit
python -m subunit.run discover -t ./ ./unit_tests |subunit2pyunit
python -m subunit.run unit_tests.test_neutron_utils.TestNeutronUtils. |subunit2pyunit
- 在大型應用中分析測試結果很重要,testrepository可以呼叫subunit來用python-subunit模組來執行測試,並將測試結果通過subunit協議輸出到檔案中,然後testrepository在些基礎上有更多的分析,如分析哪些用例執行的時間最長,如顯示失敗的用例,如僅執行上次執行失敗的用例。
testr init
testr run
testr run --parallel
$ cat .testr.conf
[DEFAULT]
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
${PYTHON:-python} -m subunit.run discover -t ./ ./unit_tests $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list
- tox用於建立虛擬python環境,也可以整合上面的testrepository(commands = ostestr {posargs})
$ cat tox.ini
[tox]
envlist = pep8,py27,py35
skipsdist = True
[testenv]
setenv = VIRTUAL_ENV={envdir}
PYTHONHASHSEED=0
CHARM_DIR={envdir}
AMULET_SETUP_TIMEOUT=5400
install_command =
pip install --allow-unverified python-apt {opts} {packages}
commands = ostestr {posargs}
whitelist_externals = juju
passenv = HOME TERM AMULET_* CS_API_*
[testenv:py27]
basepython = python2.7
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands = /bin/true
[testenv:py35]
basepython = python3.5
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
[testenv:pep8]
basepython = python2.7
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands = flake8 {posargs} hooks unit_tests tests actions lib
charm-proof
[flake8]
ignore = E402,E226
exclude = */helpers
-
pydev使用virtualenv中的py35
在eclipse的"Preferences -> Pydev -> Interpreters -> Python Interpreters"選單中定義python35=/bak/work/charms/neutron-gateway/.tox/py35/bin/python,然後在工程上點右鍵從"Properties -> Pydev - Interpreter/Grammar"定義使用python35。注意,需要將/bak/work/charms/neutron-gateway/.tox/py35/lib/python3.5/site-packages也選到環境變數中,否則後面會報ImportError: No module named 'mock。
為一個測試類定義"Python unitest"型別的"Debug Configurations", 也在其Interpreter選項卡中定義使用python35 (結果:eclipse似乎有bug,此處選擇了python35後無法儲存)
所以無法成功,似乎是pydev與python3協作不大好。最後還是pudb好使(sudo pip install pudb, import pudb; pdb.set_trace()) -
py27下的測試執行方法(如openstack), charm似乎只能用py35
cat tox.ini
tox -r -epy27
tox -e py27,pep8
tox -e py27 neutron.tests.unit.agent.linux.test_keepalived
tox -e py27 neutron.tests.unit.agent.linux.test_keepalived.KeepalivedInstanceTestCase.test_remove_addresses_by_interface
mkdir /opt/stack && sudo chown -R hua /opt/stack
tox -e functional neutron.tests.functional.agent.l3.test_ha_router.L3HATestCase.test_keepalived_configuration
tox -e dsvm-fullstack
source .tox/functional/bin/activate
.tox/functional/bin/pip install -r requirements.txt
.tox/functional/bin/pip install -r test-requirements.txt
.tox/functional/bin/pip install -r neutron/tests/functional/requirements.txt
.tox/functional/bin/pip freeze |grep neutron
.tox/functional/bin/pip install 'neutron-lib==1.13.0'
OS_SUDO_TESTING=True .tox/functional/bin/python -m unittest -v neutron.tests.functional.agent.l3.test_ha_router.L3HATestCase.test_keepalived_configuration
有時如mitaka已經eol了, 例如它的origain-stable-mitaka這個分支都沒有了, 這會導致執行’tox -r -epy27 '不成功, 那麼可以手工執行:
virtualenv venv
. venv/bin/activate
# pg_config executable not found
# Error: could not determine PostgreSQL version from '10.5'
sudo apt install python-setuptools python-dev libpython-dev libssl-dev python-pip libmysqlclient-dev libxml2-dev libxslt-dev libxslt1-dev libpq-dev git git-review libffi-dev gettext graphviz libjpeg-dev zlib1g-dev build-essential python-nose python-mock libssl1.0
sudo apt install python3.6 python3.6-dev python3-pip python3-dev python3-nose python3-mock
#sudo pip install --upgrade setuptools
#sudo pip3 install --upgrade setuptools
#sudo pip install --upgrade --force-reinstall pip virtualenv
# Failed to install Cryptography - sudo apt install libssl1.0
# No module named dulwich - ./venv/bin/pip install dulwich
# unittest has no attribute 'virt' -
./venv/bin/pip install -c https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=mitaka-eol .
./venv/bin/pip install -r requirements.txt
./venv/bin/pip install -r test-requirements.txt
find . -name "*.pyc" -exec rm -rf {} \;
git clone https://github.com/openstack/oslo.cache.git
cd oslo.cache && git checkout -b mitaka mitaka-eol
../nova/venv/bin/pip install -r requirements.txt
../nova/venv/bin/pip install -r test-requirements.txt
# dogpile can't cannot import name threading - venv/bin/pip uninstall dogpile.cache dogpile && venv/bin/pip install dogpile.cache
venv/bin/python -m subunit.run discover ./nova/tests/unit/compute |subunit2pyunit
venv/bin/python -m subunit.run nova.tests.unit.compute.test_compute |subunit2pyunit
venv/bin/python -m subunit.run nova.tests.unit.compute.test_compute.ComputeAPITestCase.test_attach_volume |subunit2pyunit
venv/bin/python -m unittest -v nova.tests.unit.compute.test_compute #make sure the package nova.tests.virt exists
#venv/bin/pep8
venv/bin/flake8