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?
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
>> 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