← Back to team overview

launchpad-dev team mailing list archive

Recap: do not use hard coded url ports in tests

 

Hi

Now that Launchpad 10.11 is deployed, so too is the new testing
infrastructure to remove the need for hard coded url ports. I
accidentally specified db-devel as the target branch when doing the
merge proposal hence had to wait till the rollout. But I hear the
default Launchpad development focus is changing to devel so it won't
happen again :-)

This is part of the effort to allow parallelisation of tests. Since it
was a little while ago I sent out an explanatory email here is the
information again.

For those who don't like reading a long email, the main take away is do
not do stuff like this any more:

browser.open('http://launchpad.dev:8085/+login')

Instead:

browser.open('%s/+login' % self.layer.appserver_root_url())

Any new tests with 8085 in them and Robert will get out his big baseball
bat and come after you :-) There's a couple of places that need changing
that were done recently before the rollout. I'll change those.

Here's the original email:

As part of the effort towards full support for running parallel tests, a
branch to remove the hard coded url port (8085) for the various test
urls (eg http://launchpad.dev:8085) has been merged. You need to be
aware of the implications of the change when writing your tests. The
main issue: the correct port number is now set during the test setUp()
and is not available before then.

So here's the main viewing highlights. I've added some material to the
wiki:
http://dev.launchpad.net/TestsStyleGuide

Please let me know if there are any questions.

There's a new appserver_root_url() API call.

def appserver_root_url(self, facet='mainsite', ensureSlash=False):
"""Return the correct app server root url for the given facet."""

This is defined on the CanonicalConfig instance and as a convenience is
available as a class method on BaseLayer.

As a concrete example of how things needed to be refactored beyond
simply using the appserver_root_url() API, code like the following:

**************************************************
class CodeWindmillLayer(BaseWindmillLayer):
    """Layer for Code Windmill tests."""

    base_url = 'http://code.launchpad.dev:8085/'
**************************************************

is no longer kosher because the initialisation of the base_url must be
refactored to be done during the test setup().

Here's the main use cases you would be likely to encounter:

1. Doc tests

Old:

    >>> browser.open('http://launchpad.dev:8085/')

New:

    >>> from canonical.testing.layers import BaseLayer
    >>> root_url = BaseLayer.appserver_root_url()
    >>> browser.open(rool_url)

2. Unit tests

Old:

    def aTest(self):
        <snip>
        browser.open('http://launchpad.dev:8085/+login')

New:

    def aTest(self):
        <snip>
        browser.open('%s/+login' % self.layer.appserver_root_url())

3. Windmill tests

Old:

class BugsWindmillLayer(BaseWindmillLayer):
    """Layer for Bugs Windmill tests."""

    base_url = 'http://code.launchpad.dev:8085/'

New:

class BugsWindmillLayer(BaseWindmillLayer):
    """Layer for Bugs Windmill tests."""

    @classmethod
    def setUp(cls):
        cls.base_url = cls.appserver_root_url('bugs')
        super(BugsWindmillLayer, cls).setUp()

Old:

    def test_bug_commenting(self):
        """Test commenting on bugs."""
        client = self.client
        lpuser.NO_PRIV.ensure_login(client)

        client.open(url='http://bugs.launchpad.dev:8085/bugs/1')
New:

    def test_bug_commenting(self):
        """Test commenting on bugs."""
        client = self.client
        lpuser.NO_PRIV.ensure_login(client)

        client.open(url='%s/bugs/1' % BugsWindmillLayer.base_url)



Follow ups