vendredi 13 avril 2018

Django. Best practice to organize Selenium tests

please share some your experience and give good advices. How to organize Selenium tests with Django?

It will be great if you give links or advice in comments.

Base approach

I'm writing tests for my own small pet project. I use SQLLite3 and make a copy of base via using fixtures. It helps me to test all functionality and have guarantees that behavior of test stage will be the same with production stage. Yes, I run tests locally on my laptop.

Problems

Right now I have (please, look below). What kind of problems I have

  • Each test looks like to hard for fast understanding after 1 month
  • Long and bad readability of long methods
  • I understand that they work, but it will be difficult to support and evolve them

Folders/Files structure

- general app
  - utils.py with base class of StaticLiveServerTestCase
  - fixtures for tests
- apps
  - app 1
   - tests
    - app_sel_tests.py
 - app 2

Base class of StaticLiveServerTestCase

@override_settings(DEBUG=True)
class SeleniumTestCase(StaticLiveServerTestCase):
    fixtures = ['fix.json', ]

    def _fixture_teardown(self):
        pass

    @classmethod
    def setUp(cls):
        super(SeleniumTestCase, cls).setUpClass()
        cls.browser = webdriver.Chrome()
        cls.wait = WebDriverWait(cls.browser, 5)
        cls.login()

    @classmethod
    def tearDown(cls):
        cls.browser.quit()

    @classmethod
    def login(cls):
        test_username = 'xxx'
        test_password = 'xxx'
        test_email = 'xxx'
        user, created = User.objects.get_or_create(username=test_username)
        if created:
            user.is_active = True
            user.set_password(test_password)
            user.save()
        cls.browser.get('%s%s' % (cls.live_server_url, '/login/'))
        username = cls.browser.find_element_by_id('id_username')
        password = cls.browser.find_element_by_id('id_password')
        submit = cls.browser.find_element_by_id('id_submit')
        username.send_keys(test_username)
        password.send_keys(test_password)
        submit.click()
        assert cls.browser.find_element_by_xpath(
            '/html/body/nav/div/div/div[1]/a').text == 'xxx'

Example of Selenium test

class ClientsTestCases(SeleniumTestCase):
def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self._client = {'name': 'name',
                    'address': 'address',
                    'phone': '+79999999999',
                    'info': 'info',
                    'lat': '55.769411',
                    'lng': '37.613025'
                    }

def test_0_add_client(self):
    url = urljoin(self.live_server_url, reverse('add_client'))
    self.browser.get(url)
    assert self.browser.find_element_by_xpath(
        '/html/body/div/div/h1').text == 'Add new client'
    name = self.browser.find_element_by_id('id_name')
    address = self.browser.find_element_by_id('id_address')
    phone = self.browser.find_element_by_id('id_phone')
    info = self.browser.find_element_by_id('id_info')
    lat = self.browser.find_element_by_id('id_lat')
    lng = self.browser.find_element_by_id('id_lng')
    submit = self.browser.find_element_by_id('submit_button')
    name.send_keys(self._client['name'])
    address.send_keys(self._client['name'])
    phone.send_keys(self._client['phone'])
    info.send_keys(self._client['info'])
    submit.click()
    assert self.browser.find_element_by_xpath(
        '/html/body/div[1]/div/div[1]/div/div').text == 'Client was added'

def test_1_find_client_and_edit_client(self):
    url = urljoin(self.live_server_url, reverse('clients'))
    self.browser.get(url)
    self.browser.implicitly_wait(2)
    assert self.browser.find_element_by_xpath(
        '/html/body/div/div/h1').text == 'Clients'
    clients_search = self.browser.find_element_by_id('clients_search')
    clients_search.send_keys(self._client['name'])
    self.wait.until(EC.visibility_of_element_located((
        By.LINK_TEXT, self._client['name'])))
    self.browser.implicitly_wait(2)
    client_link = self.browser.find_element_by_link_text(
        self._client['name'])
    assert client_link.text == self._client['name']
    client_link.click()
    self.browser.implicitly_wait(2)
    submit = self.browser.find_element_by_id('submit_button')
    submit.click()
    self.browser.implicitly_wait(2)
    assert self.browser.find_element_by_xpath(
        '/html/body/div[1]/div/div[1]/div/div').text == 'Client was updated'

Aucun commentaire:

Enregistrer un commentaire