Merge lp://staging/~gary/launchpad/yuixhr into lp://staging/launchpad

Proposed by Gary Poster
Status: Merged
Approved by: Gary Poster
Approved revision: no longer in the source branch.
Merged at revision: 14015
Proposed branch: lp://staging/~gary/launchpad/yuixhr
Merge into: lp://staging/launchpad
Diff against target: 1888 lines (+1470/-65)
18 files modified
Makefile (+15/-11)
configs/testrunner-appserver/yuitest.zcml (+2/-2)
configs/testrunner/yuitest.zcml (+16/-0)
lib/canonical/launchpad/scripts/runlaunchpad.py (+62/-6)
lib/canonical/testing/ftests/test_layers.py (+4/-4)
lib/canonical/testing/layers.py (+36/-10)
lib/lp/app/javascript/server_fixture.js (+65/-0)
lib/lp/testing/__init__.py (+23/-10)
lib/lp/testing/_login.py (+12/-7)
lib/lp/testing/tests/test_login.py (+14/-1)
lib/lp/testing/tests/test_standard_yuixhr_test_template.js (+64/-0)
lib/lp/testing/tests/test_standard_yuixhr_test_template.py (+154/-0)
lib/lp/testing/tests/test_yuixhr.py (+391/-0)
lib/lp/testing/tests/test_yuixhr_fixture.js (+175/-0)
lib/lp/testing/tests/test_yuixhr_fixture.py (+102/-0)
lib/lp/testing/views.py (+0/-12)
lib/lp/testing/yuixhr.py (+331/-0)
setup.py (+4/-2)
To merge this branch: bzr merge lp://staging/~gary/launchpad/yuixhr
Reviewer Review Type Date Requested Status
Deryck Hodge (community) code Approve
Review via email: mp+76315@code.staging.launchpad.net

Commit message

[r=deryck][bug=724609][no-qa][incr] Add the ability to write app integration tests with YUI.

Description of the change

[This is a very big branch of work started back in the Dublin sprint. I will be looking for a reviewer from the group who worked on it then, assuming I do not get someone else willing to tackle something of this size for a lark. I thought of ways to divide it, but the majority of it is of a piece, and I decided it would be better to get a full review. I'm happy to talk about the division possibilities if you disagree, or even if you wonder about it.]

This branch adds the ability to write Javascript integration tests: YUI unit tests that have a full appserver ready behind it. These should be used sparingly and carefully. The majority of our Javascript tests should continue to be in the pre-existing Javascript-only layer. However, this fills a real need. These sort of tests are intended to replace any need for our old Windmill tests. Selenium tests may be added in the future but only as a way to write acceptance tests.

I suggest starting with the two files lib/lp/testing/tests/test_standard_yuixhr_test_template.js and lib/lp/testing/tests/test_standard_yuixhr_test_template.py. These are also exposed at the top of the tree, via symlink, as exemplars (standard_yuixhr_test_template.js and standard_yuixhr_test_template.py). They are supposed to show how to write these tests, and generally show their capabilities. I considered whether these files should be smaller, with the information within them moved to the wiki. I decided I preferred this approach, but would be happy to discuss alternates. In any case, reading these files should give you an idea of how this branch is supposed to work.

You can run the existing tests in the new layer with
  xvfb-run ./bin/test -vvc --layer=YUIAppServerLayer

You can run them interactively by running "make run-testapp", waiting about 20 seconds (note that there is no warning on the console when it is ready; just retry in the browser) and then visiting http://launchpad.dev:8085/+yuitest/lp/testing/tests/test_standard_yuixhr_test_template and http://launchpad.dev:8085/+yuitest/lp/testing/tests/test_yuixhr_fixture .

The other major new tests of functionality can be run with
   ./bin/test -vvc lp.testing.tests.test_yuixhr TestYUITestFixtureController

The people who worked on this were myself, Francis, Curtis, and Deryck, with an initial assist from Steven. I'll count them as my "pre-imp call".

== Commentary ==

I'll now provide commentary on the rest of the files that I think could use discussion.

yuixhr.py and test_yuixhr.py are the heart of the matter. I've/we've tried to comment and name them sufficiently. The use of the special response object to reset the database outside of transactions is the trickiest aspect of it.

Some of the yuixhr functionality was easier to test in the tests of the Javascript integration itself. These, along with the tests for the YUI module hookup server_fixture.js, can be found in the linked pair of test_yuixhr_fixture.js and test_yuixhr_fixture.py.

Everything else is supporting material of one sort or another.

The two yuitest.zcml files add the +yuitest view that enables these tests. They are added only for tests or "make run-testapp", not for normal devel or any production.

The Makefile changes add a "run-testapp" target that we can use to run yuixhr tests interactively.

runlaunchpad.py contains the code used to actually start the app server for running the tests in the test suite and interactively. I intend for the comments to be sufficient, so I'll leave them to speak for themselves. This represents a fair amount of tweaking to find a relatively clean approach to the problem; I'll talk about alternatives I tried and considered if requested. I was reasonably pleased with the end result and hope you are. setup.py exposes this target for the test suite and the interactive "run-testapp" target.

The layers.py has one of a very few fly-by fixes: when you run some tests on layers that did not set up an LP_TEST_INSTANCE, the layer teardown would complain unnecessarily. This would only affect isolated test runs, not a full test run. I cleaned up that complaint. It also includes the YUIAppServerLayer. I initially did this more like the existing appserver layer, with creating the database and librarian in the parent process. Comments in runlaunchpad.py hint at why I moved away from this approach; again, I can go in depth if requested.

The changes to lib/lp/testing/__init__.py take Curtis' work to run a browser for our normal Javascript tests and adjust it so that I can use it for these tests as well. I initially expected to follow even more of his patterns--generating a test suite on the fly--but because these tests have .py files, the .py files are the natural places to hook things up for the test suite. Doing otherwise has problems, which I can, again, discuss further if desired.

test_login.py and _login.py make it possible to have nested logins when using factories, which can be important for situations in which you want the browser logged in as one person but a factory working as another. This change could be proposed separately, but it was such a drop in the bucket that I didn't really see the point.

I may have missed something in this description, but that's at least a broad-brush introduction.

== Lint ==

Unfortunately, make lint is not entirely happy, but I've fixed everything I agree with it. Here's what's left, with commentary.

./Makefile
     273: Line exceeds 78 characters.

This existed before I came along and doesn't have anything to do with my changes.

./standard_yuixhr_test_template.py
     103: redefinition of function 'example' from line 39
     102: E302 expected 2 blank lines, found 0

This is because of the way the decorators work--which follows the @x.setter property pattern (http://docs.python.org/library/functions.html#property).

./lib/lp/testing/yuixhr.py
     288: local variable '__traceback_info__' is assigned to but never used

This is information in the frame for traceback rendering as done by zope.exceptions and lp.services.stacktrace. If something goes wrong, you can know what the data object looked like at the time and which fixture was running.

./lib/lp/testing/tests/test_login.py
     279: E301 expected 1 blank line, found 0
     288: E301 expected 1 blank line, found 0

These are for example functions defined within a method. I believe they existed before I came along, and I don't have a problem with them as is, so I left them.

./lib/lp/testing/tests/test_standard_yuixhr_test_template.py
     103: redefinition of function 'example' from line 39
     102: E302 expected 2 blank lines, found 0

This is actually the same file (symlinked) as ./standard_yuixhr_test_template.py, discussed above.

./lib/lp/testing/tests/test_yuixhr_fixture.py
      32: redefinition of function 'baseline' from line 27
      41: redefinition of function 'second' from line 38
      54: redefinition of function 'faux_database_thing' from line 49
      63: redefinition of function 'show_teardown_value' from line 60
      91: redefinition of function 'teardown_will_fail' from line 88
      40: E302 expected 2 blank lines, found 0
      53: E302 expected 2 blank lines, found 0
      62: E302 expected 2 blank lines, found 0
      90: E302 expected 2 blank lines, found 0

These are all examples of the same problem discussed in ./standard_yuixhr_test_template.py.

Thank you!

Gary

To post a comment you must log in.
Revision history for this message
Deryck Hodge (deryck) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
The diff is not available at this time. You can reload the page or download it.