Think like a browser.
Content is your enemy!
Find beacons!
The happy path is 1/2 the solution.
Determine a page's fingerprint.
Before you start writing tests, you need to stop and think about the application and its users. Who is going to be using your site, and why? What do they need to be able to accomplish? The answers are going to form the core of your test suite.
Because you're testing a site, there are some obvious things that need to work: links, form submissions, etc.
While it's possible to test content (to some extent, anyway), that's a slippery slope, and you need to be careful. Try to stick to content your team controls, content that rarely changes, content that's available to you in some way other than straight html (json feed, db content, etc).
When running tests against your application, you're probably going to need some kind of input data, i.e. 'fixtures'. A good approach to this issue is to create some kind of fixture object that scrapes a configuration file and makes the contents available as attributes.
For example, if your app has a registration process, you could create a configuration file (be sure to check out Terry's talk on configuration options!) containing all the values that you'd need to input into the form fields. Then, instead of loading the configuration file directly into your tests, you could build a fixture object that would let you specify what kind of data you need, and then just provide it to you:
>>> from cfg import fixtures >>> data = fixtures('default') >>> data_fuzz = fixtures('fuzz') >>> dir(data) ['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'address', 'email', 'first_name', 'last_name', 'suite', 'zipcode', 'username', 'password']
When you start building a test suite around your particular application, you will quickly discover that some kind of page validation is going to be necessary. There's no use in following a sequence of test steps if you can't even be assured that you're on the correct page, right? At a minimum, you should be asserting that you're getting a 200 response (see HTTP Responses, below), since twill won't do it for you. Beyond that, you'll want to add some boilerplate to validate that you're on the page you expect, and that it is displaying correctly. What you'll want to think about is how to determine a specific page's 'fingerprint'. That is, how do I know my tests are where they're supposed to be before continuing? It's easy enough to check the current URL/path with twill, but that's not enough. You should also assert that any form fields you expect are being displayed, that any specific text is appearing, etc.
One way to do this is by wrapping a series of page validations into a method in the Page Class (see the Page Class chapter in the Extra Time section) that are executed whenever you instantiate a copy of that page. That way, you can just call mypage.validate() and go on your merry way.
HTTP is your friend. What follows are the HTTP 1.1 response status codes that you're most likely to encounter and care about.
You can see the full, real list in RFC-2616 and Wikipedia has a nice entry that lists and describes response codes.
Response Status Code | Standard Associated Phrases |
---|---|
1xx Informational | |
2xx Success | |
200 | OK |
3xx Redirection | |
301 | Moved Permanently |
302 | Found |
4xx Client Error | |
400 | Bad Request |
401 | Unauthorized |
403 | Forbidden |
404 | Not Found |
418 | I'm A Teapot |
5xx Server Error | |
500 | Internal Server Error |
501 | Not Implemented |
502 | Bad Gateway |
Fluid 960 Grid System, created by Stephen Bau, based on the 960 Grid System by Nathan Smith. Released under the GPL/ MIT Licenses.