Не корысти
ради а токмо волею пославшей мя жены! ©
Ильф и Петров.
В продолжение
темы «Заготовка
Zope Product» и, если точнее, в продолжение
подтемы «Тестирование/отладка
Zope Product». Некоторые детали нынешнего
поста раскрываются в подробностях там,
раньше.
Тенденция,
однако. Я по наивности своей полагал,
что заворачивать Zope Product
в яйцо (egg)
придется еще не скоро. Ошибся. Нынче
настали такие времена, когда яйцепоклонники
победили со всей очевидностью. Во всяком
случае в теме Zope/Plone.
Такой факт
— начиная с Zope 2.12.8 пропала возможность
запускать
zopectl test
Теперь, чтобы автоматизировать
тестирование своего продукта, надо
заворачивать продукт в яйцо и добавлять
zc.recipe.testrunner в билдаут. Иначе, разумеется,
можно. Но не нужно.
Что поделать,
яйцо, так яйцо, тестировать-то надо. В
конце концов, делов-то: раз — сделать
яйцо, два — поправить билдаут для
включения этого яйца. Понеслась. Брюки
продукты превращаются
... в egg.
Сперва добудем
инструменты — paster & zopeskel.
Чтобы сделать
яйцо, нужен paster. Рекомендуют
получить его через билдаут, хотя можно
и через virtualenv организовать.
Добавил в
C:\d\Zope\zope213\buildout.cfg
строки про
zopeskel & paster, получилось
так
[buildout]
parts =
zopeskel
paster
instance
extends = http://download.zope.org/Zope2/index/2.13.13/versions.cfg
[zopeskel]
recipe = zc.recipe.egg
eggs =
ZopeSkel<2.99
[paster]
recipe = zc.recipe.egg
eggs =
PasteScript
ZopeSkel<2.99
[instance]
recipe = zc.recipe.egg
eggs =
Zope2
Products.ZSQLMethods
interpreter = zopepy
scripts = runzope zopectl
initialization =
import sys
sys.argv[1:1] = ['-C', r'${buildout:directory}\etc\zope.conf']
|
и запустил
перестройку
C:\d\Zope>call setenv.cmd C:\d\Zope>cd zope213 C:\d\Zope\zope213>bin\buildout.exe |
как и обещали
(collective-docs.readthedocs.org/en/latest/tutorials/paste),
появились команды
c:\d\Zope\zope213\bin\paster.exe c:\d\Zope\zope213\bin\zopeskel.exe
Дополнительно
стОит заметить, что в доках рекомендуют
конфиг писать немного иначе. К примеру,
секция zopeskel изначально выглядела так
...
[zopeskel]
recipe = zc.recipe.egg
eggs =
ZopeSkel<2.99
zopeskel.dexterity
${instance:eggs}
...
|
Декстерити я
убрал, потому как он мне не нужен. А вот
с подключением яиц инстанса
(${instance:eggs}) уже интереснее. Если сделать
как рекомендуют, перестают работать
скрипты запуска Zope. Отваливаются с
сообщением
C:\d\Zope\zope213>bin\runzope.exe
Traceback (most recent call last):
File "C:\d\Zope\zope213\bin\runzope-script.py", line 92, in <module>
Zope2.Startup.run.run()
File "c:\d\zope\zope213\eggs\zope2-2.13.13-py2.7.egg\Zope2\Startup\run.py", line 19, in run
opts = _setconfig()
File "c:\d\zope\zope213\eggs\zope2-2.13.13-py2.7.egg\Zope2\Startup\run.py", line 50, in _setconfig
handlers.handleConfig(opts.configroot, opts.confighandlers)
File "c:\d\zope\zope213\eggs\zope2-2.13.13-py2.7.egg\Zope2\Startup\handlers.py", line 193, in handleConfig
return multihandler(handlers)
TypeError: 'NoneType' object is not callable
|
Как я выяснил,
это из-за того, что в скриптах запуска
пропадают строки
import sys sys.argv[1:1] = ['-C', r'C:\d\Zope\zope213\etc\zope.conf']
Так что рекомендуемый конфиг я подправил,
убрав подключение инстансовых яиц.
ОК, paster и
zopeskel у меня есть. Создаю яйцо
(weblion.psu.edu/trac/weblion/wiki/EggifyAnExistingProduct).
Попробую так:
C:\d\Zope\zope213>bin\zopeskel.exe basic_zope Products.vcufile
Говорят, что на вопросы надо отвечать
так, чтобы получилось
namespace_package: Products
package: vcufile
zip_safe: False
Но мне таких вопросов не задавали, сессия
выглядела вот как
basic_zope: A Zope project This creates a Zope project without any specific Plone features. If at any point, you need additional help for a question, you can enter '?' and press RETURN. Expert Mode? (What question mode would you like? (easy/expert/all)?) ['easy']: Version (Version number for project) ['1.0']: 3.0.0 Description (One-line description of the project) ['']: Zope2 Product for huge files chunked upload Creating directory .\Products.vcufile c:\d\zope\zope213\eggs\cheetah-2.2.1-py2.7.egg\Cheetah\Compiler.py:1523: UserWarning: You don't have the C version of NameMapper installed! I'm disabling Cheetah's useStackFrames option as it is painfully slow with the Python version of NameMapper. You should get a copy of Cheetah with the compiled C version of NameMapper. "\nYou don't have the C version of NameMapper installed! " Replace 0 bytes with 2 bytes (0/0 lines changed; 1 lines added) Replace 244 bytes with 2 bytes (6/6 lines changed; 5 lines removed) |
и в результате
получилось такое
c:\d\Zope\zope213\Products.vcufile
│ Products.vcufile-configure.zcml
│ README.txt
│ setup.py
│
├───docs
│ HISTORY.txt
│
├───Products
│ │ __init__.py
│ │
│ └───vcufile
│ configure.zcml
│ README.txt
│ tests.py
│ zope2.py
│ __init__.py
│
└───Products.vcufile.egg-info
dependency_links.txt
entry_points.txt
namespace_packages.txt
not-zip-safe
PKG-INFO
requires.txt
SOURCES.txt
top_level.txt
|
Согласно
руководству по обяичиванию, заменил
содержимое папки
c:\d\Zope\zope213\Products.vcufile\Products\vcufile
содержимым своего продукта. Получилось
так
c:\d\Zope\zope213\Products.vcufile
│ Products.vcufile-configure.zcml
│ README.txt
│ setup.py
│
├───docs
│ HISTORY.txt
│
├───Products
│ │ vcufile.egg.template.rar
│ │ __init__.py
│ │
│ └───vcufile
│ │ CHANGES.txt
│ │ configure.zcml
│ │ DEPENDENCIES.txt
│ │ HISTORY.txt
│ │ INSTALL.txt
│ │ LICENSE.txt
│ │ README.txt
│ │ TODO.txt
│ │ uploads_const.py
│ │ vcufile.py
│ │ vcufileproduct.py
│ │ VERSION.txt
│ │ __init__.py
│ │
│ ├───help
│ │ VCUFile.stx
│ │
│ ├───static
│ │ vcu.sl.client.js
│ │
│ ├───tests
│ │ testVCUFile.py
│ │ __init__.py
│ │
│ └───www
│ vcufile.png
│ vcufile16.png
│ vcuFileAdd.dtml
│ vcuFileEdit.dtml
│ vcuFileView.zpt
│
└───Products.vcufile.egg-info
dependency_links.txt
entry_points.txt
namespace_packages.txt
not-zip-safe
PKG-INFO
requires.txt
SOURCES.txt
top_level.txt
|
Жирным я выделил
свои файлы, остальное нагенерировано
роботом.
Как и положено,
теперь продукт Zope выполнен в формате
egg, что несколько меняет
способ его подключения к Zope.
Подключаю
Product egg к Zope.
Сперва нужно
удалить старый продукт, в виде папки
c:\d\Zope\zope213\Products\vcufile
если она еще не удалена на предыдущем
шаге.
Теперь разместить
яйцо в разработческой папке
c:\d\Zope\zope213\src\Products.vcufile
Поправить конфиг билдаута
[buildout]
parts =
zopeskel
paster
instance
extends = http://download.zope.org/Zope2/index/2.13.13/versions.cfg
develop =
src/Products.vcufile
[zopeskel]
recipe = zc.recipe.egg
eggs =
ZopeSkel<2.99
[paster]
recipe = zc.recipe.egg
eggs =
PasteScript
ZopeSkel<2.99
[instance]
recipe = zc.recipe.egg
eggs =
Zope2
Products.ZSQLMethods
Products.vcufile
interpreter = zopepy
scripts = runzope zopectl
initialization =
import sys
sys.argv[1:1] = ['-C', r'${buildout:directory}\etc\zope.conf']
|
и пересобрать
C:\d\Zope\zope213>bin\buildout.exe
Работает, проверил.
Поставленная
на сегодня задача выполнена — продукт
Zope завернут в яйцо (egg) и
подключен к Zope в таком виде.
Теперь можно
сделать то, для чего вся эта байда была
затеяна — запустить систему тестирования.
Как сказано в
руководстве
(collective-docs.readthedocs.org/en/latest/testing_and_debugging/unit_testing)
надо подключить zc.testrunner.
Правлю конфиг
билдаута
[buildout]
parts =
zopeskel
paster
test
instance
extends = http://download.zope.org/Zope2/index/2.13.13/versions.cfg
develop =
src/Products.vcufile
[zopeskel]
recipe = zc.recipe.egg
eggs =
ZopeSkel<2.99
[paster]
recipe = zc.recipe.egg
eggs =
PasteScript
ZopeSkel<2.99
[test]
recipe = zc.recipe.testrunner
defaults = ['--auto-color', '--auto-progress']
eggs =
${instance:eggs}
[instance]
recipe = zc.recipe.egg
eggs =
Zope2
Products.ZSQLMethods
Products.vcufile
interpreter = zopepy
scripts = runzope zopectl
initialization =
import sys
sys.argv[1:1] = ['-C', r'${buildout:directory}\etc\zope.conf']
|
после перестройки,
как и обещали, появляется утилита
c:\d\Zope\zope213\bin\test.exe
Запускаю
(барабанная дробь....)
C:\d\Zope\zope213>bin\test -s Products.vcufile Running zope.testing.testrunner.layer.UnitTests tests: Set up zope.testing.testrunner.layer.UnitTests in 0.000 seconds. Running: Ran 1 tests with 0 failures and 0 errors in 0.000 seconds. Tearing down left over layers: Tear down zope.testing.testrunner.layer.UnitTests in 0.000 seconds. |
Ура, товарищи!
Unit tests запустились и
отработали.
Вот ради этого
события и проделана вся вышеописанная
работа — многоэтапная переделка
«старорежимного» Zope Product в формат egg.
Чисто для
справки, на текущий момент юнит-тесты
выглядят так
c:\d\Zope\zope213\src\Products.vcufile\Products\vcufile\tests\__init__.py
# This file is needed to make this a package. |
c:\d\Zope\zope213\src\Products.vcufile\Products\vcufile\tests\testVCUFile.py
import os
import unittest
import ZODB # dead goat
import Products.vcufile.tests
from Products.vcufile.vcufileproduct import VCUFileProduct
import App.config
class testVCUFile(unittest.TestCase):
def setUp(self):
self._old = App.config.getConfiguration()
cfg = App.config.DefaultConfiguration()
cfg.instancehome = os.path.dirname(
Products.vcufile.tests.__file__)
App.config.setConfiguration(cfg)
def tearDown(self):
App.config.setConfiguration(self._old)
def testFID(self):
vf = VCUFileProduct('123', '456')
self.assertEqual(vf.getFID(), '')
state = vf.__getstate__()
vf2 = VCUFileProduct.__basicnew__()
vf2.__setstate__(state)
self.assertEqual(vf2.getFID(), '')
self.failIf(state.has_key('func_defaults'))
def test_suite():
return unittest.makeSuite(testVCUFile)
def package_home(globals_dict):
__name__=globals_dict['__name__']
m=sys.modules[__name__]
if hasattr(m,'__path__'):
r=m.__path__[0]
elif "." in __name__:
r=sys.modules[__name__.split('.',1)[0]].__path__[0]
else:
r=__name__
return os.path.abspath(r)
if __name__=='__main__':
unittest.main(defaultTest='test_suite')
|
Заготовка по
шаблону, зато работает.
Вот и сказочке
конец, кто дослушал — молодец.
Что было полезно
pypi.python.org/pypi/Zope2/2.12.8
Removed the test command from zopectl. The test.py script it was
relying on does no longer exist.
Комментариев нет:
Отправить комментарий