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

Automated Testing: Philosophy & Tools

Automated Testing: Philosophy & Tools

A rundown of the benefits of automated testing and how to practically do it with tox and travis.

Avatar for Stephen Burrows

Stephen Burrows

June 25, 2013
Tweet

Other Decks in Programming

Transcript

  1. I won’t cover • Jenkins • pip and virtualenv •

    deployment • python 3 compatibility
  2. The ideal • Test with every supported python version •

    Test with every database/search backend • Test with every supported dependency version • Test every possible combination
  3. Without automation ~Test with every supported python version ⨉Test with

    every database/search backend ~Test with every supported dependency version ⨉Test every possible combination
  4. With automation ✓Test with every supported python version ~Test with

    every database/search backend ~Test with every supported dependency version ~Test every possible combination
  5. Package layout django-daguerre/ .travis.yml AUTHORS LICENSE MANIFEST.in setup.py tox.ini daguerre/

    docs/ test_project/ requirements-1.4.txt requirements-1.5.txt manage.py test_project/
  6. Test project django-daguerre/ .travis.yml AUTHORS LICENSE MANIFEST.in setup.py tox.ini daguerre/

    docs/ test_project/ requirements-1.4.txt requirements-1.5.txt manage.py test_project/
  7. Requirements files django-daguerre/ .travis.yml AUTHORS LICENSE MANIFEST.in setup.py tox.ini daguerre/

    docs/ test_project/ requirements-1.4.txt requirements-1.5.txt manage.py test_project/
  8. ⨉ No django-nose south mock six Pillow Pillow>2.0.0 django<1.5 -e

    git+https://github.com/jbalogh/django-nose.git@ master#egg=django-nose south>0.8 mock six
  9. tox: local testing django-daguerre/ .travis.yml AUTHORS LICENSE MANIFEST.in setup.py tox.ini

    daguerre/ docs/ test_project/ requirements-1.4.txt requirements-1.5.txt manage.py test_project/
  10. • Isolated virtual environments • Multiple versions of python •

    Local == pre-commit • .../django-daguerre$ tox
  11. tox.ini (basic) [tox] envlist = py26, py27, py33 [testenv] changedir

    = {toxinidir}/test_project deps = --no-deps --use-mirrors -r{toxinidir}/test_project/requirements-1.4.txt commands = {envpython} manage.py test daguerre
  12. tox.ini (matrix) [tox] envlist = py26-django14, py27-django14, py26-django15, py27-django15, [testenv]

    changedir = {toxinidir}/test_project commands = {envpython} manage.py test daguerre # Continued
  13. tox.ini (matrix) [testenv:py26-django14] basepython=python2.6 deps = --no-deps --use-mirrors -r{toxinidir}/test_project/requirements-1.4.txt [testenv:py27-django14]

    basepython=python2.7 deps = --no-deps --use-mirrors -r{toxinidir}/test_project/requirements-1.4.txt [testenv:py26-django15] basepython=python2.6 deps = --no-deps --use-mirrors -r{toxinidir}/test_project/requirements-1.5.txt [testenv:py27-django15] basepython=python2.7 deps = --no-deps --use-mirrors -r{toxinidir}/test_project/requirements-1.5.txt
  14. travis-ci: remote testing django-daguerre/ .travis.yml AUTHORS LICENSE MANIFEST.in setup.py tox.ini

    daguerre/ docs/ test_project/ requirements-1.4.txt requirements-1.5.txt manage.py test_project/
  15. • Isolated virtual environments • Multiple versions of python •

    Good matrix support • Built-in support for MySQL, PostgreSQL, Elasticsearch, Redis, and more • Remote == post-push • Integration for public Github repos only
  16. .travis.yml (basic) language: python python: - "2.6" - "2.7" -

    "3.3" install: - pip install . --no-deps - pip install --use-mirrors --no-deps -r test_project/requirements-1.5.txt script: - cd test_project - ./manage.py test --verbosity=2 daguerre
  17. tox.ini (basic) [tox] envlist = py26, py27, py33 [testenv] changedir

    = {toxinidir}/test_project deps = --no-deps --use-mirrors -r{toxinidir}/test_project/requirements-1.4.txt commands = {envpython} manage.py test daguerre
  18. .travis.yml (matrix) language: python python: - "2.6" - "2.7" -

    "3.3" env: - REQUIREMENTS=test_project/requirements-1.4.txt - REQUIREMENTS=test_project/requirements-1.5.txt matrix: exclude: - python: "3.3" env: REQUIREMENTS=test_project/requirements-1.4.txt install: - pip install . --no-deps - pip install --use-mirrors --no-deps -r $REQUIREMENTS script: - cd test_project - ./manage.py test --verbosity=2 daguerre
  19. tox.ini (matrix) [tox] envlist = py26-django14, py27-django14, py26-django15, py27-django15, [testenv]

    changedir = {toxinidir}/test_project commands = {envpython} manage.py test daguerre # Continued
  20. tox.ini (matrix) [testenv:py26-django14] basepython=python2.6 deps = --no-deps --use-mirrors -r{toxinidir}/test_project/requirements-1.4.txt [testenv:py27-django14]

    basepython=python2.7 deps = --no-deps --use-mirrors -r{toxinidir}/test_project/requirements-1.4.txt [testenv:py26-django15] basepython=python2.6 deps = --no-deps --use-mirrors -r{toxinidir}/test_project/requirements-1.5.txt [testenv:py27-django15] basepython=python2.7 deps = --no-deps --use-mirrors -r{toxinidir}/test_project/requirements-1.5.txt
  21. .travis.yml (matrix 2) language: python python: - "2.6" - "2.7"

    - "3.3" env: - DB=sqlite3 REQUIREMENTS=test_project/requirements-1.4.txt - DB=mysql REQUIREMENTS=test_project/requirements-1.4.txt - DB=sqlite3 REQUIREMENTS=test_project/requirements-1.5.txt - DB=mysql REQUIREMENTS=test_project/requirements-1.5.txt matrix: exclude: - python: "3.3" env: DB=sqlite3 REQUIREMENTS=test_project/requirements-1.4.txt - python: "3.3" env: DB=mysql REQUIREMENTS=test_project/requirements-1.4.txt - python: "3.3" env: DB=mysql REQUIREMENTS=test_project/requirements-1.5.txt install: - pip install . --no-deps - pip install --use-mirrors --no-deps -r $REQUIREMENTS - if [ $DB == 'mysql' ]; then pip install --use-mirrors --no-deps mysql-python; fi before_script: - if [ $DB == 'mysql' ]; then mysql -e 'CREATE DATABASE daguerre_test;'; fi script: - cd test_project - ./manage.py test --verbosity=2 daguerre
  22. (in settings.py) import os DB = os.environ.get('DB') if DB ==

    'mysql': DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'daguerre_test', 'USER': 'root', 'TEST_CHARSET': 'utf8', 'TEST_COLLATION': 'utf8_general_ci', } } else: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(PROJECT_DIR, 'db.sl3'), } }
  23. Summary (tox) • Multiple versions of python: trivial • Two-dimensional

    matrix: work, but possible • For example, multiple versions of django • Higher-dimensional matrix: not really feasible • For example multiple versions of django and multiple database settings
  24. Summary (travis) • Multiple versions of python: trivial • Two-dimensional

    matrix: simple • For example, multiple versions of django • Higher-dimensional matrix: work, but possible • For example multiple versions of django and multiple database settings