Testing Web Applications
Willem Visser
• Testing Theory
• Testing Web Apps
• Tools
The Basics
• A test consists of
– Input
– Expected output (also called the Oracle)
• White Box Testing
– Considering the code when coming up with tests
• Black Box Testing
– Only consider the input-output interface
• Automated Testing is the Holy Grail
Types of Testing
Unit Testing
Integration Testing
Systems Testing
Regression Testing
Acceptance Testing
– Alpha/Beta Testing
– Usability Testing
• Performance Testing
• Robustness Testing
• Security Testing
Lower Level Code Testing
• Unit Testing
– Test individual components of the code
– Can be as little as one function
– White box
• Integration Testing
– Interface between components
– White Box
– Can be as much as the whole system (which case
it becomes more black box)
• Code Coverage as Test Adequacy Measure
Functional Testing
• Testing that the systems meets the
• Systems Testing
– In the deployed environment
• Unlike Integration testing
– Always black box
Cross Cutting
• Regression Testing
– When code changes (some) old tests must still
– Could be at unit, integration or systems level
• Very high cost involved in regression testing
– Regression failure has high cost to fix
Customer Facing
• Acceptance Testing
– Is the customer happy with the product?
• Alpha/Beta Testing
– Let the system out to a few of your customers and
see how they feel about it
• Usability Testing
– Typically for GUI/Web/Mobile to not just check
that the system is correct but also easy to use
– Harder to create an Oracle
Non-Functional Testing
• Performance
– Load
• See how the system behaves at peak load
– Stress
• Push the system beyond its limits to see how far it will
• Security Testing
– Check whether there are vulnerabilities that might
lead to loss of privacy or other security issues
Web App Testing
• Full Gambit of Features
• Front End GUI
– Usability issues
– Hard to test
– Browser Compatibility issues
• Server Side (including storage)
– Performance issues
• Security issues
Unit Testing
• Utterly important!
• Finding bugs early saves money
• Makes regression testing much more effective
– Write once, run often
• What do you test?
– Business logic!
– No need to test simple code or interactions with
3rd party libraries
• Until they fail of course!
• Use Coverage tools to help you decide if you
have tested enough
Stubs or Mocks
• In unit testing you are interested in local
behavior and assume other things you might
be using behave correctly
• Most unit testing frameworks provides stubs
for these 3rd party components
• Good example is datastore and memcache
stubs provided by GAE
• Only problem is that sometimes these stubs
don’t respect the behavior of the real thing!
Unit Testing Frameworks
• Java – JUnit
– The most famous of them all
• PHP – PHPUnit
• Python – PyUnit
– Actually just “import unittest”
• And many more XUnit tools for language X
– For example GAEUnit, but it looks “dead” now
• Use coverage tools along side, examples…
– Coverage.py for Python
– (Ecl)Emma for (Eclipse) Java
Unit Testing and GUIs
• When doing Unit Testing you try and stay well
clear of the GUI
– Clicking and entering text through a GUI is not
automated, although we will see later that with
Replay Technology it can also be done
• Isolating the GUI to allow more efficient
testing is the reason to use Model-ViewPresenter rather than Model-View-Controller
design pattern
Webapp2 example
import webapp2
Code to Test
class HelloHandler(webapp2.RequestHandler):
def get(self):
self.response.write('Hello, world!')
app = webapp2.WSGIapplication([('/', HelloHandler)])
import unittest
import webapp2
# from the app main.py
import main
class TestHandlers(unittest.TestCase):
def test_hello(self):
request = webapp2.Request.blank('/’)
response = request.get_response(main.app)
self.assertEqual(response.status_int, 200)
self.assertEqual(response.body, 'Hello, world!’)
Integration Testing
• Thin line between unit and integration
• Strictly speaking when more than one
component is used you are doing integration
– For example if your web app uses a datastore then
the test on the previous slide that came in via a
GET request could be an integration test not a unit
• This is not worth worrying about
– Unit/Integration Testing is fine
System Testing
• Now the full round-trip is being tested,
including the Browser component
• Unit/Integration Testing can be done on a
local environment, but System Testing need to
be in the deployed environment
• State-of-the-Practice
– Record and replay tests
• The #1 tool in Web System Testing
• “automates browsers. That’s it!”
– Much like the webapp2 example earlier, just many
more options, including browser specific drivers
• IDE for record and replay
– With scripts that can be edited
• WebDriver that allows one to run without a
browser at all
Selenium Example
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
# Create a new instance of the Firefox driver
driver = webdriver.Firefox()
# go to the google home page
# find the element that's name attribute is q (the google search box)
inputElement = driver.find_element_by_name("q")
# type in the search
# we have to wait for the page to refresh, the last thing that seems to be updated is the title
WebDriverWait(driver, 10).until(EC.title_contains("cheese!"))
# You should see "cheese! - Google Search"
print driver.title
Java Example
import com.thoughtworks.selenium.*;
// This is the driver's import. You'll use this for instantiating a
// browser and making it do what you need.
public class NewTest extends SeleneseTestCase {
public void setUp() throws Exception {
setUp("http://www.google.com/", "*firefox");
public void testNew() throws Exception {
selenium.type("q", "selenium rc");
assertTrue(selenium.isTextPresent("Results * for selenium rc"));
Usability Testing
Based on user opinions
Manual according to a list of tasks
Observer records behavior
Could use things like eye-tracking for more
precise results
• Automated Usability Testing is still a research
Robustness Testing
• Try anything and see if something breaks
• Most famous of these is Android Monkey
– Sends random keystrokes to your Android app
• gremlins.js does the same thing for web apps
<script src="path/to/gremlins.min.js"></script>
Performance Testing
• System performance under specific loads
– Concurrent users doing a certain number of
transactions for a certain duration
• This is a very hard kind of testing to do
– Needs lots of infrastructure
– Often the performance bottleneck is your testing
framework and not the system under test
• In the end we know where the problem is
– More generally where something has to wait for
something else to finish
Web Performance Testing
• Measure throughput or transaction rate
• Server response time
• Rendering, but that might need additional
scripts on the client side
• You might not know what is the expected
performance, so often you profile the
– You will quickly notice bad performance
Web front-end Performance Tools
Google Pagespeed tools
Google Chrome Developer Tools
Nice summary of tools related to performance
can be found at
• Load and Performance Testing
• Server side
• Not a browser, but can simulate some actions
typically done by a browser
– HTTP, etc.
– No javascript execution
Security Testing
• This is HUGE!
– A whole course or even degree can be devoted to it
• Nice checklist of things to do at
• Large part of security testing is manual
• Penetration Testing
– Find security vulnerabilities that can be exploited
• Tools to find buffer overflows is one of the most
effective automatic approaches
• Fuzz Testing
– Semi-structured random testing
Zed Attack Proxy (ZAP)
• Automated Penetration Testing
– Point it to URL and it does the rest
• Includes Fuzzing and many more
• Find it here