Не корысти
ради а токмо волею пославшей мя жены! ©
Ильф и Петров.
В продолжение
темы «Заготовка
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.
Комментариев нет:
Отправить комментарий