layout/tools/reftest/README.txt

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 Layout Engine Visual Tests (reftest)
     2 L. David Baron <dbaron@dbaron.org>, Mozilla Corporation
     3 July 19, 2006
     5 This code is designed to run tests of Mozilla's layout engine.  These
     6 tests consist of an HTML (or other format) file along with a reference
     7 in the same format.  The tests are run based on a manifest file, and for
     8 each test, PASS or FAIL is reported, and UNEXPECTED is reported if the
     9 result (PASS or FAIL) was not the expected result noted in the manifest.
    11 Images of the display of both tests are captured, and most test types
    12 involve comparing these images (e.g., test types == or !=) to determine
    13 whether the test passed.  The captures of the tests are taken in a
    14 viewport that is 800 pixels wide and 1000 pixels tall, so any content
    15 outside that area will be ignored (except for any scrollbars that are
    16 displayed).  Ideally, however, tests should be written so that they fit
    17 within 600x600, since we may in the future want to switch to 600x600 to
    18 match http://lists.w3.org/Archives/Public/www-style/2012Sep/0562.html .
    20 Why this way?
    21 =============
    23 Writing HTML tests where the reference rendering is also in HTML is
    24 harder than simply writing bits of HTML that can be regression-tested by
    25 comparing the rendering of an older build to that of a newer build
    26 (perhaps using stored reference images from the older build).  However,
    27 comparing across time has major disadvantages:
    29  * Comparisons across time either require two runs for every test, or
    30    they require stored reference images appropriate for the platform and
    31    configuration (often limiting testing to a very specific
    32    configuration).
    34  * Comparisons across time may fail due to expected changes, for
    35    example, changes in the default style sheet for HTML, changes in the
    36    appearance of form controls, or changes in default preferences like
    37    default font size or default colors.
    39 Using tests for which the pass criteria were explicitly chosen allows
    40 running tests at any time to see whether they still pass.
    42 Manifest Format
    43 ===============
    45 The test manifest format is a plain text file.  A line starting with a
    46 "#" is a comment.  Lines may be commented using whitespace followed by
    47 a "#" and the comment.  Each non-blank line (after removal of comments)
    48 must be one of the following:
    50 1. Inclusion of another manifest
    52    <failure-type>* include <relative_path>
    54    <failure-type> is the same as listed below for a test item.  As for 
    55    test items, multiple failure types listed on the same line are 
    56    combined by using the last matching failure type listed.  However, 
    57    the failure type on a manifest is combined with the failure type on 
    58    the test (or on a nested manifest) with the rule that the last in the
    59    following list wins:  fails, random, skip.  (In other words, skip 
    60    always wins, and random beats fails.)
    62 2. A test item
    64    [ <failure-type> | <preference> ]* [<http>] <type> <url> <url_ref>
    66    where
    68    a. <failure-type> (optional) is one of the following:
    70       fails  The test passes if the images of the two renderings DO NOT
    71              meet the conditions specified in the <type>.
    73       fails-if(condition) If the condition is met, the test passes if the 
    74                           images of the two renderings DO NOT meet the 
    75                           conditions of <type>. If the condition is not met,
    76                           the test passes if the conditions of <type> are met.
    78       needs-focus  The test fails or times out if the reftest window is not
    79                    focused.
    81       random  The results of the test are random and therefore not to be
    82               considered in the output.
    84       random-if(condition) The results of the test are random if a given
    85                            condition is met.
    87       silentfail This test may fail silently, and if that happens it should
    88                  count as if the test passed. This is useful for cases where
    89                  silent failure is the intended behavior (for example, in
    90                  an out of memory situation in JavaScript, we stop running
    91                  the script silently and immediately, in hopes of reclaiming
    92                  enough memory to keep the browser functioning).
    94       silentfail-if(condition) This test may fail silently if the condition
    95                                is met.
    97       skip  This test should not be run. This is useful when a test fails in a
    98             catastrophic way, such as crashing or hanging the browser. Using
    99             'skip' is preferred to simply commenting out the test because we
   100             want to report the test failure at the end of the test run.
   102       skip-if(condition) If the condition is met, the test is not run. This is
   103                          useful if, for example, the test crashes only on a
   104                          particular platform (i.e. it allows us to get test
   105                          coverage on the other platforms).
   107       slow  The test may take a long time to run, so run it if slow tests are
   108             either enabled or not disabled (test manifest interpreters may
   109             choose whether or not to run such tests by default).
   111       slow-if(condition) If the condition is met, the test is treated as if
   112                          'slow' had been specified.  This is useful for tests
   113                          which are slow only on particular platforms (e.g. a
   114                          test which exercised out-of-memory behavior might be
   115                          fast on a 32-bit system but inordinately slow on a
   116                          64-bit system).
   118       fuzzy(maxDiff, diffCount)
   119           This allows a test to pass if the pixel value differences are <=
   120           maxDiff and the total number of different pixels is <= diffCount.
   121           It can also be used with '!=' to ensure that the difference is
   122           greater than maxDiff.
   124       fuzzy-if(condition, maxDiff, diffCount)
   125           If the condition is met, the test is treated as if 'fuzzy' had been
   126           specified. This is useful if there are differences on particular
   127           platforms.
   129       require-or(cond1&&cond2&&...,fallback)
   130           Require some particular setup be performed or environmental
   131           condition(s) made true (eg setting debug mode) before the test
   132           is run. If any condition is unknown, unimplemented, or fails,
   133           revert to the fallback failure-type.
   134           Example: require-or(debugMode,skip)
   136       asserts(count)
   137           Loading the test and reference is known to assert exactly
   138           count times.
   139           NOTE: An asserts() notation with a non-zero count or maxCount
   140           suppresses use of a cached canvas for the test with the
   141           annotation.  However, if later occurrences of the same test
   142           are not annotated, they will use the cached canvas
   143           (potentially from the load that asserted).  This allows
   144           repeated use of the same test or reference to be annotated
   145           correctly (which may be particularly useful when the uses are
   146           in different subdirectories that can be tested independently),
   147           but does not force them to be, nor does it force suppression
   148           of caching for a common reference when it is the test that
   149           asserts.
   151       asserts(minCount-maxCount)
   152           Loading the test and reference is known to assert between
   153           minCount and maxCount times, inclusive.
   154           NOTE: See above regarding canvas caching.
   156       asserts-if(condition,count)
   157       asserts-if(condition,minCount-maxCount)
   158           Same as above, but only if condition is true.
   160       Conditions are JavaScript expressions *without spaces* in them.
   161       They are evaluated in a sandbox in which a limited set of
   162       variables are defined.  See the BuildConditionSandbox function in
   163       layout/tools/reftest.js for details.
   165       Examples of using conditions:
   166           fails-if(winWidget) == test reference
   167           asserts-if(cocoaWidget,2) load crashtest
   169    b. <preference> (optional) is a string of the form
   171           pref(<name>,<value>)
   172           test-pref(<name>,<value>)
   173           ref-pref(<name>,<value>)
   175       where <name> is the name of a preference setting, as seen in
   176       about:config, and <value> is the value to which this preference should
   177       be set. <value> may be a boolean (true/false), an integer, or a
   178       quoted string *without spaces*, according to the type of the preference.
   180       The preference will be set to the specified value prior to
   181       rendering the test and/or reference canvases (pref() applies to
   182       both, test-pref() only to the test, and ref-pref() only to the
   183       reference), and will be restored afterwards so that following
   184       tests are not affected. Note that this feature is only useful for
   185       "live" preferences that take effect immediately, without requiring
   186       a browser restart.
   188    c. <http>, if present, is one of the strings (sans quotes) "HTTP" or
   189       "HTTP(..)" or "HTTP(../..)" or "HTTP(../../..)", etc. , indicating that
   190       the test should be run over an HTTP server because it requires certain
   191       HTTP headers or a particular HTTP status.  (Don't use this if your test
   192       doesn't require this functionality, because it unnecessarily slows down
   193       the test.)
   195       With "HTTP", HTTP tests have the restriction that any resource an HTTP
   196       test accesses must be accessed using a relative URL, and the test and
   197       the resource must be within the directory containing the reftest
   198       manifest that describes the test (or within a descendant directory).
   199       The variants "HTTP(..)", etc., can be used to relax this restriction by
   200       allowing resources in the parent directory, etc.
   202       To modify the HTTP status or headers of a resource named FOO, create a
   203       sibling file named FOO^headers^ with the following contents:
   205       [<http-status>]
   206       <http-header>*
   208       <http-status> A line of the form "HTTP ###[ <description>]", where
   209                     ### indicates the desired HTTP status and <description>
   210                     indicates a desired HTTP status description, if any.
   211                     If this line is omitted, the default is "HTTP 200 OK".
   212       <http-header> A line in standard HTTP header line format, i.e.
   213                     "Field-Name: field-value".  You may not repeat the use
   214                     of a Field-Name and must coalesce such headers together,
   215                     and each header must be specified on a single line, but
   216                     otherwise the format exactly matches that from HTTP
   217                     itself.
   219       HTTP tests may also incorporate SJS files.  SJS files provide similar
   220       functionality to CGI scripts, in that the response they produce can be
   221       dependent on properties of the incoming request.  Currently these
   222       properties are restricted to method type and headers, but eventually
   223       it should be possible to examine data in the body of the request as
   224       well when computing the generated response.  An SJS file is a JavaScript
   225       file with a .sjs extension which defines a global |handleRequest|
   226       function (called every time that file is loaded during reftests) in this
   227       format:
   229       function handleRequest(request, response)
   230       {
   231         response.setStatusLine(request.httpVersion, 200, "OK");
   233         // You *probably* want this, or else you'll get bitten if you run
   234         // reftest multiple times with the same profile.
   235         response.setHeader("Cache-Control", "no-cache");
   237         response.write("any ASCII data you want");
   239         var outputStream = response.bodyOutputStream;
   240         // ...anything else you want to do, synchronously...
   241       }
   243       For more details on exactly which functions and properties are available
   244       on request/response in handleRequest, see the nsIHttpRe(quest|sponse)
   245       definitions in <netwerk/test/httpserver/nsIHttpServer.idl>.
   247    d. <type> is one of the following:
   249       ==     The test passes if the images of the two renderings are the
   250              SAME.
   251       !=     The test passes if the images of the two renderings are 
   252              DIFFERENT.
   253       load   The test passes unconditionally if the page loads.  url_ref
   254              must be omitted, and the test cannot be marked as fails or
   255              random.  (Used to test for crashes, hangs, assertions, and
   256              leaks.)
   257       script The loaded page records the test's pass or failure status
   258              in a JavaScript data structure accessible through the following
   259              API.
   261              getTestCases() returns an array of test result objects
   262              representing the results of the tests performed by the page.
   264              Each test result object has two methods:
   266              testPassed() returns true if the test result object passed,
   267              otherwise it returns false.
   269              testDescription() returns a string describing the test
   270              result.
   272              url_ref must be omitted. The test may be marked as fails or
   273              random. (Used to test the JavaScript Engine.)
   275    e. <url> is either a relative file path or an absolute URL for the
   276       test page
   278    f. <url_ref> is either a relative file path or an absolute URL for
   279       the reference page
   281    The only difference between <url> and <url_ref> is that results of
   282    the test are reported using <url> only.
   284 3. Specification of a url prefix
   286    url-prefix <string>
   288    <string> will be prepended to relative <url> and <url_ref> for all following
   289    test items in the manifest.
   291    <string> will not be prepended to the relative path when including another
   292    manifest, e.g. include <relative_path>.
   294    <string> will not be prepended to any <url> or <url_ref> matching the pattern
   295    /^\w+:/. This will prevent the prefix from being applied to any absolute url
   296    containing a protocol such as data:, about:, or http:.
   298    While the typical use of url-prefix is expected to be as the first line of
   299    a manifest, it is legal to use it anywhere in a manifest. Subsequent uses
   300    of url-prefix overwrite any existing values.
   302 4. Specification of default preferences
   304    default-preferences <preference>*
   306    where <preference> is defined above.
   308    The <preference> settings will be used for all following test items in the
   309    manifest.
   311    If a test item includes its own preference settings, then they will override
   312    any settings for preferences of the same names that are set using
   313    default-preferences, just as later items within a line override earlier ones.
   315    A default-preferences line with no <preference> settings following it will
   316    reset the set of default preferences to be empty.
   318    As with url-prefix, default-preferences will often be used at the start of a
   319    manifest file so that it applies to all test items, but it is legal for
   320    default-preferences to appear anywhere in the manifest. A subsequent
   321    default-preferences will reset any previous default preference values and
   322    overwrite them with the specified <preference> values.
   324 This test manifest format could be used by other harnesses, such as ones
   325 that do not depend on XUL, or even ones testing other layout engines.
   327 Running Tests
   328 =============
   330 (If you're not using a DEBUG build, first set browser.dom.window.dump.enabled
   331 to true (in about:config, in the profile you'll be using to run the tests).
   332 Create the option as a new boolean if it doesn't exist already. If you skip
   333 this step you won't get any output in the terminal.)
   335 At some point in the future there will hopefully be a cleaner way to do
   336 this.  For now, go to your object directory, and run (perhaps using
   337 MOZ_NO_REMOTE=1 or the -profile <directory> option)
   339 ./firefox -reftest /path/to/srcdir/mozilla/layout/reftests/reftest.list > reftest.out
   341 and then search/grep reftest.out for "UNEXPECTED".
   343 There are two scripts provided to convert the reftest.out to HTML.
   344 clean-reftest-output.pl converts reftest.out into simple HTML, stripping
   345 lines from the log that aren't relevant.  reftest-to-html.pl converts
   346 the output into html that makes it easier to visually check for
   347 failures.
   349 Testable Areas
   350 ==============
   352 This framework is capable of testing many areas of the layout engine.
   353 It is particularly well-suited to testing dynamic change handling (by
   354 comparison to the static end-result as a reference) and incremental
   355 layout (comparison of a script-interrupted layout to one that was not).
   356 However, it is also possible to write tests for many other things that
   357 can be described in terms of equivalence, for example:
   359  * CSS cascading could be tested by comparing the result of a
   360    complicated set of style rules that makes a word green to <span
   361    style="color:green">word</span>.
   363  * <canvas> compositing operators could be tested by comparing the
   364    result of drawing using canvas to a block-level element with the
   365    desired color as a CSS background-color.
   367  * CSS counters could be tested by comparing the text output by counters
   368    with a page containing the text written out
   370  * complex margin collapsing could be tested by comparing the complex
   371    case to a case where the margin is written out, or where the margin
   372    space is created by an element with 'height' and transparent
   373    background
   375 When it is not possible to test by equivalence, it may be possible to
   376 test by non-equivalence.  For example, testing justification in cases
   377 with more than two words, or more than three different words, is
   378 difficult.  However, it is simple to test that justified text is at
   379 least displayed differently from left-, center-, or right-aligned text.
   381 Writing Tests
   382 =============
   384 When writing tests for this framework, it is important for the test to
   385 depend only on behaviors that are known to be correct and permanent.
   386 For example, tests should not depend on default font sizes, default
   387 margins of the body element, the default style sheet used for HTML, the
   388 default appearance of form controls, or anything else that can be
   389 avoided.
   391 In general, the best way to achieve this is to make the test and the
   392 reference identical in as many aspects as possible.  For example:
   394   Good test markup:
   395     <div style="color:green"><table><tr><td><span>green
   396     </span></td></tr></table></div>
   398   Good reference markup:
   399     <div><table><tr><td><span style="color:green">green
   400     </span></td></tr></table></div>
   402   BAD reference markup:
   403     <!-- 3px matches the default cellspacing and cellpadding -->
   404     <div style="color:green; padding: 3px">green
   405     </div>
   407   BAD test markup:
   408     <!-- span doesn't change the positioning, so skip it -->
   409     <div style="color:green"><table><tr><td>green
   410     </td></tr></table></div>
   412 Asynchronous Tests: class="reftest-wait"
   413 ========================================
   415 Normally reftest takes a snapshot of the given markup's rendering right
   416 after the load event fires for content. If your test needs to postpone
   417 the moment the snapshot is taken, it should make sure a class
   418 'reftest-wait' is on the root element by the moment the load event
   419 fires. The easiest way to do this is to put it in the markup, e.g.:
   420     <html class="reftest-wait">
   422 When your test is ready, you should remove this class from the root
   423 element, for example using this code:
   424     document.documentElement.className = "";
   427 Note that in layout tests it is often enough to trigger layout using 
   428     document.body.offsetWidth  // HTML example
   430 When possible, you should use this technique instead of making your
   431 test async.
   433 Invalidation Tests: MozReftestInvalidate Event
   434 ==============================================
   436 When a test (or reference) uses reftest-wait, reftest tracks invalidation
   437 via MozAfterPaint and updates the test image in the same way that
   438 a regular window would be repainted. Therefore it is possible to test
   439 invalidation-related bugs by setting up initial content and then
   440 dynamically modifying it before removing reftest-wait. However, it is
   441 important to get the timing of these dynamic modifications right so that
   442 the test doesn't accidentally pass because a full repaint of the window
   443 was already pending. To help with this, reftest fires one MozReftestInvalidate
   444 event at the document root element for a reftest-wait test when it is safe to
   445 make changes that should test invalidation. The event bubbles up to the
   446 document and window so you can set listeners there too. For example,
   448 function doTest() {
   449   document.body.style.border = "";
   450   document.documentElement.removeAttribute('class');
   451 }
   452 document.addEventListener("MozReftestInvalidate", doTest, false);
   454 Painting Tests: class="reftest-no-paint"
   455 ========================================
   457 If an element shouldn't be painted, set the class "reftest-no-paint" on it
   458 when doing an invalidation test. Causing a repaint in your
   459 MozReftestInvalidate handler (for example, by changing the body's background
   460 colour) will accurately test whether the element is painted.
   462 Snapshot The Whole Window: class="reftest-snapshot-all"
   463 =======================================================
   465 In a reftest-wait test, to disable testing of invalidation and force the final
   466 snapshot to be taken of the whole window, set the "reftest-snapshot-all"
   467 class on the root element.
   469 Zoom Tests: reftest-zoom="<float>"
   470 ==================================
   472 When the root element of a test has a "reftest-zoom" attribute, that zoom
   473 factor is applied when rendering the test. The reftest document will be
   474 800 device pixels wide by 1000 device pixels high. The reftest harness assumes
   475 that the CSS pixel dimensions are 800/zoom and 1000/zoom. For best results
   476 therefore, choose zoom factors that do not require rounding when we calculate
   477 the number of appunits per device pixel; i.e. the zoom factor should divide 60,
   478 so 60/zoom is an integer.
   480 Setting Viewport Size: reftest-viewport-w/h="<int>"
   481 ===================================================
   483 If either of the "reftest-viewport-w" and "reftest-viewport-h" attributes on
   484 the root element are non-zero, sets the CSS viewport to the given size in
   485 CSS pixels. This does not affect the size of the snapshot that is taken.
   487 Setting Async Scroll Mode: reftest-async-scroll attribute
   488 =========================================================
   490 If the "reftest-async-scroll" attribute is set on the root element, we try to
   491 enable async scrolling for the document. This is unsupported in many
   492 configurations.
   494 Setting Displayport Dimensions: reftest-displayport-x/y/w/h="<int>"
   495 ===================================================================
   497 If any of the "reftest-displayport-x", "reftest-displayport-y",
   498 "reftest-displayport-w" and "reftest-displayport-h" attributes on the root
   499 element are nonzero, sets the displayport dimensions to the given bounds in
   500 CSS pixels. This does not affect the size of the snapshot that is taken.
   502 When the "reftest-async-scroll" attribute is set on the root element, *all*
   503 elements in the document are checked for "reftest-displayport-x/y/w/h" and have
   504 displayports set on them when those attributes are present.
   506 Testing Async Scrolling: reftest-async-scroll-x/y="<int>"
   507 =========================================================
   509 When the "reftest-async-scroll" attribute is set on the root element, for any
   510 element where either the "reftest-async-scroll-x" or "reftest-async-scroll-y
   511 attributes are nonzero, at the end of the test take the snapshot with the given
   512 offset (in CSS pixels) added to the async scroll offset.
   514 Printing Tests: class="reftest-print"
   515 =====================================
   517 Now that the patch for bug 374050 has landed
   518 (https://bugzilla.mozilla.org/show_bug.cgi?id=374050), it is possible to
   519 create reftests that run in a paginated context.
   521 The page size used is 5in wide and 3in tall (with the default half-inch
   522 margins).  This is to allow tests to have less text and to make the
   523 entire test fit on the screen.
   525 There is a layout/reftests/printing directory for printing reftests; however,
   526 there is nothing special about this directory.  You can put printing reftests
   527 anywhere that is appropriate.
   529 The suggested first lines for any printing test is
   530 <!DOCTYPE html><html class="reftest-print">
   531 <style>html{font-size:12pt}</style>
   533 The reftest-print class on the root element triggers the reftest to
   534 switch into page mode. Fixing the font size is suggested, although not
   535 required, because the pages are a fixed size in inches. The switch to page mode
   536 happens on load if the reftest-wait class is not present; otherwise it happens
   537 immediately after firing the MozReftestInvalidate event.
   539 The underlying layout support for this mode isn't really complete; it
   540 doesn't use exactly the same codepath as real print preview/print. In
   541 particular, scripting and frames are likely to cause problems; it is untested,
   542 though.  That said, it should be sufficient for testing layout issues related
   543 to pagination.
   545 Plugin and IPC Process Crash Tests: class="reftest-expect-process-crash"
   546 ========================================================================
   548 If you are running a test that causes an out-of-process plugin or IPC process
   549 under Electrolysis to crash as part of a reftest, this will cause process
   550 crash minidump files to be left in the profile directory.  The test
   551 infrastructure that runs the reftests will notice these minidump files and
   552 dump out information from them, and these additional error messages in the logs
   553 can end up erroneously being associated with other errors from the reftest run.
   554 They are also confusing, since the appearance of "PROCESS-CRASH" messages in
   555 the test run output can seem like a real problem, when in fact it is the
   556 expected behavior.
   558 To indicate to the reftest framework that a test is expecting a plugin or
   559 IPC process crash, have the test include "reftest-expect-process-crash" as
   560 one of the root element's classes by the time the test has finished.  This will
   561 cause any minidump files that are generated while running the test to be removed
   562 and they won't cause any error messages in the test run output.
   564 Skip Forcing A Content Process Layer-Tree Update: reftest-no-sync-layers attribute
   565 ==================================================================================
   567 Normally when an multi-process reftest test ends, we force the content process
   568 to push a layer-tree update to the compositor before taking the snapshot.
   569 Setting the "reftest-no-sync-layers" attribute on the root element skips this
   570 step, enabling testing that layer-tree updates are being correctly generated.
   571 However the test must manually wait for a MozAfterPaint event before ending.

mercurial