{ "info": { "author": "Saul Shanabrook", "author_email": "s.shanabrook@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Framework :: Django", "Framework :: Django :: 1.8", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5" ], "description": "# `django-externaltestserver`\n[![PyPI Version](https://img.shields.io/pypi/v/https://pypi.python.org/pypi/django-externaltestserver.svg?style=flat-square)![PyPI Python Versions](https://img.shields.io/pypi/pyversions/django-externaltestserver.svg?style=flat-square)](https://pypi.python.org/pypi/django-externaltestserver)\n[![Travis branch](https://img.shields.io/travis/saulshanabrook/django-externaltestserver/master.svg?style=flat-square)](https://travis-ci.org/saulshanabrook/django-externaltestserver)\n\n\n\n- [How?][how]\n- [Why?][why]\n - [External Server][external-server]\n - [Docker][docker]\n - [Problem][problem]\n - [Solution][solution]\n- [Development][development]\n\n\n\n\n## How?\n1. `pip install django-externaltestserver`.\n2. Set `EXTERNAL_TEST_SERVER` in your settings\n3. Change test cases to inherit from\n `externaltestserver.ExternalLiveServerTestCase` instead of\n `LiveServerTestCase`.\n4. (optional) Add `externaltestserver` to `INSTALLED_APPS` to run\n `python manage.py testserver [--static]` in another process.\n\n## Why?\n\n### External Server\nWe have a CI system that pushes to a staging server after all tests pass.\nWe wanted to re-run our selenium test against the staging server, to make\nsure there are no regressions moving from a dev to a staging environment.\n\nTo do this, we just have to set the `EXTERNAL_TEST_SERVER`\nsetting to our staging server (like `http://magicapp-staging.herokuapp.com/`)\nand make sure our integration tests inherit from `externaltestserver.ExternalLiveServerTestCase`\nso that they get the correct `live_server_url`.\n\n\n### Docker\n\n#### Problem\n\nTesting Selenium in Django with Docker is\n[not obvious](http://stackoverflow.com/questions/32408429/running-django-tests-with-selenium-in-docker).\n\nThe problem is that there is a circular dependency between the testing\ncontainer and the selenium container. The test container needs to access\nselenium in order to send commands and recieve responses. The selenium\ncontainer needs to access the testing container, in order to hit the server.\n\n![diagram of old process](./images/old.jpg)\n\nWe might hope we could represent this relation this in our `docker-compose.yml`\n\n```yaml\ndb:\n image: postgres\ntest:\n build: .\n command: python manage.py test\n links:\n - db\n - selenium\nselenium:\n image: selenium/standalone-chrome\n ports:\n - \"4444:4444\"\n - \"5900:5900\"\n links:\n - test\n```\n\nBut alas `ERROR: Circular import between test and selenium and db`.\n\nI was previously using\n[an alternative solution](https://github.com/docker/compose/issues/1991#issuecomment-138139493),\nby placing the the `test` container in the same network as the `selenium`\ncontainer, so that they could access each other.\n\n\n```yaml\ndb:\n image: postgres\ntest:\n build: .\n command: python manage.py test\n links:\n - db\n net: \"container:selenium\"\nselenium:\n image: selenium/standalone-chrome\n ports:\n - \"4444:4444\"\n - \"5900:5900\"\n```\n\nThis stopped working with Docker Compose 1.5.0 / Docker 1.9.0 with\n`ERROR: Conflicting options: --net=container can't be used with links. This would result in undefined behavior`.\n\n#### Solution\n\nThe simplist solution to me seemed to be to break up the test command into\ntwo seperate Docker containers. One would handle serving the server, the other\nwould just run the tests.\n\n![diagram of new process](./images/new.jpg)\n\nThat way there are no cyclical dependencies.\n\n```yaml\ndb:\n image: postgres:9.5\ntest:\n build: .\n # sleep for https://github.com/docker/compose/issues/374#issuecomment-156546513\n command: bash -c \"sleep 5; python manage.py test --keepdb\"\n links:\n - db\n - selenium\n environment:\n - EXTERNAL_TEST_SERVER=http://testserver:8000/\n - SELENIUM_HOST=http://selenium:4444/wd/hub\nselenium:\n image: selenium/standalone-chrome:2.48.2\n links:\n - testserver\ntestserver:\n build: .\n # sleep for https://github.com/docker/compose/issues/374#issuecomment-156546513\n command: bash -c \"sleep 5; python manage.py testserver 8000 --static\"\n expose:\n - \"8000\"\n links:\n - db\n\n```\n\nThen just make sure we are picking up the host in the settings:\n\n```python\n# settings.py\nimport os\n\nEXTERNAL_TEST_SERVER = os.environ.get('EXTERNAL_TEST_SERVER', None)\n```\n\nAnd that your tests are inheriting from `externaltestserver.ExternalLiveServerTestCase`\nand accesing the right selenium server:\n\n```python\n# test_integration.py\nimport os\n\nfrom selenium import webdriver\nfrom selenium.webdriver.common.desired_capabilities import DesiredCapabilities\nfrom externaltestserver import ExternalLiveServerTestCase\n\nfrom items.models import Item\n\n\nclass IntegrationTest(ExternalLiveServerTestCase):\n def setUp(self):\n self.browser = webdriver.Remote(\n command_executor=os.environ['SELENIUM_HOST'],\n desired_capabilities=DesiredCapabilities.CHROME\n )\n\n def test_item_count(self):\n Item.objects.create()\n self.browser.get(self.live_server_url)\n self.assertIn(\"1\", self.browser.page_source)\n```\n\nThen you can run all the tests with `docker-compose run test`.\n\n\n## Development\n\nFirst choose what python and django versions you wanna test on:\n\n```bash\nsed -e 's/${PYTHON_VERSION}/3.5/g' -e 's/${DJANGO_VERSION}/1.8/g' Dockerfile.tmpl > Dockerfile\n```\n\nThen run the tests:\n\n```bash\ndocker-compose run test\n```\n\n\nTo deploy a new version:\n\n```\npython setup.py publish\ngit tag \ngit push --tags\n```", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/saulshanabrook/django-externaltestserver", "keywords": null, "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "externaltestserver", "package_url": "https://pypi.org/project/externaltestserver/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/externaltestserver/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/saulshanabrook/django-externaltestserver" }, "release_url": "https://pypi.org/project/externaltestserver/0.0.0/", "requires_dist": null, "requires_python": null, "summary": "Run your Django selenium tests against an external server", "version": "0.0.0" }, "last_serial": 1816641, "releases": { "0.0.0": [] }, "urls": [] }