Часть 3: юнит- и функциональное тестирование, Hello World в Chameleon
Хватит с нас “hello world”, теперь приступим к работе над Projector'ом. UX-человек обычно имеет ряд представлений, которые нуждаются в прототипировании и отображении в URL-структуру.
Мы хотим сделать этот процесс быстрым и продуктивным.
В этом шаге мы копируем структуру карты сайта такую:
(Неизмененное) Копируем одно в другое —
что должно выдать нам отчет по 6ти тестам.
Запускаем приложение:
И радуемся результату в браузере —
Что произойдет если у вас есть две регистрации представления без @ name атрибута, meaning both as the default?
Правда ли что Chameleon (сейчас, если мы говорим о второй версии) в любом случае лучше для предоставления вам сообщений об ошибках? Попробуйте это, положив немного ошибок в ваши Python выражения.
Будет ли WebTest корректно срабатывать на эти ошибки?
Влияет ли прибавление .html, к вашим URL'ам, на что-нибудь?
Мы начали процесс построения пространства URL'ов, которые отображаются в объекты и иерархию, в нашем приложении. На данный момент, мы смоделировали это с использованием представлений.
Несмотря на увеличение количества наших тестов, каждый из них до сих пор очень маленький. Даже такой простой тест будет до сих пор ловить большинство глупых ошибок которые всплывают в процессе начальной разработки. Надеемся, вы найдете для себя nosetests'ы более продуктивными, чем простое кликание.
How do the registrations happen under the hood?
Chameleon, кэширование, и занесение готовых версий на диск
Шаг 04: Каркас представлений
Хватит с нас “hello world”, теперь приступим к работе над Projector'ом. UX-человек обычно имеет ряд представлений, которые нуждаются в прототипировании и отображении в URL-структуру.
Мы хотим сделать этот процесс быстрым и продуктивным.
В этом шаге мы копируем структуру карты сайта такую:
/
/about.html
/acme
/people
… и сделаем ряд URL'ов которые это осуществят. По ходу, мы создаем больше представлений и больше шаблонов.Цели
- Введение в UX рабочий процесс, для примера, используя произвольные данные
Что ожидается
- “Стандартные” и “именованные” представления
- Больше ZPT конструкций
Шаги
$ cd ../../creatingux; mkdir step04; cd step04
(Неизмененное) Копируем одно в другое —
step04/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()
step04/views.py
:from pyramid.view import view_configИ здесь —
@view_config(renderer="index.pt")
def index_view(request):
return {}
@view_config(renderer="about.pt", name="about.html")
def about_view(request):
return {}
@view_config(renderer="company.pt", name="acme")
def company_view(request):
return {"company": COMPANY, "projects": PROJECTS}
@view_config(renderer="people.pt", name="people")
def people_view(request):
return {"company": COMPANY, "people": PEOPLE}
# Dummy data
COMPANY = "ACME, Inc."
PEOPLE = [
{'name': 'sstanton', 'title': 'Susan Stanton'},
{'name': 'bbarker', 'title': 'Bob Barker'},
]
PROJECTS = [
{'name': 'sillyslogans', 'title': 'Silly Slogans'},
{'name': 'meaninglessmissions', 'title': 'Meaningless Missions'},
]
step04/index.pt
:<html>Дальше здесь —
<head>
<title>Projector - Home</title>
</head>
<body>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about.html">About Projector</a></li>
<li><a href="/acme">ACME, Inc.</a></li>
<li><a href="/people">People</a></li>
</ul>
<h1>Projector - Home</h1>
</body>
</html>
step04/about.pt
:<html>Здесь —
<head>
<title>Projector - About</title>
</head>
<body>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about.html">About Projector</a></li>
<li><a href="/acme">ACME, Inc.</a></li>
<li><a href="/people">People</a></li>
</ul>
<h1>Projector - About</h1>
<p>Projector is a simple project management tool capable of hosting
multiple projects for multiple independent companies,
sharing a developer pool between autonomous companies.</p>
</body>
</html>
step04/company.pt
:<html>И наконец, здесь —
<head>
<title>Projector - People</title>
</head>
<body>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about.html">About Projector</a></li>
<li><a href="/acme">ACME Inc.</a></li>
<li><a href="/people">People</a></li>
</ul>
<h1>People</h1>
<ul>
<li tal:repeat="person people">
<a href="${person.name}">${person.title}</a>
</li>
</ul>
</body>
</html>
step04/tests.py
:import unittestДальше пишем:
class ProjectorViewsUnitTests(unittest.TestCase):
def test_hello_view(self):
from views import index_view
result = index_view({})
self.assertEqual(len(result.keys()), 0)
def test_about_view(self):
from views import about_view
result = about_view({})
self.assertEqual(len(result.keys()), 0)
def test_company_view(self):
from views import company_view
result = company_view({})
self.assertEqual(result["company"], "ACME, Inc.")
self.assertEqual(len(result["projects"]), 2)
def test_people_view(self):
from views import people_view
result = people_view({})
self.assertEqual(result["company"], "ACME, Inc.")
self.assertEqual(len(result["people"]), 2)
class ProjectorFunctionalTests(unittest.TestCase):
def setUp(self):
from application import main
app = main()
from webtest import TestApp
self.testapp = TestApp(app)
def test_home(self):
res = self.testapp.get('/', status=200)
self.failUnless('Home' in res.body)
def test_it(self):
res = self.testapp.get('/', status=200)
self.failUnless('Home' in res.body)
res = self.testapp.get('/about.html', status=200)
self.failUnless('autonomous' in res.body)
res = self.testapp.get('/people', status=200)
self.failUnless('Susan' in res.body)
res = self.testapp.get('/acme', status=200)
self.failUnless('Silly Slogans' in res.body)
$ nosetests
что должно выдать нам отчет по 6ти тестам.
Запускаем приложение:
$ python application.py
И радуемся результату в браузере —
127.0.0.1:8080
Дополнительные вопросы
Что произойдет если у вас есть две регистрации представления без @ name атрибута, meaning both as the default?
Правда ли что Chameleon (сейчас, если мы говорим о второй версии) в любом случае лучше для предоставления вам сообщений об ошибках? Попробуйте это, положив немного ошибок в ваши Python выражения.
Будет ли WebTest корректно срабатывать на эти ошибки?
Влияет ли прибавление .html, к вашим URL'ам, на что-нибудь?
Анализ
Мы начали процесс построения пространства URL'ов, которые отображаются в объекты и иерархию, в нашем приложении. На данный момент, мы смоделировали это с использованием представлений.
Несмотря на увеличение количества наших тестов, каждый из них до сих пор очень маленький. Даже такой простой тест будет до сих пор ловить большинство глупых ошибок которые всплывают в процессе начальной разработки. Надеемся, вы найдете для себя nosetests'ы более продуктивными, чем простое кликание.
Тезисы
How do the registrations happen under the hood?
Chameleon, кэширование, и занесение готовых версий на диск