Note: This page is out of date. If you are using modern practices, you are using a BrowserProxy for your JS/C++ interactions. The BrowserProxy document covers some testing practices for that case.
ProblemSee Also domui-testing.
WebUI contains Javascript, which runs in the renderer and a C++ handler, which runs in the UI thread of the browser process. While this is a necessary part of the design, testing across these boundaries of both language and process/thread is cumbersome at best.
ObjectiveMake it possible to test the Javascript portion of WebUI in Javascript:
SolutionThe solution comes in the following parts:
How to write a testThe best reference examples are chrome/test/data/webui/print_preview.js and chrome/browser/ui/webui/options/options_browsertest.js
/** * TestFixture for OptionsPage WebUI testing. * @extends {testing.Test} * @constructor **/ function OptionsWebUITest() {} OptionsWebUITest.prototype = { __proto__: testing.Test.prototype, /** * Browse to the options page & call our preLoad(). **/ browsePreload: 'chrome://settings-frame', // ... };
OptionsWebUITest.prototype = { ... /** * Register a mock handler to ensure expectations are met and options pages * behave correctly. **/ preLoad: function() { this.makeAndRegisterMockHandler(
['defaultZoomFactorAction',
'fetchPrefs',
'observePrefs',
'setBooleanPref',
'setIntegerPref',
'setDoublePref',
'setStringPref',
'setObjectPref',
'clearPref',
'coreOptionsUserMetricsAction',
]);
// Register stubs for methods expected to be called before/during tests.
// Specific expectations can be made in the tests themselves.
this.mockHandler.stubs().fetchPrefs(ANYTHING);
this.mockHandler.stubs().observePrefs(ANYTHING);
this.mockHandler.stubs().coreOptionsUserMetricsAction(ANYTHING);
},
... };
TEST_F('OptionsWebUITest', 'testSetBooleanPrefTriggers', function() { var showHomeButton = $('toolbarShowHomeButton'); var trueListValue = [ 'browser.show_home_button', true, 'Options_Homepage_HomeButton', ]; // Note: this expectation is checked in testing::Test::TearDown. this.mockHandler.expects(once()).setBooleanPref(trueListValue); // Cause the handler to be called. showHomeButton.click(); showHomeButton.blur(); });
See Handling a failing test for more details on style and how/when to disable a test. // Not meant to run on ChromeOS at this time. // Not finishing in windows. http://crbug.com/81723 GEN('#if defined(OS_CHROMEOS) || defined(OS_MACOSX) || defined(OS_WIN) \\'); GEN(' || defined(TOUCH_UI)'); GEN('#define MAYBE_testRefreshStaysOnCurrentPage \\'); GEN(' DISABLED_testRefreshStaysOnCurrentPage'); GEN('#else'); GEN('#define MAYBE_testRefreshStaysOnCurrentPage ' + 'testRefreshStaysOnCurrentPage'); GEN('#endif'); TEST_F('OptionsWebUITest', 'MAYBE_testRefreshStaysOnCurrentPage', function() { var item = $('advancedPageNav'); item.onclick(); window.location.reload(); var pageInstance = AdvancedOptions.getInstance(); var topPage = OptionsPage.getTopmostVisiblePage(); var expectedTitle = pageInstance.title; var actualTitle = document.title; expectEquals("chrome://settings/advanced", document.location.href); expectEquals(expectedTitle, actualTitle); expectEquals(pageInstance, topPage); }); Maintaining
Considerations/FAQs
Caveats
Best practices
// NO TEST_F('FooTest', 'TestFoo', function() { expectEquals(foo, bar, 'foo != bar'); expectEquals(foo, bar, foo + '!=' + bar); var i = ...; expectEquals(5, array[i], 'array[i] != 5'); }); // YES TEST_F('FooTest', 'TestFoo', function() { expectEquals(foo, bar); expectEquals(foo, bar); var i = ...; expectEquals(5, array[i], 'i=' + i); }); |
Chromium > DOMUI Testing >