QA/TDAI/DocShell Tests

From MozillaWiki
< QA‎ | TDAI
Jump to: navigation, search

Introduction

The DocShell is part of browser code that acts as glue between parts of the front and back ends. It manages navigation requests (from the user or elsewhere), creation of content viewers (the actual window that holds a web page), and session history, among other things.

For various reasons, we don't have many automated tests for DocShell. This currently isn't that big of an issue, as the DocShell has been fairly stable for a few years now. But that will all change soon, with the implementation of a multiple-process browser, code-named Electrolysis.

In Electrolysis, DocShell will need to communicate across multiple processes, and could easily break during development. To help quickly identify regressions, Mozilla QA needs help in creating automated DocShell tests. This is a great opportunity to get into test automation at Mozilla QA, for those who are interested. The only skill pre-requisites are a working knowledge of javascript, and an ability to create debug builds of Firefox...and the latter is something that I can walk you through if you've never done it before.

Finding Bugs That Need Tests

The first step in writing a DocShell test is finding an existing DocShell bug report that you can write a test against. The list of candidate bugs can be found in Bugzilla.

To find a good bug from this list to work on:

  • Locate a bug whose description and resolution you clearly understand.
  • Make sure the bug does not already have an automated test case attached to it (a plain HTML "testcase" is fine, though, and makes your job easier).
  • Skip bugs involving memory leaks, such as bug 87901, which cannot be verified easily with this method.
  • Skip bugs that are primarily code refactoring, such as bug 206166.

Getting Started With Mochitest

Once you've found a good bug to write a test for, it's time to dig in.

The test tool used to write DocShell tests is mochitest. If you've never used mochitest, here are some references:

If this is the first attempt in delving into mochitest, I suggest approaching things in this order:

  1. Download the Firefox code from "trunk" (aka "mozilla-central") (the "newest" code, not tied specifically to any release), and create a debug build.
  2. Run one of the existing DocShell mochitests; use the commands
 cd $(OBJDIR)/_tests/testing/mochitest
 python runtests.py --chrome --test-path=docshell/test/chrome/test_bug303267.xul

where $(OBJDIR) is object directory created when building Firefox.

Test Writing: Use a Template!

Now it's time to start working on the test you've selected for yourself. To make things a little easier I've created a template that takes care of a lot of boilerplate code that most DocShell tests need. To generate the template code:

 cd $(TOPSRCDIR)/docshell/test/chrome
perl gen_template.pl -b <bugnumber>

where $(TOPSRCDIR) is the directory containing your mozilla-central repository.

This will generate two files in the current directory, test_bug<bugnumber>.xul, and bug<bugnumber>_window.xul. The former you probably won't need to modify at all; all the action takes place in the latter.

Test Writing: Adding Your Own Code

Once the template code is generated, you can work on adding your own code relevant to the bug you're working on. Open bug<bugnumber>_window.xul in a text editor. You'll notice a function testIterator() which is described in the comments as a generator function. The bulk of the test takes place here. The test steps needed to execute the test are placed here, separated with yield statements, and the test code iterates through the steps one at a time. If this sounds confusing, you can look at bug303267.xul (from the test you may have run earlier according to the instructions above) and see how that's constructed.

The general rules for working with this generator function are:

  1. Whenever you initiate something that happens asynchronously (like navigating to a uri), you should add a yield statement; this causes execution of testIterator() to stop until nextTest() is called.
  2. Call nextTest() to resume iteration through testIterator(); generally you call this from an event handler or callback from an asynchronous function.

In the simplest case:

 setTimeout(nextTest, 1000);
 yield;
 

There are several helpful utility functions related to DocShell tests in the file docshell_helpers.js. The most frequently used is doPageNavigation(), which performs some navigation in the test window, verifies that some combination of load/unload/pageshow/pagehide events occur as the result of the navigation, and then notifies a callback. You can see several calls to this function in bug303267_window.xul.

Also available in this file are waitForTrue(), which notifies a callback when a given condition becomes true, enableBFCache(), which enables or disables the bfcache, and getHttpUrl(), which generates an HTTP uri for a test file.

Testing Your Test

Once you have a prototype of your automated test, you'll need to run it in order to see if it works. Modify Makefile.in in the $(TOPSRCDIR)/docshell/test/chrome directory to include the files you've created for this test. At a minimum, those will be test_bug<bugnumber>.xul and bug<bugnumber>_window.xul, and may include other files. Once you've made those changes, you'll need to re-build Firefox so that your test files get copied to the correct locations in the $(OBJDIR) directory. Then you can run your test using the commands:

 cd $(OBJDIR)/_tests/testing/mochitest
 python runtests.py --chrome --test-path=docshell/test/chrome/test_bug<bugwindow>.xul

Debugging Your Test

If you're like most people, the first time you make a mochitest it may not run quite right, and you'll need to debug it. The easiest way I've found to do this is to add dump() statements in your code, which will print out arbitrary statements along with all the other debug output the browser produces.

Getting Your Test Reviewed and Checked In

Once the test is working to your satisfaction, ping me for a review. Once I've reviewed it I'll work with you to get it checked into the Mozilla repository.

Additional Information

Many of the DocShell tests will involve the backwards-forwards cache (or bfcache, for short). See Firefox caching for a description of this along with the pageshow and pagehide events.

Contact Me

For help at any stage, please contact me at (IRC: jgriffin on #qa), (email: jgriffin at mozilla dot com)