B2G/QA/Automation/Style Guide/Python Script Style: Difference between revisions

Moved away the external consumer parts and fixed nits
(Moved away the external consumer parts and fixed nits)
 
(26 intermediate revisions by 2 users not shown)
Line 70: Line 70:
# Bad
# Bad
class test_this_site:
class test_this_site:
</source>
== Locators ==
* Locator variables should be prefixed with <code>_</code> to show that it is [http://docs.python.org/tutorial/classes.html#private-variables private].
* Variables should be descriptive of the area and not clash with any properties.
* Should have a suffix of <code>_locator</code>.
* Accessing locators should be done through a property or method as this keeps the locator as read-only.
<source lang="python">
@property
def search_term(self):
    return self.marionette.find_element(*self._search_box_locator).value
</source>
* We should use locators in the following order of preference (there will be exceptions):
** ID
** Name
** Class name
** CSS selector
** XPath
* CSS locators should use whitespace for readability when using direct descendants.
<source lang="python">
# Good
_my_locator = "css=#content > p > a"
   
# Bad
_my_locator = "css=#content>p>a"
</source>
* Use Python tuples to define locators:
<source lang="python">
# Good
_my_locator = (By.ID, "content")
</source>
</source>


Line 85: Line 119:
* Actions should wait for the appropriate action to complete. This could be an implicit or explicit wait. For example, clicking a login button might explicitly wait for a username field to be visible.
* Actions should wait for the appropriate action to complete. This could be an implicit or explicit wait. For example, clicking a login button might explicitly wait for a username field to be visible.


== Use testvars.json <njpark> ==
== Using High-Level Methods ==
Using test variable file when running gaiatest can avoid defining variables inside the script.  The testvars template is located [http://mxr.mozilla.org/gaia/source/tests/python/gaia-ui-tests/gaiatest/testvars_template.json here].
* A test script should remain a short entry point which leads to more details (like the main() function of a program). Don't detail every single tap and wait, in the test. Use methods that reflect a user's intent rather than a sequence of small steps the user has to do. The details of how to fulfill that intent will be in the page classes.
<br>
Make sure to fill in the appropriate section if you're planning to use it, and supply the name and location of the .json file as the parameter to the '''gaiatest''' command with '''--testvars=''' option.
<br><br>
If you want to access the varable value defined in the .json file, you can do as the following example:
<br>
<source lang="python">
<source lang="python">
test_phone_number = self.testvars['remote_phone_number']
# Good
messages.send_an_sms_to_yourself()
 
# Bad
messages.open_sms_app()
messages.create_new_sms(receiver)
messages.type_content(content)
messages.send()
</source>
 
== Variable Naming ==
* Name your variables with units.  
<source lang="python">
# Good
timeout_in_seconds, width_in_pixels
 
# Bad
timeout, width
</source>
</source>
<br>
* Don't shorten variable names.
If you need to access the sub-variable, consider below example as well:
<source lang="python">
<source lang="python">
self.testvars['plivo']['auth_id'],
# Good
self.testvars['plivo']['auth_token'],
self.time_out_error_time = 1000
self.testvars['plivo']['phone_number']
 
# Bad
self.t_out_err_tim = 1000
</source>
</source>


== Using high-level methods ==
== Making Tests Locale Independent ==  
TBD - jlorenzo
It is recommended to make the test scripts (and especially the helper methods) locale independent, because this enables us to test devices in RTL locale.  There are still some sections in gaiatest where it checks for the displayed English text, but unless one cannot avoid it, data-l10n-id attribute should be checked in place of any raw text comparison.
* In a test, make sure to only have steps that are high level (for instance: messages.send_an_sms_to_yourself() instead of detailing every single tap and click)
 
== Avoid sleep() calls ==
<source lang="python">
TBD - njpark
       
== Variable naming ==
        # below method will not work in a non-English locale,
TBD - jlorenzo
        # should only be used when there is no appropriate tag for the Open App button
* Name your variables with units. For example: timeout_in_seconds, width_in_pixels
        button = self.root_element.find_element(*self._install_button_locator)
* Don't shorten variable names. A bad example: self.t_out_err_tim = 1000 instead of self.time_out_error_time
        Wait(self.marionette).until(lambda m: button.text == 'Open app')
== app.py and regions/helper.py ==  
        button.tap()
TBD - njpark
 
== How to create filename strings ==
        # below code will tap 'Send Mozilla Feedback' button in any locale
TBD - njpark
        _send_feedback_locator = (By.CSS_SELECTOR, '[data-l10n-id="sendMozillaFeedback"]')
http://mxr.mozilla.org/gaia/source/tests/python/gaia-ui-tests/gaiatest/apps/settings/app.py#296
        element = Wait(self.marionette).until(
== Meaningful custom Assert() messages ==
            expected.element_present(*self._send_feedback_locator))
TBD - njpark
        Wait(self.marionette).until(expected.element_displayed(element))
https://bugzilla.mozilla.org/show_bug.cgi?id=1198449#c2
        element.tap()
== Clean up afterwards ==
</source> 
TBD - njpark
== Avoid code duplication ==
TBD - jlorenzo
* Use parameterized()
* Centralize workarounds
== Simulate end-user check ==
TBD - jlorenzo
* Check what an end-user would check.
* Make sure manifest.ini is updated with right flags


== Making test multi-locale ==
The rules of thumb are:
TBD - njpark
* We can check for the raw text in order to verify the user input (i.e., a phone number entered in the dialer app)
* we check the raw text in order to verify the input from the user (for instance a phone number put in the dialer, we verify it appears in the call log)
* We check the data-l10n-id for any string that comes from Gaia only (i.e., an error message)
* we test the l10n-id for any string that comes from Gaia only (like an error message)
== Be aware of outside consumers of ui-test ==
TBD - mwargers   
* Be aware if you change the Gaia UI test API, that outside consumers (mtbf, etc) might get broken
Confirmed users
211

edits