Upgrade to Pro — share decks privately, control downloads, hide ads and more …

werkzeugkiste.pdf

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for wosc wosc
October 28, 2012
190

 werkzeugkiste.pdf

Avatar for wosc

wosc

October 28, 2012
Tweet

Transcript

  1. Aus der Werkzeugkiste eines Python/Web-Entwicklers Wolfgang Schnerring gmbh & co.

    kg PyCon DE 2012, Leipzig Wolfgang Schnerring Werkzeugkiste 01.11.2012 1 / 45
  2. Agenda 1 Sandbox 2 Editor 3 Konsole 4 Testing 5

    Deployment http://www.flickr.com/photos/zakh/337938459 by zakh Wolfgang Schnerring Werkzeugkiste 01.11.2012 4 / 45
  3. Sandbox Paket-Skelett setup.py README.txt CHANGES.txt HACKING.txt LICENSE.txt doc/ src/ws/pycondetalk/tests/ jeweils

    mit passender __init__.py Wolfgang Schnerring Werkzeugkiste 01.11.2012 6 / 45
  4. Sandbox Paket-Skelett $ bin/paster create -t gocept_package ws.pycondetalk <...snip...> Enter

    description (One-line description of the package) ['']: An example for my talk Enter keywords (Space-separated keywords/tags) ['']: Creating template gocept_package <...snip...> Wolfgang Schnerring Werkzeugkiste 01.11.2012 7 / 45
  5. Sandbox Isolation http://www.flickr.com/photos/ajc1/2799103829 by ajc1 Using the system-installed Python is

    considered harmful. I want YOU to use virtualenv! Wolfgang Schnerring Werkzeugkiste 01.11.2012 8 / 45
  6. Sandbox Isolation http://www.flickr.com/photos/ajc1/2799103829 by ajc1 Using the system-installed Python is

    considered harmful. I want YOU to use virtualenv! . . . but not activate! Wolfgang Schnerring Werkzeugkiste 01.11.2012 8 / 45
  7. Sandbox Pakete installieren PyPI ist hervorragend – außer, wenn er

    down ist Leute ihre Eggs nicht hochladen, sondern selber hosten und dann down sind Leute alte Versionen löschen . . . Wolfgang Schnerring Werkzeugkiste 01.11.2012 10 / 45
  8. Sandbox Pakete installieren PyPI ist hervorragend – außer, wenn er

    down ist Leute ihre Eggs nicht hochladen, sondern selber hosten und dann down sind Leute alte Versionen löschen . . . Hilfreiche Parameter für pip/easy_install: index, find-links socket-timeout, allow-hosts Wolfgang Schnerring Werkzeugkiste 01.11.2012 10 / 45
  9. Sandbox Pakete installieren I want YOU to pin your versions!

    Wolfgang Schnerring Werkzeugkiste 01.11.2012 11 / 45
  10. Sandbox Pakete installieren [buildout] allow−picked−versions = false versions = versions

    [versions] Sphinx = 1.1.2 zc.buildout pip install -r requirements.txt ist nicht ganz das gleiche Wolfgang Schnerring Werkzeugkiste 01.11.2012 12 / 45
  11. Editor Syntax check Emacs: flymake-mode, Vim: syntastic pyflakes, importchecker, pep8,

    pylint Wolfgang Schnerring Werkzeugkiste 01.11.2012 15 / 45
  12. Konsole Anwendung >>> import zope, myapp >>> um = zope.component.getUtility(

    myapp.usermanager.interfaces.IUserManager) >>> um.get_user( ’[email protected]’).login = ’[email protected]’ >>> import transaction >>> transaction.commit() Wolfgang Schnerring Werkzeugkiste 01.11.2012 18 / 45
  13. Konsole Anwendung >>> import zope, myapp >>> um = zope.component.getUtility(

    myapp.usermanager.interfaces.IUserManager) >>> um.get_user( ’[email protected]’).login = ’[email protected]’ >>> import transaction >>> transaction.commit() Zope: zopectl debug Pyramid: bin/pshell etc/paste.ini Django: manage.py shell Wolfgang Schnerring Werkzeugkiste 01.11.2012 18 / 45
  14. Konsole Readline-History (pdb) p self.request.get(’key’).getList() ∗∗∗ AttributeError: ’Example’ object has

    no attribute ’getList’ Wolfgang Schnerring Werkzeugkiste 01.11.2012 19 / 45
  15. Konsole Readline-History (pdb) p self.request.get(’key’).getList() ∗∗∗ AttributeError: ’Example’ object has

    no attribute ’getList’ <ARROW_UP> (pdb) p self.request.get(’key’).get_list() Wolfgang Schnerring Werkzeugkiste 01.11.2012 19 / 45
  16. Konsole Readline-History (pdb) p self.request.get(’key’).getList() ∗∗∗ AttributeError: ’Example’ object has

    no attribute ’getList’ <ARROW_UP> (pdb) p self.request.get(’key’).get_list() pdb (siehe https://gist.github.com/3621963) rlwrap Wolfgang Schnerring Werkzeugkiste 01.11.2012 19 / 45
  17. Konsole Test-Auswahl $ bin/test −t create_user $ bin/test −s myapp.subpackage

    Wolfgang Schnerring Werkzeugkiste 01.11.2012 20 / 45
  18. Konsole Test-Auswahl $ bin/test −t create_user $ bin/test −s myapp.subpackage

    zope.testrunner nose py.test stdlib unittest ab 2.7 (bzw. Backport-Paket unittest2) Wolfgang Schnerring Werkzeugkiste 01.11.2012 20 / 45
  19. Konsole Test-Auswahl $ t −t create_user $ t −s myapp.subpackage

    Wolfgang Schnerring Werkzeugkiste 01.11.2012 21 / 45
  20. Testing Layer class Layer(object): __bases__ = (OTHER_LAYER,) def setUp(self): def

    tearDown(self): def testSetUp(self): def testTearDown(self): Wolfgang Schnerring Werkzeugkiste 01.11.2012 26 / 45
  21. Testing Beispiel class PersistenceTest(unittest.TestCase): layer = DB_LAYER def test_serializing_document_parameters(self): #

    [...] class IntegrationTest(unittest.TestCase): layer = COMBINED_LAYER def test_search_displays_suggestions_from_database(self): # [...] Wolfgang Schnerring Werkzeugkiste 01.11.2012 27 / 45
  22. Testing Beispiel class DatabaseLayer(plone.testing.Layer): def setUp(self): self.connection = dbdriver.connect(os.environ[’DSN’]) def

    tearDown(self): self.connection.close() DB_LAYER = DatabaseLayer() HTTP_LAYER = HTTPServerLayer() COMBINED_LAYER = plone.testing.Layer( bases=(DatabaseLayer, HTTPServerLayer)) Wolfgang Schnerring Werkzeugkiste 01.11.2012 28 / 45
  23. Testing JSLint var something = { ’foo’: ’bar’, }; Wolfgang

    Schnerring Werkzeugkiste 01.11.2012 29 / 45
  24. Testing JSLint var something = { ’foo’: ’bar’, }; $

    jshint foo.js Line 1: 'something' is defined but never used. Line 2: Extra comma. Wolfgang Schnerring Werkzeugkiste 01.11.2012 29 / 45
  25. Testing JSLint var something = { ’foo’: ’bar’, }; $

    jshint foo.js Line 1: 'something' is defined but never used. Line 2: Extra comma. $ bin/test -t jslint Failure in test test_jslint_foo.js Traceback (most recent call last): <snip> AssertionError: JSLint foo.js:2:Extra comma. Wolfgang Schnerring Werkzeugkiste 01.11.2012 29 / 45
  26. Testing gocept.jslint class JSLintTestCase(gocept.jslint.TestCase): include = (’my.package.browser:js’,) options = (gocept.jslint.TestCase.options

    + (’browser’, ’jquery’,)) ignore = ( "Don’t make functions within a loop", ) Wolfgang Schnerring Werkzeugkiste 01.11.2012 30 / 45
  27. Testing JavaScript Unit-Tests require ’my_app.js’ describe ’MyApp’, −> it ’has

    read Douglas Adams’, −> expect(new MyApp().calculate_the_answer()).toEqual(42) Wolfgang Schnerring Werkzeugkiste 01.11.2012 31 / 45
  28. Testing JavaScript Unit-Tests require ’my_app.js’ describe ’MyApp’, −> it ’has

    read Douglas Adams’, −> expect(new MyApp().calculate_the_answer()).toEqual(42) def test_suite(): return gocept.exttest.makeSuite( os.environ.get(’jasmine−bin’), ’−−coffee’, pkg_resources.resource_filename(’your.package’, ’tests’)) gocept.exttest ist noch im Alpha-Stadium. Wolfgang Schnerring Werkzeugkiste 01.11.2012 31 / 45
  29. Testing gocept.selenium class AutocompleteTest(gocept.selenium.wsgi.TestCase): layer = gocept.selenium.wsgi.Layer(my_wsgi_callable) def test_search_field_should_show_suggestions(self): s

    = self.selenium s.open(’http://%s:%s/search_form’ % (self.layer.host, self.layer.port) s.type(’name=q’, ’zope’) s.waitForVisible(’id=suggestions’)) s.assertText(’//div[@id="suggestions"])/ul/li[2]’, ’∗fisch’) Wolfgang Schnerring Werkzeugkiste 01.11.2012 34 / 45
  30. Deployment Egg-Releases Thinking about checking out trunk to production? I

    want YOU to use eggs! Wolfgang Schnerring Werkzeugkiste 01.11.2012 38 / 45
  31. Deployment Egg-Releases 1 Versionsnummer in setup.py eintragen, Datum in CHANGES.txt

    eintragen 2 Tag erzeugen 3 python setup.py sdist 4 Tarball hochladen (PyPI oder eigener Server) 5 Versionsnummer in setup.py/CHANGES.txt hochzählen zest.relaser macht das alles auf Knopfdruck Wolfgang Schnerring Werkzeugkiste 01.11.2012 39 / 45
  32. Deployment http://12factor.net/ Codebase Dependencies Config Backing Services Build, release, run

    Processes Port binding Concurrency Disposability dev/prod parity Logs Admin processes Wolfgang Schnerring Werkzeugkiste 01.11.2012 40 / 45
  33. Deployment Konfigurations-Profile base.cfg email-from = [email protected] database-url = sqlite:/// dev.cfg

    extends = base.cfg database-url = postgresql://localhosthost/myapp-dev production.cfg extends = base.cfg database-url = postgresql://db.example.com/myapp Wolfgang Schnerring Werkzeugkiste 01.11.2012 41 / 45
  34. Deployment 1-Click-Deployment 1 Versionsnummern hochziehen 2 Tag erzeugen bzw. auf

    production-Branch mergen 3 Auf Produktions-Server anmelden 4 Vom VCS aktualisieren 5 Deployment laufen lassen 6 Tests laufen lassen 7 Prozesse neustarten Wolfgang Schnerring Werkzeugkiste 01.11.2012 42 / 45
  35. Deployment 1-Click-Deployment def pull(): remote(’hg pull −u’) def deploy(): remote(’bin/buildout’)

    def test(): remote(’bin/test’) def restart(): remote(’etc/init.d/myproduct−app1 restart’) def remote(command): return fabric.api.sudo( (’cd %s && ’ + command) % SERVICE_DIR, user=SERVICE_USER) Wolfgang Schnerring Werkzeugkiste 01.11.2012 43 / 45
  36. Zusammenfassung Uncle Sam sagt I want YOU to use eggs!

    I want YOU to use virtualenv! I want YOU to pin your versions! Wolfgang Schnerring Werkzeugkiste 01.11.2012 44 / 45