SlideShare uma empresa Scribd logo
1 de 42
Baixar para ler offline
Тестирование
      и Django
      Илья Барышев
       @coagulant


 Moscow Django Meetup №6
Защита от
регрессий
Быстрые
изменения
  в коде
Меняет подход к
написанию кода
Пойдёт на пользу
 вашему проекту
Модульное
тестирование
 	
  	
  	
  def	
  test_vin_is_valid(self):
	
  	
  	
  	
  	
  	
  	
  	
  valid_vins	
  =	
  ('2G1FK1EJ7B9141175',
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  '11111111111111111',)
	
  	
  	
  	
  	
  	
  	
  	
  for	
  valid_vin	
  in	
  valid_vins:
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  self.assertEqual(vin_validator(valid_vin),	
  None)


	
  	
  	
  	
  def	
  test_vin_is_invalid(self):
	
  	
  	
  	
  	
  	
  	
  	
  invalid_vins	
  =	
  ('abc',	
  u'M05C0WDJAN60M33TUP6',)
	
  	
  	
  	
  	
  	
  	
  	
  for	
  invalid_vin	
  in	
  invalid_vins:
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  self.assertRaises(ValidationError,	
  
                                                   	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  vin_validator,	
  invalid_vin)
Unittest

Модели      Контекст-процессоры
Формы       Middleware
Views?      Template tags, filters
Тестируйте поведение
     А не имплементацию
Функциональное
 тестирование
django.test.client.Client
def	
  testPostAsAuthenticatedUser(self):
	
  	
  	
  	
  data	
  =	
  self.getValidData(Article.objects.get(pk=1))
	
  	
  	
  	
  self.client.login(username="normaluser",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  password="normaluser")
	
  	
  	
  	
  self.response	
  =	
  self.client.post("/post/",	
  data)
	
  	
  	
  	
  
	
  	
  	
  	
  self.assertEqual(self.response.status_code,	
  302)
	
  	
  	
  	
  self.assertEqual(Comment.objects.count(),	
  1)
django.test.сlient.RequestFactory
def	
  test_post_ok(self):
	
  	
  	
  	
  request	
  =	
  RequestFactory().post(reverse('ch_location'),
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {'location_id':	
  77})
	
  	
  	
  	
  request.cookies	
  =	
  {}

	
  	
  	
  	
  response	
  =	
  change_location(request)

	
  	
  	
  	
  self.assertEqual(response.cookies['LOCATION'].value,	
  '77')
	
  	
  	
  	
  self.assertEqual(response.status_code,	
  302)
Smoke Testing
def	
  test_password_recovery_smoke(self):
         	
  	
  	
  	
  """
         	
  	
  	
  	
  Урлы	
  восстановления	
  пароля.
         	
  	
  	
  	
  Логика	
  уже	
  протестирована	
  в	
  django-­‐password-­‐reset
         	
  	
  	
  	
  """
         	
  	
  	
  	
  response_recover	
  =	
  self.client.get(reverse('pass_recover'))
         	
  	
  	
  	
  
         	
  	
  	
  	
  self.assertEqual(response_recover.status_code,	
  200)

	
  	
  	
  	
  	
  	
  	
  	
  self.assertContains(response_recover,
	
  	
  	
  	
  	
  	
  	
  	
  self.assertTemplateUsed(response_recover,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  u'Восстановление	
  пароля')
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  'password_reset/recovery_form.html')
Как мы тестируем
Continious
Integration
Покрытие важно
  Но не делайте из него фетиш
mock
http://www.voidspace.org.uk/python/mock/
>>>	
  real	
  =	
  SomeClass()
>>>	
  my_mock	
  =	
  MagicMock(name='method')
>>>	
  real.method	
  =	
  my_mock
>>>	
  real.method(3,	
  4,	
  5,	
  key='value')
>>>	
  my_mock.called
True
>>>	
  my_mock.call_count
1
>>>	
  mock.method.assert_called_with(3,	
  4,	
  5)
Traceback	
  (most	
  recent	
  call	
  last):
	
  	
  ...
AssertionError:	
  Expected	
  call:	
  method(3,	
  4,	
  5)
Actual	
  call:	
  method(3,	
  4,	
  5,	
  key='value')
@patch('twitter.Api')
def	
  test_twitter_tag_simple_mock(self,	
  ApiMock):
	
  	
  	
  	
  api_instance	
  =	
  ApiMock.return_value
	
  	
  	
  	
  api_instance.GetUserTimeline.return_value	
  =	
  SOME_JSON

	
  	
  	
  	
  output,	
  context	
  =	
  render_template(
                   """{%	
  load	
  twitter_tag	
  %}
                     	
  {%	
  get_tweets	
  for	
  "jresig"	
  as	
  tweets	
  %}""")

	
  	
  	
  	
  api_instance.GetUserTimeline.assert_called_with(
	
  	
  	
  	
  	
  	
  	
  	
  screen_name='jresig',	
  
	
  	
  	
  	
  	
  	
  	
  	
  include_rts=True,	
  
	
  	
  	
  	
  	
  	
  	
  	
  include_entities=True)
from	
  mock	
  import	
  patch
from	
  django.conf	
  import	
  settings

@patch.multiple(settings,	
  APPEND_SLASH=True,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  MIDDLEWARE_CLASSES=(common_middleware,))
def	
  test_flatpage_doesnt_require_trailing_slash(self):
	
  	
  	
  	
  form	
  =	
  FlatpageForm(data=dict(url='/no_trailing_slash',	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  **self.form_data))
	
  	
  	
  	
  self.assertTrue(form.is_valid())
from	
  django.test.utils	
  import	
  override_settings

@override_settings(
	
  	
  	
  	
  APPEND_SLASH=False,	
  
	
  	
  	
  	
  MIDDLEWARE_CLASSES=(common_middleware,)
)
def	
  test_flatpage_doesnt_require_trailing_slash(self):
	
  	
  	
  	
  form	
  =	
  FlatpageForm(data=dict(url='/no_trailing_slash',	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  **self.form_data))
	
  	
  	
  	
  self.assertTrue(form.is_valid())
Фикстуры
[
    {
         "model": "docs.documentrelease",
         "pk": 1,
         "fields": {
           "lang": "en",
           "version": "dev",
           "scm": "svn",
           "scm_url": "http://code.djangoproject.com/svn/django/trunk/docs",
           "is_default": false
         }
    },
    {
         "model": "docs.documentrelease",             Обычный тест с
         "pk": 2,                                     фикстурами
         "fields": {
           "lang": "en",
           "version": "1.0",
           "scm": "svn",
           "scm_url": "http://code.djangoproject.com/svn/django/branches/releases/1.0.X/docs",
           "is_default": false
         }
    },
    {
         "model": "docs.documentrelease",
         "pk": 3,
         "fields": {
           "lang": "en",
           "version": "1.1",
           "scm": "svn",
           "scm_url": "http://code.djangoproject.com/svn/django/branches/releases/1.1.X/docs",
           "is_default": false
django-­‐any
                            https://github.com/kmmbvnr/django-­‐any


from	
  django_any	
  import	
  any_model

class	
  TestMyShop(TestCase):
	
  	
  	
  	
  def	
  test_order_updates_user_account(self):
	
  	
  	
  	
  	
  	
  	
  	
  account	
  =	
  any_model(Account,	
  amount=25,	
  
                                          	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  user__is_active=True)
	
  	
  	
  	
  	
  	
  	
  	
  order	
  =	
  any_model(Order,	
  user=account.user,	
  
                                          	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  amount=10)
	
  	
  	
  	
  	
  	
  	
  	
  order.proceed()

	
  	
  	
  	
  	
  	
  	
  	
  account	
  =	
  Account.objects.get(pk=account.pk)
	
  	
  	
  	
  	
  	
  	
  	
  self.assertEquals(15,	
  account.amount)
factory_boy
https://github.com/dnerdy/factory_boy
import	
  factory
from	
  models	
  import	
  MyUser

class	
  UserFactory(factory.Factory):
	
  	
  	
  	
  FACTORY_FOR	
  =	
  MyUser
	
  	
  	
  	
  first_name	
  =	
  'John'
	
  	
  	
  	
  last_name	
  =	
  'Doe'
	
  	
  	
  	
  admin	
  =	
  False
#	
  Инстанс,	
  сохранённый	
  в	
  базу
user	
  =	
  UserFactory.create()

#	
  Экземпляр	
  User,	
  не	
  сохранённый	
  в	
  базу
user	
  =	
  UserFactory.build()

#	
  Создаём	
  инстанс	
  с	
  конкретыми	
  значениями
user	
  =	
  UserFactory.create(name=u'Василий',	
  age=25)
class	
  UserFactory(factory.Factory):
	
  	
  	
  	
  first_name	
  =	
  'Vasily'
	
  	
  	
  	
  last_name	
  =	
  'Pupkin'
	
  	
  	
  	
  email	
  =	
  factory.LazyAttribute(
                     lambda	
  u:	
  '{0}.{1}@example.com'.format(
                     u.first_name,	
  u.last_name).lower())


>>>	
  UserFactory().email
'vasily.pupkin@example.com'
class	
  UserWithEmailFactory(UserFactory):
	
  	
  	
  	
  email	
  =	
  factory.Sequence(
                   lambda	
  n:	
  'person{0}@example.com'.format(n))


>>>	
  UserFactory().email
'person0@example.com'

>>>	
  UserFactory().email	
  	
  
'person1@example.com'
Django test runner
     SUCKS
INSTALLED_APPS	
  =	
  (
	
  	
  	
  	
  ...

	
  	
  	
  	
  #3rd-­‐party	
  apps
	
  	
  	
  	
  'south',
	
  	
  	
  	
  'sorl.thumbnail',
	
  	
  	
  	
  'pytils',
	
  	
  	
  	
  'pymorphy',	
  	
  	
  	
  	
  
	
  	
  	
  	
  'compressor',
                                                  Несколько сотен
	
  	
  	
  	
  'django_nose',                        тестов
	
  	
  	
  	
  'django_geoip',
	
  	
  	
  	
  'mptt',
	
  	
  	
  	
  'widget_tweaks',
	
  	
  	
  	
  'guardian',
	
  	
  	
  	
  
	
  	
  	
  	
  ...
/tests                               #	
  -­‐*-­‐	
  coding:	
  utf-­‐8	
  -­‐*-­‐
	
  	
  	
  	
  __init__.py
                test_archive.py      from	
  test_archive	
  import	
  *
	
  	
  	
  	
  test_blog_model.py   from	
  test_blog_model	
  import	
  *
	
  	
  	
  	
  test_modified.py     from	
  test_modified	
  import	
  *
	
  	
  	
  	
  test_post_model.py   from	
  test_post_model	
  import	
  *
	
  	
  	
  	
  test_redactor.py     from	
  test_redactor	
  import	
  *
	
  	
  	
  	
  test_views.py        from	
  test_views	
  import	
  *
	
  	
  	
  	
  test_cross_post.py   from	
  test_cross_post	
  import	
  *
django-­‐nose




          https://github.com/jbalogh/django-­‐nose
$	
  pip	
  install	
  django-­‐nose


  #	
  settings.py	
  
  INSTALLED_APPS	
  =	
  (
  	
  	
  	
  	
  ...
  	
  	
  	
  	
  'django_nose',
  	
  	
  	
  	
  ...
  )


  TEST_RUNNER	
  =	
  'django_nose.NoseTestSuiteRunner'
$	
  manage.py	
  test

$	
  manage.py	
  test	
  apps.comments.tests

$	
  manage.py	
  test	
  apps.comments.tests:BlogTestCase

$	
  manage.py	
  test	
  apps.comments.tests:BlogTestCase.test_index



$	
  manage.py	
  test	
  -­‐-­‐with-­‐ids	
  -­‐-­‐failed
$	
  manage.py	
  -­‐-­‐pdb
$	
  manage.py	
  -­‐-­‐pdb-­‐failures
from	
  nose.plugins.attrib	
  import	
  attr

@attr(speed='slow',	
  priority=1)
def	
  test_big_download():
	
  	
  	
  	
  import	
  urllib
	
  	
  	
  	
  #	
  commence	
  slowness..


$	
  nosetests	
  -­‐a	
  speed=slow


$	
  nosetests	
  -­‐a	
  '!slow'


$	
  nosetests	
  -­‐A	
  "(priority	
  >	
  5)	
  and	
  not	
  slow"
TESTING




TESTING
SQLite для
быстрых тестов
 Если ваш проект позволяет
Параллелим тесты
    Нетрудоёмкое ускоение
Ran	
  337	
  tests	
  in	
  326.664s
                    OK	
  (SKIP=2)


1 процесс                                                         326

2 процесса
      Секунды                                   169

3 процесса                               126
                0                  100              200     300         400




                     $	
  ./manage.py	
  -­‐-­‐processes=N
Спасибо за внимание


baryshev@futurecolors.ru
@coagulant                      http://blog.futurecolors.ru/

Mais conteúdo relacionado

Mais procurados

Python testing using mock and pytest
Python testing using mock and pytestPython testing using mock and pytest
Python testing using mock and pytestSuraj Deshmukh
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitMichelangelo van Dam
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Michelangelo van Dam
 
Django tutorial 2009
Django tutorial 2009Django tutorial 2009
Django tutorial 2009Ferenc Szalai
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"GeeksLab Odessa
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian BergmannNew Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmanndpc
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitmfrost503
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013Michelangelo van Dam
 
Test in action week 2
Test in action   week 2Test in action   week 2
Test in action week 2Yi-Huan Chan
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitMichelangelo van Dam
 
Testing in Laravel
Testing in LaravelTesting in Laravel
Testing in LaravelAhmed Yahia
 

Mais procurados (20)

Python testing using mock and pytest
Python testing using mock and pytestPython testing using mock and pytest
Python testing using mock and pytest
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnit
 
Django (Web Konferencia 2009)
Django (Web Konferencia 2009)Django (Web Konferencia 2009)
Django (Web Konferencia 2009)
 
inception.docx
inception.docxinception.docx
inception.docx
 
Phpunit testing
Phpunit testingPhpunit testing
Phpunit testing
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Django tutorial 2009
Django tutorial 2009Django tutorial 2009
Django tutorial 2009
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian BergmannNew Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmann
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 
Practical Celery
Practical CeleryPractical Celery
Practical Celery
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
 
Test in action week 2
Test in action   week 2Test in action   week 2
Test in action week 2
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
Testing in Laravel
Testing in LaravelTesting in Laravel
Testing in Laravel
 

Semelhante a Тестирование и Django

Pruebas unitarias con django
Pruebas unitarias con djangoPruebas unitarias con django
Pruebas unitarias con djangoTomás Henríquez
 
MT_01_unittest_python.pdf
MT_01_unittest_python.pdfMT_01_unittest_python.pdf
MT_01_unittest_python.pdfHans Jones
 
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalksSelenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalksLohika_Odessa_TechTalks
 
Effective testing with pytest
Effective testing with pytestEffective testing with pytest
Effective testing with pytestHector Canto
 
Django - Know Your Namespace: Middleware
Django - Know Your Namespace: MiddlewareDjango - Know Your Namespace: Middleware
Django - Know Your Namespace: Middlewarehowiworkdaily
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethodsdreampuf
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Tsuyoshi Yamamoto
 
E2E testing con nightwatch.js - Drupalcamp Spain 2018
E2E testing con nightwatch.js  - Drupalcamp Spain 2018E2E testing con nightwatch.js  - Drupalcamp Spain 2018
E2E testing con nightwatch.js - Drupalcamp Spain 2018Salvador Molina (Slv_)
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testingpleeps
 
Testing for Pragmatic People
Testing for Pragmatic PeopleTesting for Pragmatic People
Testing for Pragmatic Peopledavismr
 
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...solit
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everythingnoelrap
 
Behind the curtain - How Django handles a request
Behind the curtain - How Django handles a requestBehind the curtain - How Django handles a request
Behind the curtain - How Django handles a requestDaniel Hepper
 
Plone testingdzug tagung2010
Plone testingdzug tagung2010Plone testingdzug tagung2010
Plone testingdzug tagung2010Timo Stollenwerk
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsFrancois Zaninotto
 

Semelhante a Тестирование и Django (20)

Pruebas unitarias con django
Pruebas unitarias con djangoPruebas unitarias con django
Pruebas unitarias con django
 
Django tricks (2)
Django tricks (2)Django tricks (2)
Django tricks (2)
 
MT_01_unittest_python.pdf
MT_01_unittest_python.pdfMT_01_unittest_python.pdf
MT_01_unittest_python.pdf
 
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalksSelenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
 
Effective testing with pytest
Effective testing with pytestEffective testing with pytest
Effective testing with pytest
 
Django - Know Your Namespace: Middleware
Django - Know Your Namespace: MiddlewareDjango - Know Your Namespace: Middleware
Django - Know Your Namespace: Middleware
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethods
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
Django
Django Django
Django
 
E2E testing con nightwatch.js - Drupalcamp Spain 2018
E2E testing con nightwatch.js  - Drupalcamp Spain 2018E2E testing con nightwatch.js  - Drupalcamp Spain 2018
E2E testing con nightwatch.js - Drupalcamp Spain 2018
 
How to fake_properly
How to fake_properlyHow to fake_properly
How to fake_properly
 
Testing in JavaScript
Testing in JavaScriptTesting in JavaScript
Testing in JavaScript
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testing
 
Testing for Pragmatic People
Testing for Pragmatic PeopleTesting for Pragmatic People
Testing for Pragmatic People
 
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Behind the curtain - How Django handles a request
Behind the curtain - How Django handles a requestBehind the curtain - How Django handles a request
Behind the curtain - How Django handles a request
 
Plone testingdzug tagung2010
Plone testingdzug tagung2010Plone testingdzug tagung2010
Plone testingdzug tagung2010
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
Advanced Django
Advanced DjangoAdvanced Django
Advanced Django
 

Mais de MoscowDjango

Пример fuzzy testing для поиска URL в тексте
Пример fuzzy testing для поиска URL в текстеПример fuzzy testing для поиска URL в тексте
Пример fuzzy testing для поиска URL в текстеMoscowDjango
 
TDD или как я стараюсь писать код
TDD или как я стараюсь писать кодTDD или как я стараюсь писать код
TDD или как я стараюсь писать кодMoscowDjango
 
Cyclone + Eventsource (realtime push-сообщения)
Cyclone + Eventsource (realtime push-сообщения)Cyclone + Eventsource (realtime push-сообщения)
Cyclone + Eventsource (realtime push-сообщения)MoscowDjango
 
Производительность в Django
Производительность в DjangoПроизводительность в Django
Производительность в DjangoMoscowDjango
 
Django на Android
Django на AndroidDjango на Android
Django на AndroidMoscowDjango
 
Работа со статикой в Django
Работа со статикой в DjangoРабота со статикой в Django
Работа со статикой в DjangoMoscowDjango
 
Разработка расширяемых приложений на Django
Разработка расширяемых приложений на DjangoРазработка расширяемых приложений на Django
Разработка расширяемых приложений на DjangoMoscowDjango
 
Class Based Generic Views в Django
Class Based Generic Views в DjangoClass Based Generic Views в Django
Class Based Generic Views в DjangoMoscowDjango
 
Простой и удобный деплоймент проекта
Простой и удобный деплоймент проектаПростой и удобный деплоймент проекта
Простой и удобный деплоймент проектаMoscowDjango
 
Django South. Миграция баз данных.
Django South. Миграция баз данных.  Django South. Миграция баз данных.
Django South. Миграция баз данных. MoscowDjango
 
Журнальная вёрстка в Django
Журнальная вёрстка в DjangoЖурнальная вёрстка в Django
Журнальная вёрстка в DjangoMoscowDjango
 

Mais de MoscowDjango (11)

Пример fuzzy testing для поиска URL в тексте
Пример fuzzy testing для поиска URL в текстеПример fuzzy testing для поиска URL в тексте
Пример fuzzy testing для поиска URL в тексте
 
TDD или как я стараюсь писать код
TDD или как я стараюсь писать кодTDD или как я стараюсь писать код
TDD или как я стараюсь писать код
 
Cyclone + Eventsource (realtime push-сообщения)
Cyclone + Eventsource (realtime push-сообщения)Cyclone + Eventsource (realtime push-сообщения)
Cyclone + Eventsource (realtime push-сообщения)
 
Производительность в Django
Производительность в DjangoПроизводительность в Django
Производительность в Django
 
Django на Android
Django на AndroidDjango на Android
Django на Android
 
Работа со статикой в Django
Работа со статикой в DjangoРабота со статикой в Django
Работа со статикой в Django
 
Разработка расширяемых приложений на Django
Разработка расширяемых приложений на DjangoРазработка расширяемых приложений на Django
Разработка расширяемых приложений на Django
 
Class Based Generic Views в Django
Class Based Generic Views в DjangoClass Based Generic Views в Django
Class Based Generic Views в Django
 
Простой и удобный деплоймент проекта
Простой и удобный деплоймент проектаПростой и удобный деплоймент проекта
Простой и удобный деплоймент проекта
 
Django South. Миграция баз данных.
Django South. Миграция баз данных.  Django South. Миграция баз данных.
Django South. Миграция баз данных.
 
Журнальная вёрстка в Django
Журнальная вёрстка в DjangoЖурнальная вёрстка в Django
Журнальная вёрстка в Django
 

Último

TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 

Último (20)

TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 

Тестирование и Django

  • 1. Тестирование и Django Илья Барышев @coagulant Moscow Django Meetup №6
  • 5. Пойдёт на пользу вашему проекту
  • 7.        def  test_vin_is_valid(self):                valid_vins  =  ('2G1FK1EJ7B9141175',                                            '11111111111111111',)                for  valid_vin  in  valid_vins:                        self.assertEqual(vin_validator(valid_vin),  None)        def  test_vin_is_invalid(self):                invalid_vins  =  ('abc',  u'M05C0WDJAN60M33TUP6',)                for  invalid_vin  in  invalid_vins:                        self.assertRaises(ValidationError,                              vin_validator,  invalid_vin)
  • 8. Unittest Модели Контекст-процессоры Формы Middleware Views? Template tags, filters
  • 9. Тестируйте поведение А не имплементацию
  • 11. django.test.client.Client def  testPostAsAuthenticatedUser(self):        data  =  self.getValidData(Article.objects.get(pk=1))        self.client.login(username="normaluser",                                              password="normaluser")        self.response  =  self.client.post("/post/",  data)                self.assertEqual(self.response.status_code,  302)        self.assertEqual(Comment.objects.count(),  1)
  • 12. django.test.сlient.RequestFactory def  test_post_ok(self):        request  =  RequestFactory().post(reverse('ch_location'),                                                                        {'location_id':  77})        request.cookies  =  {}        response  =  change_location(request)        self.assertEqual(response.cookies['LOCATION'].value,  '77')        self.assertEqual(response.status_code,  302)
  • 14. def  test_password_recovery_smoke(self):        """        Урлы  восстановления  пароля.        Логика  уже  протестирована  в  django-­‐password-­‐reset        """        response_recover  =  self.client.get(reverse('pass_recover'))                self.assertEqual(response_recover.status_code,  200)                self.assertContains(response_recover,                self.assertTemplateUsed(response_recover,                                                        u'Восстановление  пароля')                                                                'password_reset/recovery_form.html')
  • 17. Покрытие важно Но не делайте из него фетиш
  • 19. >>>  real  =  SomeClass() >>>  my_mock  =  MagicMock(name='method') >>>  real.method  =  my_mock >>>  real.method(3,  4,  5,  key='value') >>>  my_mock.called True >>>  my_mock.call_count 1 >>>  mock.method.assert_called_with(3,  4,  5) Traceback  (most  recent  call  last):    ... AssertionError:  Expected  call:  method(3,  4,  5) Actual  call:  method(3,  4,  5,  key='value')
  • 20. @patch('twitter.Api') def  test_twitter_tag_simple_mock(self,  ApiMock):        api_instance  =  ApiMock.return_value        api_instance.GetUserTimeline.return_value  =  SOME_JSON        output,  context  =  render_template( """{%  load  twitter_tag  %}  {%  get_tweets  for  "jresig"  as  tweets  %}""")        api_instance.GetUserTimeline.assert_called_with(                screen_name='jresig',                  include_rts=True,                  include_entities=True)
  • 21. from  mock  import  patch from  django.conf  import  settings @patch.multiple(settings,  APPEND_SLASH=True,                                MIDDLEWARE_CLASSES=(common_middleware,)) def  test_flatpage_doesnt_require_trailing_slash(self):        form  =  FlatpageForm(data=dict(url='/no_trailing_slash',                                                                      **self.form_data))        self.assertTrue(form.is_valid())
  • 22. from  django.test.utils  import  override_settings @override_settings(        APPEND_SLASH=False,          MIDDLEWARE_CLASSES=(common_middleware,) ) def  test_flatpage_doesnt_require_trailing_slash(self):        form  =  FlatpageForm(data=dict(url='/no_trailing_slash',                                                                      **self.form_data))        self.assertTrue(form.is_valid())
  • 24. [ { "model": "docs.documentrelease", "pk": 1, "fields": { "lang": "en", "version": "dev", "scm": "svn", "scm_url": "http://code.djangoproject.com/svn/django/trunk/docs", "is_default": false } }, { "model": "docs.documentrelease", Обычный тест с "pk": 2, фикстурами "fields": { "lang": "en", "version": "1.0", "scm": "svn", "scm_url": "http://code.djangoproject.com/svn/django/branches/releases/1.0.X/docs", "is_default": false } }, { "model": "docs.documentrelease", "pk": 3, "fields": { "lang": "en", "version": "1.1", "scm": "svn", "scm_url": "http://code.djangoproject.com/svn/django/branches/releases/1.1.X/docs", "is_default": false
  • 25. django-­‐any https://github.com/kmmbvnr/django-­‐any from  django_any  import  any_model class  TestMyShop(TestCase):        def  test_order_updates_user_account(self):                account  =  any_model(Account,  amount=25,                              user__is_active=True)                order  =  any_model(Order,  user=account.user,                        amount=10)                order.proceed()                account  =  Account.objects.get(pk=account.pk)                self.assertEquals(15,  account.amount)
  • 27. import  factory from  models  import  MyUser class  UserFactory(factory.Factory):        FACTORY_FOR  =  MyUser        first_name  =  'John'        last_name  =  'Doe'        admin  =  False
  • 28. #  Инстанс,  сохранённый  в  базу user  =  UserFactory.create() #  Экземпляр  User,  не  сохранённый  в  базу user  =  UserFactory.build() #  Создаём  инстанс  с  конкретыми  значениями user  =  UserFactory.create(name=u'Василий',  age=25)
  • 29. class  UserFactory(factory.Factory):        first_name  =  'Vasily'        last_name  =  'Pupkin'        email  =  factory.LazyAttribute( lambda  u:  '{0}.{1}@example.com'.format( u.first_name,  u.last_name).lower()) >>>  UserFactory().email 'vasily.pupkin@example.com'
  • 30. class  UserWithEmailFactory(UserFactory):        email  =  factory.Sequence( lambda  n:  'person{0}@example.com'.format(n)) >>>  UserFactory().email 'person0@example.com' >>>  UserFactory().email     'person1@example.com'
  • 32. INSTALLED_APPS  =  (        ...        #3rd-­‐party  apps        'south',        'sorl.thumbnail',        'pytils',        'pymorphy',                  'compressor', Несколько сотен        'django_nose', тестов        'django_geoip',        'mptt',        'widget_tweaks',        'guardian',                ...
  • 33. /tests #  -­‐*-­‐  coding:  utf-­‐8  -­‐*-­‐        __init__.py test_archive.py from  test_archive  import  *        test_blog_model.py from  test_blog_model  import  *        test_modified.py from  test_modified  import  *        test_post_model.py from  test_post_model  import  *        test_redactor.py from  test_redactor  import  *        test_views.py from  test_views  import  *        test_cross_post.py from  test_cross_post  import  *
  • 34. django-­‐nose https://github.com/jbalogh/django-­‐nose
  • 35. $  pip  install  django-­‐nose #  settings.py   INSTALLED_APPS  =  (        ...        'django_nose',        ... ) TEST_RUNNER  =  'django_nose.NoseTestSuiteRunner'
  • 36. $  manage.py  test $  manage.py  test  apps.comments.tests $  manage.py  test  apps.comments.tests:BlogTestCase $  manage.py  test  apps.comments.tests:BlogTestCase.test_index $  manage.py  test  -­‐-­‐with-­‐ids  -­‐-­‐failed $  manage.py  -­‐-­‐pdb $  manage.py  -­‐-­‐pdb-­‐failures
  • 37. from  nose.plugins.attrib  import  attr @attr(speed='slow',  priority=1) def  test_big_download():        import  urllib        #  commence  slowness.. $  nosetests  -­‐a  speed=slow $  nosetests  -­‐a  '!slow' $  nosetests  -­‐A  "(priority  >  5)  and  not  slow"
  • 39. SQLite для быстрых тестов Если ваш проект позволяет
  • 40. Параллелим тесты Нетрудоёмкое ускоение
  • 41. Ran  337  tests  in  326.664s OK  (SKIP=2) 1 процесс 326 2 процесса Секунды 169 3 процесса 126 0 100 200 300 400 $  ./manage.py  -­‐-­‐processes=N