Testing WebApps 101
For newbies by newbies
Requisites for the talk
● Virtualenv (of course)
● Django
● Selenium
Different Types of tests
● Unit Tests
A unit test establishes that the code does what you
intended the code to do (e.g. you wanted to add parameter
a and b, you in fact add them, and don't subtract them)
Different Types of tests
● Functional Tests
Functional tests test that all of the code works
together to get a correct result, so that what you
intended the code to do in fact gets the right
result in the system.
Different Types of tests
● Integration Tests
Is the phase in software testing in which
individual software modules are combined and
tested as a group
Integration tests tell what's not working. But
they are of no use in guessing where the
problem could be.
Some bugs are dependent of other modules
A single bug will break several features, and
several integration tests will fail
On the other hand, the same bug will break
just one unit test
virtualenv --python=/Library/Frameworks/Python.framework/Versions/3.3/bin/python
3 testdir
Installing Virtualenv
Functional
Testing
from selenium import webdriver
browser = webdriver.Firefox()
browser.get('http://localhost:8000')
assert 'Django' in browser.title
funcional_test.py
from selenium import webdriver
browser = webdriver.Firefox()
browser.get('http://localhost:8000')
assert 'Django' in browser.title
browser.quit()
funcional_test.py
def setUp(self):
self.browser = webdriver.Firefox()
self.browser.implicitly_wait(3)
Implicits wait
from selenium import webdriver
import unittest
class NewVisitorTest(unittest.TestCase): #
def setUp(self): #
self.browser = webdriver.Firefox()
def tearDown(self): #
self.browser.quit()
def test_can_start_a_list_and_retrieve_it_later(self):
self.browser.get('http://localhost:8000')
self.assertIn('To-Do', self.browser.title) #
self.fail('Finish the test!') #
if __name__ == '__main__': #
unittest.main(warnings='ignore') #
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import unittest
class NewVisitorTest(unittest.TestCase):
def setUp(self):
self.browser = webdriver.Firefox()
self.browser.implicitly_wait(3)
def tearDown(self):
self.browser.quit()
#It continues below…. next slide
# We continue here...
def test_can_start_a_list_and_retrieve_it_later(self):
# Edith has heard about a cool new online to-do app. She goes
# to check out its homepage
self.browser.get('http://localhost:8000')
# She notices the page title and header mention to-do lists
self.assertIn('To-Do', self.browser.title)
header_text = self.browser.find_element_by_tag_name('h1').text
self.assertIn('To-Do', header_text)
# She is invited to enter a to-do item straight away
inputbox = self.browser.find_element_by_id('id_new_item')
self.assertEqual(
inputbox.get_attribute('placeholder'),
'Enter a to-do item'
)
Django UnitTest
from django.test import TestCase
Django Tests
Views
from django.core.urlresolvers import resolve
from django.test import TestCase
from django.http import HttpRequest
from lists.views import home_page
class HomePageTest(TestCase):
def test_root_url_resolves_to_home_page_view(self):
found = resolve('/')
self.assertEqual(found.func, home_page)
def test_home_page_returns_correct_html(self):
request = HttpRequest() #
response = home_page(request) #
self.assertTrue(response.content.startswith(b'<html>')) #
self.assertIn(b'<title>To-Do lists</title>', response.content) #
self.assertTrue(response.content.endswith(b'</html>')) #
from django.core.urlresolvers import resolve
from django.test import TestCase
from lists.views import home_page #
class HomePageTest(TestCase):
def test_root_url_resolves_to_home_page_view
(self):
found = resolve('/') #
self.assertEqual(found.func, home_page) #
Views Tests
MODELS
from lists.models import Item
[...]
class ItemModelTest(TestCase):
def test_saving_and_retrieving_items(self):
first_item = Item()
first_item.text = 'The first (ever) list item'
first_item.save()
second_item = Item()
second_item.text = 'Item the second'
second_item.save()
saved_items = Item.objects.all()
self.assertEqual(saved_items.count(), 2)
first_saved_item = saved_items[0]
second_saved_item = saved_items[1]
self.assertEqual(first_saved_item.text, 'The first (ever) list item')
self.assertEqual(second_saved_item.text, 'Item the second')
POST Requests
def test_home_page_can_save_a_POST_request(self):
request = HttpRequest()
request.method = 'POST'
request.POST['item_text'] = 'A new list item'
response = home_page(request)
self.assertEqual(Item.objects.count(), 1) #
new_item = Item.objects.first() #
self.assertEqual(new_item.text, 'A new list item') #
self.assertIn('A new list item', response.content.decode())
expected_html = render_to_string(
'home.html',
{'new_item_text': 'A new list item'}
)
self.assertEqual(response.content.decode(), expected_html)
def test_home_page_can_redirect_after_POST(self):
request = HttpRequest()
request.method = 'POST'
request.POST['item_text'] = 'A new list item'
response = home_page(request)
self.assertEqual(Item.objects.count(), 1)
new_item = Item.objects.first()
self.assertEqual(new_item.text, 'A new list item')
#Redirect instead of template
self.assertEqual(response.status_code, 302)
self.assertEqual(response['location'], '/') #W

Python Testing 101 with Selenium

  • 1.
    Testing WebApps 101 Fornewbies by newbies
  • 2.
    Requisites for thetalk ● Virtualenv (of course) ● Django ● Selenium
  • 3.
    Different Types oftests ● Unit Tests A unit test establishes that the code does what you intended the code to do (e.g. you wanted to add parameter a and b, you in fact add them, and don't subtract them)
  • 4.
    Different Types oftests ● Functional Tests Functional tests test that all of the code works together to get a correct result, so that what you intended the code to do in fact gets the right result in the system.
  • 5.
    Different Types oftests ● Integration Tests Is the phase in software testing in which individual software modules are combined and tested as a group Integration tests tell what's not working. But they are of no use in guessing where the problem could be.
  • 6.
    Some bugs aredependent of other modules
  • 7.
    A single bugwill break several features, and several integration tests will fail
  • 8.
    On the otherhand, the same bug will break just one unit test
  • 9.
  • 10.
  • 11.
    from selenium importwebdriver browser = webdriver.Firefox() browser.get('http://localhost:8000') assert 'Django' in browser.title funcional_test.py
  • 12.
    from selenium importwebdriver browser = webdriver.Firefox() browser.get('http://localhost:8000') assert 'Django' in browser.title browser.quit() funcional_test.py
  • 13.
    def setUp(self): self.browser =webdriver.Firefox() self.browser.implicitly_wait(3) Implicits wait
  • 14.
    from selenium importwebdriver import unittest class NewVisitorTest(unittest.TestCase): # def setUp(self): # self.browser = webdriver.Firefox() def tearDown(self): # self.browser.quit() def test_can_start_a_list_and_retrieve_it_later(self): self.browser.get('http://localhost:8000') self.assertIn('To-Do', self.browser.title) # self.fail('Finish the test!') # if __name__ == '__main__': # unittest.main(warnings='ignore') #
  • 15.
    from selenium importwebdriver from selenium.webdriver.common.keys import Keys import unittest class NewVisitorTest(unittest.TestCase): def setUp(self): self.browser = webdriver.Firefox() self.browser.implicitly_wait(3) def tearDown(self): self.browser.quit() #It continues below…. next slide
  • 16.
    # We continuehere... def test_can_start_a_list_and_retrieve_it_later(self): # Edith has heard about a cool new online to-do app. She goes # to check out its homepage self.browser.get('http://localhost:8000') # She notices the page title and header mention to-do lists self.assertIn('To-Do', self.browser.title) header_text = self.browser.find_element_by_tag_name('h1').text self.assertIn('To-Do', header_text) # She is invited to enter a to-do item straight away inputbox = self.browser.find_element_by_id('id_new_item') self.assertEqual( inputbox.get_attribute('placeholder'), 'Enter a to-do item' )
  • 17.
  • 18.
    from django.test importTestCase Django Tests
  • 19.
  • 20.
    from django.core.urlresolvers importresolve from django.test import TestCase from django.http import HttpRequest from lists.views import home_page class HomePageTest(TestCase): def test_root_url_resolves_to_home_page_view(self): found = resolve('/') self.assertEqual(found.func, home_page) def test_home_page_returns_correct_html(self): request = HttpRequest() # response = home_page(request) # self.assertTrue(response.content.startswith(b'<html>')) # self.assertIn(b'<title>To-Do lists</title>', response.content) # self.assertTrue(response.content.endswith(b'</html>')) #
  • 21.
    from django.core.urlresolvers importresolve from django.test import TestCase from lists.views import home_page # class HomePageTest(TestCase): def test_root_url_resolves_to_home_page_view (self): found = resolve('/') # self.assertEqual(found.func, home_page) # Views Tests
  • 22.
  • 23.
    from lists.models importItem [...] class ItemModelTest(TestCase): def test_saving_and_retrieving_items(self): first_item = Item() first_item.text = 'The first (ever) list item' first_item.save() second_item = Item() second_item.text = 'Item the second' second_item.save() saved_items = Item.objects.all() self.assertEqual(saved_items.count(), 2) first_saved_item = saved_items[0] second_saved_item = saved_items[1] self.assertEqual(first_saved_item.text, 'The first (ever) list item') self.assertEqual(second_saved_item.text, 'Item the second')
  • 24.
  • 25.
    def test_home_page_can_save_a_POST_request(self): request =HttpRequest() request.method = 'POST' request.POST['item_text'] = 'A new list item' response = home_page(request) self.assertEqual(Item.objects.count(), 1) # new_item = Item.objects.first() # self.assertEqual(new_item.text, 'A new list item') # self.assertIn('A new list item', response.content.decode()) expected_html = render_to_string( 'home.html', {'new_item_text': 'A new list item'} ) self.assertEqual(response.content.decode(), expected_html)
  • 26.
    def test_home_page_can_redirect_after_POST(self): request =HttpRequest() request.method = 'POST' request.POST['item_text'] = 'A new list item' response = home_page(request) self.assertEqual(Item.objects.count(), 1) new_item = Item.objects.first() self.assertEqual(new_item.text, 'A new list item') #Redirect instead of template self.assertEqual(response.status_code, 302) self.assertEqual(response['location'], '/') #W