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

Testing Django Applications

Testing Django Applications

Iacopo Spalletti

September 20, 2015
Tweet

More Decks by Iacopo Spalletti

Other Decks in Programming

Transcript

  1. WHO AM I? Founder and Lead developer @NephilaIt django CMS

    core developer django CMS installer author
  2. DJANGOCMS-HELPER An addon to help writing testcases Not a replacement

    for unittest, nose or py.test Does not require django CMS
  3. HOW DO I USE IT? THE HELPER FILE HELPER_SETTINGS =

    dict( INSTALLED_APPS=[ ... 'myapp' ] ... ) def run(): from djangocms_helper import runner runner.cms('myapp') if __name__ == '__main__': run()
  4. THE HELPER FILE HOW DOES IT WORK? Add the settings

    needed by your application + Execute the runner
  5. THE HELPER FILER HOW DOES IT WORK? 1. Merge app

    settings with default ones 2. Setup Django 3. Execute the Django commands
  6. THE HELPER FILE SETTINGS MAGIC djangocms-helper knows a few things:

    South / Django migrations Django 1.8 TEMPLATE settings Depedencies and custom configurations for django CMS
  7. HOW DO I USE IT? EXECUTING THE HELPER (page-meta)yakky@andalu: ~/myapp

    $ python cms_helper.py Creating test database for alias 'default'... ........... ------------------------------------------------------- Ran 11 tests in 8.668s OK Destroying test database for alias 'default'... Without arguments it just runs the tests
  8. HOW DO I USE IT? EXECUTING THE HELPER Plus built-in

    commands: server: execute the bundled project so you can interact with it makemigrations: generates migrations (both south and django) compilemessages / makemessages ... any command ... (through call_command)
  9. HOW DO I USE IT? MOCK HELPERS Generating Request object

    is tedious and error-prone By default no useful attributes like cookies, session, user etc
  10. MOCK HELPERS CREATING A REQUEST In [1]: request = self.get_request(

    page=some_page, lang='en', user=some_user, path='/en/', use_middlewares=True ) In [2]: request.COOKIES {} In [3]: request.session <django.contrib.sessions.backends.cache.SessionStore ...> In [4]: request.current_page <SimpleLazyObject: <function CurrentPageMiddleware ...>> In [5]: request.user <SimpleLazyObject: <django.contrib.auth.models.User ...>> In [6]: request._messages <django.contrib.messages.storage.fallback.FallbackStorage ...>
  11. MOCK HELPERS DJANGO CMS PLUGINS Rendering django CMS plugins in

    tests is not straightforward Shortcuts to easily test plugin rendering BaseTestCase.get_plugin_context BaseTestCase.render_plugin
  12. MOCK HELPERS DJANGO CMS PLUGINS Like this context = self.get_plugin_context(page,

    'en', plugin, edit=True) # Render a single plugin rendered_1 = plugin.render_plugin(context, placeholder) # Render a whole placeholder rendered_2 = render_placeholder( placeholder, context, editable=True ) # Render the plugin - Same as rendered_1 but in one pass rendered_3 = self.render_plugin(page, 'en', plugin, edit=True)
  13. MOCK HELPERS DJANGO CMS APPHOOKS Helpers to load apphooks during

    tests: app_page = api.create_page( 'page', 'project.html', 'en', published=True, apphook='MyApp', ) app_page.publish('en') self.reload_urlconf() Call BaseTestCase.reload_urlconf after adding an Apphook
  14. MOCK HELPERS USER LOGINS [...] with self.login_user_context(self.user): # this request

    is made with self.user logged in self.client.get([...]) with self.login_user_context(self.user_staff): # this request is made with self.user_staff logged in self.client.get([...]) BaseTestCase.login_user_context: context manager for authenticated sessions
  15. HOW DO I USE IT? CREATING DATA Lots of way

    of preparing test data: static fixtures custom code data generator (factory-boy et al.) Sometimes they does not fit
  16. CREATING DATA DJANGO CMS PAGES class MyTestCase(BaseTestCase): _pages_data = (

    {'en': {'title': 'page one', 'template': 'page_meta.html', 'publish': True}, 'fr_FR': {'title': 'page un', 'publish': True}, 'it': {'title': 'pagina uno', 'publish': True}}, {'en': {'title': 'page two', 'template': 'page_meta.html', 'publish': True}, 'fr_FR': {'title': 'page deux', 'publish': True}, 'it': {'title': 'pagina due', 'publish': True}}, ) ... def test_method(self): pages = self.get_pages() Built on top of django CMS API
  17. CREATING DATA DJANGO CMS PAGES Supports 'complex' arguments: parent: using

    the slug of the parent page apphook: reloads the urlconf if any is provided
  18. CREATING DATA USERS self.user = self.create_user( 'admin', '[email protected]', 'admin', is_staff=True,

    is_superuser=True, base_cms_permissions=True, permissions=('add_something',) ) BaseTestCase.create_user knows about custom user models An admin, a staff and a normal user are provided by default in setUpClass
  19. CREATING DATA IMAGES Django does not provide any quick way

    to create images in tests dangocms-helper does: create_image create_django_image_object create_filer_image_object
  20. CREATING DATA IMAGES In [1]: self.create_image() <PIL.Image.Image image mode=RGB size=800x600

    at 0x7F03382C5320> In [2]: self.create_django_image_object() <File: test_file.jpg> In [3]: self.create_filer_image_object() <Image: test_file.jpg>