mkupidura@future-processing.com
@__fwkz__
github.com/fwkz



Test Reactor

Automated Web Testing 

Framework

Inspirations

Kevin Boers @ PyCon US 2009
"Building a Simple Configuration-driven Web Testing Framework With Twill" 






  • The Web framework for perfectionists with deadlines

  • Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design.

  • Django focuses on automating as much as possible and adhering to the DRY principle.


In the spring of 2006, I was working for NASA on project that implemented a Java-based RESTful web service that taking weeks to deliver. One evening, when managment had left for the day, I reimplemented that service in Python in 90 minutes.

~ Daniel Greenfeld

pydanny.com, @pydanny

Function-based Views

from django.http import HttpResponse
from django.template import RequestContext, loader

from books.models import Publisher
def index(request):
    publishers = Publisher.objects.all()
    template = loader.get_template("templates/publishers.html")
    context = RequestContext(request, {
        'publishers': publishers,
    })
    return HttpResponse(template.render(context))

Class-based Views

from django.views.generic import ListView
from books.models import Publisher

class PublisherList(ListView):
    model = Publisher
    template_name = "templates/publisher.html"

Event Driven Programming




Decoupling Transports and Protocols

  • Transports represent the connection between two endpoints communicating over a network.

  • Transports are responsible for describing connection details, TCP, UDP, and Unix sockets are examples of transports.

  • Decoupled from protocol implementations, allowing for many protocols to utilize the same type of transport.


What's next?


Adopt
Adapt
Improve

Classic Method


import unittest
from selenium import webdriver

class TestSomething(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Firefox()

    def test_something(self):
        textbox = self.driver.find_element_by_id("OldPassword")
        textbox.send_keys("zupa_pomidorowa")
        # ...

    def tearDown(self):
        self.driver.quit()

Page Objects

import unittest
from selenium import webdriver
from page_objects import EditProfile

class TestSomething(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Firefox()

    def test_something(self)
        edit_profile = EditProfile(self.driver)
        edit_profile.set_new_password()
        # ...

    def tearDown(self):
        self.driver.close()

Test reactor 

STRUCTURE

core/
    | generic/
          | ...
    | reactor.py
    | settings.py
    | ...
tests/
    | create_user/
         | handlers.py
         | scenarios.cfg
         | test.py
    | lock_account/
         | handlers.py
         | scenarios.cfg
         | test.py
    | ...

 core/
    | generic/
    | reactor.py
    | settings.py
    | ...
tests/
    | create_user/
         | handlers.py
         | scenarios.cfg
         | test.py
from core.reactor import Reactor
from core.scenario import ScenarioFactory
from core import xpages

scenarios = ScenarioFactory("tests/create_user/scenarios.cfg")

def create_user_test():
    reactor = Reactor(entry_url="http://appundertest.com/",
                      exit_point=xpages.CreateUserSuccessPage,
                      scenario=scenarios["create_user"])
    reactor.run()

 core/
    | generic/
    | reactor.py
    | settings.py
    | ...
tests/
    | create_user/
         | handlers.py
         | scenarios.cfg
         | test.py
class Reactor(...):
    def run(self):        
        # Navigate to starting point.
        self.driver.get(self.entry_url)

        self.currentpage = self.where_am_i()

        while self.currentpage != self.exit_point:
            self.execute_handler()  # Handle the current page.
            self.currentpage = self.where_am_i() 

        # Execute handler of exit point.
        self.execute_handler()

 core/
    | generic/
    | reactor.py
    | settings.py
    | ...
tests/
    | add_funds/
         | handlers.py
         | scenarios.cfg
         | test.py
from core.generic.handlers import *
from core import xpages

class HandleDashboard(xpages.Dashboard):
    def execute(self):
        self.my_account()

class HandleMyAccount(xpages.MyAccount):
    def execute(self):
        self.add_new_funds()

class HandleAddFunds(xpages.AddFunds):
    def execute(self):
        self.set_amount()
        self.pay()
        self.submit()

inheritance of actions


from core.generic.handlers import *
from tests.edit_user.handlers import (HandleDashboard, 
                                      HandleMyAccount, 
                                      HandleEditMyProfilePersonalInfo, 
                                      HandleEditMyProfileSuccess, )

class HandleForgotPassword(xpages.ForgotPasswordPage):
    def execute(self):
        self.email()
        self.submit()

class HandleForgotPasswordSuccessPage(xpages.ForgotPasswordSuccessPage):
    def execute(self):       
        self.set_login()
        self.set_password()
        self.submit()

Generic actions

  • Login  page
  • Errors raised by server
  • Search
  • ...


from core.generic.handlers import *

Next steps




Open Source?

Polon project


https://github.com/fwkz/polon


>> polon-admin.py --start-project automatic_web_tests
>> cd automatic_web_tests
>> python manage.py --add-tests login search add_product
>> 



Questions?

Test Reactor

By fwkz

Test Reactor

  • 1,347