Twill is a straightforward, easy-to-use package that is built on top of Python's implementation of Mechanize. Twill allows you to traverse web pages and fill out forms. In this section, we'll talk about some very common twill commands to get you started.
Okay, so we have a little nose under our belts, but isn't this tutorial about functional web testing? Indeed, and we'll marry up nose with twill, once we get through some basics of twill.
We'll discuss in the next section the different ways you can interact with twill, but for now I'm simply going to write some dead simple scripts. We'll start with one called 'twill_go.py':
import twill.commands as tc tc.go("http://127.0.0.1")
Let's run it.
[terryp@tpmacbook] code :: python twill_go.py ==> at http://127.0.0.1 [terryp@tpmacbook] code ::
You can see that after executing the code, twill took us to the website that we asked to go to! That's a good start, but let's keep on building and write a script called 'twill_go_info.py':
import twill.commands as tc tc.go("http://127.0.0.1") tc.info()
And let's run it to see the output:
[terryp@tpmacbook] code :: python twill_go_info.py ==> at http://127.0.0.1 Page information: URL: http://127.0.0.1 HTTP code: 200 Content type: text/html (HTML) Page title: Introduction to Functional Web Testing With Twill & Selenium
So now we know how to use 'go' and 'info,' but that's not very browsey. To really get our surf on, we need to follow some links! So let's write a script called 'twill_go_link.py':
import twill.commands as tc tc.go("http://127.0.0.1") tc.follow("About Us") tc.info() tc.back() tc.info()
All right, let's run it!
[terryp@tpmacbook] code :: python twill_go_link.py ==> at http://127.0.0.1 ==> at http://127.0.0.1/about_us.html Page information: URL: http://127.0.0.1/about_us.html HTTP code: 200 Content type: text/html (HTML) Page title: Introduction to Functional Web Testing With Twill & Selenium ==> back to http://127.0.0.1 Page information: URL: http://127.0.0.1 HTTP code: 200 Content type: text/html (HTML) Page title: Introduction to Functional Web Testing With Twill & Selenium
So you can see now that with a little code we can navigate our way through a website with relative ease. For bonus ease, let's look at 'twill_show_me_links.py':
import twill.commands as tc tc.go("http://127.0.0.1") tc.showlinks()
And let's run it:
[terryp@tpmacbook] code :: python twill_show_me_links.py ==> at http://127.0.0.1 Links: 0. Welcome ==> index.html 1. Part 1 ==> part_one/index.html 2. Part 2 ==> part_two/index.html 3. About The Tools ==> about_tools.html 4. About Us ==> about_us.html 5. Download Source Files ==> # 6. Index Reference ==> index_reference.html 7. Grid Reference ==> grid_reference.html 8. PyCon 2009 ==> http://us.pycon.org 9. Python 2.4.5 - 2.5.2 ==> http://python.org/download/ 10. nose 0.10.4 ==> http://somethingaboutorange.com/mrl/projects/nose/ 11. twill 0.9.0 ==> http://twill.idyll.org 12. BeautifulSoup 3.0.6 ==> http://www.crummy.com/software/BeautifulSoup/ 13. Selenium RC 1.0 Beta 1 ==> http://selenium-rc.openqa.org/ 14. Selenium IDE 1.0 Beta 2 ==> http://selenium-ide.openqa.org/ 15. Firefox 3 ==> http://www.mozilla.com/firefox/%3E 16. Begin Part One ==> part_one/index.html 17. Begin Part Two ==> part_two/index.html 18. Stephen Bau ==> http://www.domain7.com/WhoWeAre/StephenBau.html 19. 960 Grid System ==> http://960.gs/ 20. Nathan Smith ==> http://sonspring.com/journal/960-grid-system 21. GPL ==> licenses/GPL_license.txt 22. MIT ==> licenses/MIT_license.txt 23. Licenses ==> README.txt
... now might be a good time to rewind a little bit to look at the twill module itself from a really high level.
[terryp@tpmacbook] code :: python Python 2.5.4 (r254:67917, Dec 23 2008, 14:57:27) [GCC 4.0.1 (Apple Computer, Inc. build 5363)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import pprint >>> import twill >>> pprint.pprint(dir(twill)) ['TwillCommandLoop', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__path__', '__version__', '_browser', 'add_wsgi_intercept', 'browser', 'commands', 'errors', 'execute_file', 'execute_string', 'extensions', 'get_browser', 'get_browser_state', 'namespaces', 'os', 'parse', 'remove_wsgi_intercept', 'set_errout', 'set_output', 'shell', 'sys', 'thisdir', 'utils', 'wsgi_intercept', 'wwwsearchlib'] >>>
That's a lot of stuff, but for now we really only need to concern ourselves with 'commands,' since these are the primary controls for twill. So let's have a look at those.
[terryp@tpmacbook] code :: python Python 2.5.4 (r254:67917, Dec 23 2008, 14:57:27) [GCC 4.0.1 (Apple Computer, Inc. build 5363)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import pprint >>> import twill >>> pprint.pprint(dir(twill.commands)) ['ClientForm', 'ERR', 'OUT', 'TwillAssertionError', 'TwillBrowser', 'TwillException', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '_agent_map', '_options', '_orig_options', '_parseFindFlags', 'add_auth', 'add_extra_header', 'agent', 'back', 'browser', 'clear_cookies', 'clear_extra_headers', 'code', 'config', 'debug', 'echo', 'exit', 'extend_with', 'fa', 'find', 'follow', 'formaction', 'formclear', 'formfile', 'formvalue', 'fv', 'get_browser', 'get_twill_glocals', 'getinput', 'getpass', 'getpassword', 'go', 'info', 'is_html', 'load_cookies', 'mechanize', 'notfind', 're', 'redirect_error', 'redirect_output', 'reload', 'reset_browser', 'reset_error', 'reset_output', 'run', 'run_tidy', 'runfile', 'save_cookies', 'save_html', 'set_form_control_value', 'setglobal', 'setlocal', 'show', 'show_cookies', 'show_extra_headers', 'showforms', 'showhistory', 'showlinks', 'sleep', 'submit', 'sys', 'tidy_ok', 'time', 'title', 'url', 'utils'] >>>
So there we are, lots and lots of commands that we can use to get around. Many of them are documented on the twill language reference page, although you'll have to do a little translation into Python. (The docs on the python api might help you out there.)
Fluid 960 Grid System, created by Stephen Bau, based on the 960 Grid System by Nathan Smith. Released under the GPL/ MIT Licenses.