📜 ⬆️ ⬇️

Guide: Pyramid for People - part 3

Part 2: concept, installation and simple “hello world” application

Step 02: unit and functional testing

Of course, testing helps ensure future quality and facilitates refactoring. And this, of course, makes development faster, especially when using smart editors and IDEs . Restarting your application and clicking on your browser is a drag.

In this step, the same code is used as in step one, but we will add some tests.
')
Goals
Technical requirements
Steps

$ cd ../../creatingux; mkdir step02; cd step02
Create a directory in the right place.
Copy the following into the newly created file step02/application.py :
from wsgiref.simple_server import make_server

from pyramid.config import Configurator
from pyramid.response import Response

def hello_world (request):
return response ( 'hello!' )

def main ():
config = Configurator ()
config . add_view (hello_world)
app = config . make_wsgi_app ()
return app

if __name__ == '__main__' :
app = main ()
server = make_server ( '0.0.0.0' , 8080 , app)
server . serve_forever ()
This is the same code that we saw in step one.
Copy the following in step02/tests.py :
import unittest

class ProjectorViewsUnitTests (unittest . TestCase):
def test_hello_world ( self ):
from application import hello_world
result = hello_world ({})
self . assertEqual (result . body, 'hello!' )

class ProjectorFunctionalTests (unittest . TestCase):
def setUp ( self ):
from application import main
app = main ()
from webtest import TestApp
self . testapp = TestApp (app)

def test_it ( self ):
res = self . testapp . get ( '/' , status = 200 )
self . failUnless ( 'hello' in res . body)
$ nosetests
After that we should see the following result:
..
--------------------------------------------------------
Ran 2 tests in 0.301s

OK


Additional questions
Analysis

Unit tests are hard. Unit tests with the framework are even more difficult. The Pyramid culture, in spite of this, aims at full test coverage, and Pyramid works very hard to make writing tests a useful activity.

Even if you do not do full test coverage, you will find that most basic unit tests catch standard errors faster than opening your browser, for verification, with each code change. This is a bit like installing your editor, or IDE, to start pylint which allows you to know before saving (much less before executing) whether you have any errors.

Functional tests are easier to write, and for UX-people, they help with the problem in question.

Theses
Step 03: Hello World at Chameleon

Most web systems have a template language for generating HTML. This gives the UX-person the opportunity to concentrate on the thing they know (the markup) and interspersed in the code, and not vice versa.

Pyramid doesn’t have much to say about languages. This tutorial does though. We're Chameleon / ZPT folks. So let's do “hello world” using the page template.

Goals
Technical task
Steps

Recall that the installation section $ export PYRAMID_RELOAD_TEMPLATES=1 to make $ export PYRAMID_RELOAD_TEMPLATES=1 , which allows you to edit templates and not have to reload your Pyramid application.
$ cd ../../creatingux; mkdir step03; cd step03
Copy the following to step03/application.py :
from wsgiref.simple_server import make_server

from pyramid.config import Configurator

def main ():
config = Configurator ()
config . scan ( "views" )
app = config . make_wsgi_app ()
return app

if __name__ == '__main__' :
app = main ()
server = make_server ( '0.0.0.0' , 8080 , app)
server . serve_forever ()
Copy the following into step03/views.py :
from pyramid.view import view_config

@view_config (renderer = "hello.pt" )
def hello_view (request):
return { "tutorial" : "Little Dummy" }
And further, the HTML template layout is step03/hello.pt in step03/hello.pt :
<html>
<head>
<title> Hello </ title>
</ head>
<body>
<p> Hello, $ {tutorial} </ p>
</ body>
</ html>
And here it is - step03/tests.py :
import unittest

class ProjectorViewsUnitTests (unittest . TestCase):
def test_hello_view ( self ):
from views import hello_view
result = hello_view ({})
self . assertEqual (result [ 'tutorial' ], 'Little Dummy' )

class ProjectorFunctionalTests (unittest . TestCase):
def setUp ( self ):
from application import main
app = main ()
from webtest import TestApp
self . testapp = TestApp (app)

def test_it ( self ):
res = self . testapp . get ( '/' , status = 200 )
self . failUnless ( 'Hello' in res . body)
And finally, we write:
$ nosetests
Following what should see:
..
----------------------------------------------------------------
Ran 2 tests in 0.885s

OK


Trying to run: $ python application.py
And open 127.0.0.1:8080 in your browser.

Additional questions

If you are editing a theme, do you need to restart the application to see the changes?
What other values ​​are possible for the renderer, on @view_config?

Analysis

This step gives an idea of ​​code parsing. There are several different ways to make configuration in Pyramid: imperative (which we saw in the first step: Hello World in Pyramid), scanning (close to many modern web frameworks), and our old friend ZCML. The choice is mainly one of the style, though there are some sharp edges in some cases.

Note the coolness ... all you have to do is return the dictionary to your submission, and your template is invoked on the way out the door, with this data.

Theses

Configuration history in Zope2, Zope3, BFG, then Pyramid
How things worked before renderers

Following is part 4 .

Source: https://habr.com/ru/post/136245/


All Articles