Skip to content

Latest commit

 

History

History
149 lines (101 loc) · 4.64 KB

speedily_practical_large_scale_tests.rst

File metadata and controls

149 lines (101 loc) · 4.64 KB

Speedily Practical Large-Scale Tests with Erik Rose from Votizen

Presenter: Erik Rose (https://github.com/erikrose) (@ErikRose)

PyCon 2012 presentation page: https://us.pycon.org/2012/schedule/presentation/473/

Slides (Keynote): https://github.com/downloads/erikrose/presentations/Speedily%20Practical%20Large-Scale%20Tests.key

Slides (HTML): http://erikrose.github.com/presentations/speedily-practical-large-scale-tests/

Video: http://pyvideo.org/video/634/speedily-practical-large-scale-tests

iStat menus for the Mac so you know your baseline memory usage, disk activity, etc.

The Python profiler doesn't tell you about I/O; only CPU. You can use the UNIX time command to look at wall clock time and CPU time and then do subtraction to get an idea of I/O time. top, lsof

Conquest of Speed parts:

  1. Per-class fixture loading
  2. Fixture bundling
  3. Startup Speedups

Got tests form 302 seconds down to 62 seconds.

Nose

  • Finding and picking tests
  • dealing with errors
  • etc.

django-nose 1.0 will be released soon (Note: it's out - see PyPI) and Erik Rose will be sprinting on it on Monday.

Die, setUp(), die

More explicit test setup. Can be more efficient because you're not setting up stuff you don't need.

Die, fixtures, die

"model makers" -- d = document(title='test')

with_save decorator

factory_boy for Python - based on thoughtbot's factory_girl for Rails

Shared setup makes tests...

  • Coupled to each other
  • Brittle
  • Hard to understand
  • Slow
  • Kick puppies

Local setup gives you...

  • Decoupling
  • Robustness
  • Clarity
  • Efficiency
  • Puppy kisses

Imperative vs. declarative

The Mock Library:

from mock import patch

with patch.object(APIVoterManager, '_raw_voters') as voters:
    ....

The Fudge Library:

@fudge.patch('sphinxapi.SphinxClient')
def test_single_filter(sphinx_client):
    ....
    (sphinx_client.expects_call().returns_fake()
        .is_a_stub()
        .expects('SetFilter').with_args('a', [1], False)
        .expects('SetFilter')....
    ....

Horrible dots - They don't tell you anything

Hate tracebacks - too much noise

Erik Rose put together an alternative nose test runner called nose-progressive:

% nosetests --with-progressive
  • displays a progress bar instead of dots so you know how long tests might take
  • much abbreviated tracebacks
  • editor shortcuts with the + syntax for line numbers that you can copy and paste to edit the file

If you just want the improved tracebacks, check out tracefront which is Erik Rose's extraction of the traceback stuff from nose-progressive.

How to install testing goodness:

pip install nose-progressive
pip install django-nose

zope.testing package is pretty well-decoupled from the rest of Zope and easy to use with non-zope stuff. Also Twisted's Trial test runner - someone noted that it's nice but it doesn't work with Django because Django is broken and wanted to sprint on it.

David Cramer of Disqus --nose-bleed and nose-quickunit

Someone mentioned that it's nice to set up editor keybindings that run the tests for just the file you're editing. Another way is to have something like autonose that automatically runs your tests for you.

MySQL sucks at everything; wants to switch to Postgres at Votizen.