Introducing integration tests
authorAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Tue, 2 Apr 2013 07:36:13 +0000 (09:36 +0200)
committerAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Tue, 2 Apr 2013 07:36:13 +0000 (09:36 +0200)
$ TEST_BROWSER=Chrome python redakcja/manage.py test --settings settings.selenium tests/integration/

.gitignore
redakcja/settings/integration_test.py [new file with mode: 0644]
tests/__init__.py [new file with mode: 0644]
tests/integration/__init__.py [new file with mode: 0644]
tests/integration/base.py [new file with mode: 0644]
tests/integration/smoke_test.py [new file with mode: 0644]

index 866239a..318e02d 100644 (file)
@@ -30,4 +30,7 @@ nbproject/*
 .pydevproject
 .settings
 
-node_modules
\ No newline at end of file
+node_modules
+
+/static_test
+chromedriver.log
\ No newline at end of file
diff --git a/redakcja/settings/integration_test.py b/redakcja/settings/integration_test.py
new file mode 100644 (file)
index 0000000..ba477bb
--- /dev/null
@@ -0,0 +1,7 @@
+from redakcja.settings.test import *
+
+NOSE_ARGS = ()
+
+STATIC_ROOT_SYMLINK = os.path.dirname(STATIC_ROOT) + '_test'
+STATICFILES_DIRS.append(STATIC_ROOT_SYMLINK)
+
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py
new file mode 100644 (file)
index 0000000..5c572ea
--- /dev/null
@@ -0,0 +1,5 @@
+import os\r
+from django.conf import settings\r
+\r
+if not os.path.exists(settings.STATIC_ROOT_SYMLINK):\r
+    os.symlink(settings.STATIC_ROOT, settings.STATIC_ROOT_SYMLINK)
\ No newline at end of file
diff --git a/tests/integration/base.py b/tests/integration/base.py
new file mode 100644 (file)
index 0000000..c2774c9
--- /dev/null
@@ -0,0 +1,125 @@
+import os\r
+import inspect\r
+from urlparse import urlparse\r
+\r
+from django.test import LiveServerTestCase\r
+from django.test.client import Client\r
+from django.conf import settings\r
+from django.contrib.auth.models import User, Permission\r
+from django.utils.translation import ugettext as _\r
+\r
+from selenium import webdriver, selenium\r
+from selenium.webdriver.support.wait import WebDriverWait\r
+\r
+\r
+class SeleniumTestCase(LiveServerTestCase):\r
+\r
+    @classmethod\r
+    def setUpClass(cls):\r
+        LiveServerTestCase.setUpClass()\r
+        cls.browser = getattr(webdriver, os.environ.get('TEST_BROWSER', 'Firefox'))()\r
+        cls.browser.implicitly_wait(5)\r
+        \r
+    @classmethod\r
+    def tearDownClass(cls):\r
+        LiveServerTestCase.tearDownClass()\r
+        cls.browser.quit()\r
+        \r
+    def setUp(self):\r
+        self.browser.delete_all_cookies()\r
+    \r
+    def create_user(self, username = 'testuser',  passwd = 'passwd', do_login = False):\r
+        user = User.objects.create_user(username, '', passwd)\r
+        user._plain_passwd = passwd\r
+        if do_login:\r
+            self.login_user(user)\r
+        return user\r
+    \r
+    def create_super_user(self, *args, **kwargs):\r
+        user = self.create_user(*args, **kwargs)\r
+        user.is_superuser = True\r
+        user.save()\r
+        return user\r
+        \r
+    def login_user(self, user):\r
+        client = Client()\r
+        client.login(username = user.username, password = user._plain_passwd)\r
+\r
+        if not self.browser.current_url.startswith(self.live_server_url):\r
+            self.browser.get(self.live_server_url+'/not_existing_url')\r
+            \r
+        self.browser.find_element_by_tag_name('body') # Make sure the page is actually loaded before setting the cookie\r
+        self.browser.delete_cookie(settings.SESSION_COOKIE_NAME)\r
+        self.browser.add_cookie(dict(name = settings.SESSION_COOKIE_NAME, \r
+                                     value = client.cookies[settings.SESSION_COOKIE_NAME].value,\r
+                                     path = '/')\r
+                               )\r
+        \r
+    def get_main_page(self):\r
+        self.browser.get(self.live_server_url)\r
+        self.browser.find_element_by_tag_name('body')\r
+        return MainPage(self.browser)\r
+\r
+        \r
+class Page(object):\r
+    def __init__(self, browser):\r
+        self.browser = browser\r
+    \r
+    \r
+class MainPage(Page):\r
+\r
+    def __init__(self, browser):\r
+        Page.__init__(self, browser)\r
+        self.tab = None\r
+    \r
+    @property\r
+    def element(self):\r
+        return self.browser.find_element_by_tag_name('body')\r
+    \r
+    def select_tab(self, tab_title):\r
+        for a in self.element.find_element_by_id('tabs-nav-left').find_elements_by_tag_name('a'):\r
+            if a.text == tab_title:\r
+                a.click()\r
+                self.tab = find_tab_class(tab_title)(self.browser)\r
+                return\r
+        raise Exception, 'Tab not found'\r
+        \r
+                \r
+def find_tab_class(tab_title):       \r
+    for obj in globals().values():\r
+        if inspect.isclass(obj) and issubclass(obj, MainPageTabBase) and getattr(obj, 'tab_title', None) == tab_title:\r
+            return obj\r
+    raise NotImplementedError\r
+                \r
+\r
+class MainPageTabBase(Page):\r
+    def __init__(self, browser):\r
+        Page.__init__(self, browser)\r
+    \r
+    @property\r
+    def element(self):\r
+        return self.browser.find_element_by_id('content')\r
+        \r
+\r
+class AddBookPage(MainPageTabBase):\r
+    tab_title = _('Add')\r
+    \r
+    def put_title(self, title):\r
+        self.element.find_element_by_id('id_title').send_keys(title)\r
+        \r
+    def put_text(self, text):\r
+        self.element.find_element_by_id('id_text').send_keys(text)\r
+        \r
+    def submit(self):\r
+        self.browser.find_element_by_css_selector('table.editable button').click()\r
+        return self.browser\r
+        \r
+    \r
+class BooksListPage(MainPageTabBase):\r
+    tab_title = _('All')\r
+    \r
+    @property\r
+    def visible_books_count(self):\r
+        return len(self.element.find_element_by_id('file-list').find_elements_by_tag_name('tr')) - 2\r
+        \r
+        
\ No newline at end of file
diff --git a/tests/integration/smoke_test.py b/tests/integration/smoke_test.py
new file mode 100644 (file)
index 0000000..fb29a73
--- /dev/null
@@ -0,0 +1,18 @@
+from tests.integration.base import SeleniumTestCase, MainPage, _\r
+\r
+class SmokeTest(SeleniumTestCase):\r
+\r
+    def test_add_book(self):\r
+        user = self.create_super_user(do_login = True)\r
+        \r
+        page = self.get_main_page()\r
+        page.select_tab(_('All'))\r
+        assert page.tab.visible_books_count == 0\r
+        \r
+        page.select_tab(_('Add'))\r
+        page.tab.put_title('Test title')\r
+        page.tab.put_text('Test text')\r
+        page.tab.submit()\r
+        page.select_tab(_('All'))\r
+        assert page.tab.visible_books_count == 1\r
+        
\ No newline at end of file