QA/Execution/Web Testing/Docs/Automation/StyleGuide: Difference between revisions

no edit summary
No edit summary
Line 1: Line 1:
The goal of the style guide is to try provide rules to write code that looks the same no matter what project. It is a guide and is always up for discussion by the team. I have created [https://github.com/AutomatedTester/mozwebqa-test-templates templates] based on the details below.
The goal of the style guide is to try provide rules to write code that looks the same no matter what project. It is a guide and is always up for discussion by the team. I have created [https://github.com/AutomatedTester/mozwebqa-test-templates templates] based on the details below.


=All Files=
= All Files =
==File headers==
 
*At the top of each file should have python file header


== File Headers ==
* At the top of each file should have python file header
<pre class="brush:py;toolbar:false;">
<pre class="brush:py;toolbar:false;">
     #!/usr/bin/env python
     #!/usr/bin/env python
</pre>
</pre>
 
* Each file should have a completed copy of the [http://www.mozilla.org/MPL/boilerplate-1.1/mpl-tri-license-sh MPL]
*Each file should have a completed copy of the [http://www.mozilla.org/MPL/boilerplate-1.1/mpl-tri-license-sh MPL]
* Each file should pass [http://www.python.org/dev/peps/pep-0008/ PEP8] except for line length, see below.   
 
*Each file should pass [http://www.python.org/dev/peps/pep-0008/ PEP8] except for line length, see below.   
** I.e. parameters  should have a comma and a space e.g.
** I.e. parameters  should have a comma and a space e.g.
 
<pre class="brush:py;toolbar:false;">
<pre class="brush:py;toolbar:false;">
     # Good
     # Good
Line 22: Line 18:
     def method(self,parameter)
     def method(self,parameter)
</pre>
</pre>
 
** Lines should try not to have more than 100 characters.
**Lines should try not to have more than 100 characters. This allows 2 files to be side by side with no overlap for easier development.(I base this on MacVim on my MBP)
** Indenting should be a soft tab (4 spaces) as common with in Python. Do not mix tabs and spaces!
**Indenting should be a soft tab(4 spaces) as common with in Python. Do not mix tabs and spaces
** There should be no whitespace at the end of the file (as per PEP8)
**There should be no whitespace at the end of the file(as per PEP8)
** Comments should be on the line above. Remember to update comments when changing code so that code matches the comments.
**Comments should be on the line above. Remember to update comments when changing code so that code matches the comments.
** Class names should be in Pascal style as this is Python idiomatic.
**Class names should be in Pascal style as this is Python idiomatic
 
<pre class="brush:py;toolbar:false;">
<pre class="brush:py;toolbar:false;">
     # Good
     # Good
Line 37: Line 31:
</pre>
</pre>


== Page Object Style Guide ==
= Page Objects =
* All Page Objects should inherit from Page in page.py
== General ==
* Page Objects should not do asserts. This should be done within the test
* All Page Objects should inherit from Page in page.py.
* Each Page should be grouped within one module
* Page Objects should not do asserts. This should be done within the test.
* Each Page should be grouped within one module.
* If using mutliple words to describe a module separate them with underscores '_'
* If using mutliple words to describe a module separate them with underscores '_'
     test_search.py
     test_search.py
* Timeout time should be taken from conftest.py
* Timeout time should be taken from pytest-mozwebqa via page.py's timeout property.
* Locators Class Variables
 
** Locator variables should be prefixed with _ to show that it is "[http://docs.python.org/tutorial/classes.html#private-variables private]"
== Locators ==
** Variables should be descriptive of the area and not clash with any properties
** Locator variables should be prefixed with _ to show that it is "[http://docs.python.org/tutorial/classes.html#private-variables private]".
** Suffix of _locator
** Variables should be descriptive of the area and not clash with any properties.
* Accessing Locator Variables
** Suffix of _locator.
** Accessing Locators should be done through a property method as this keeps the locator as readonly.
** Accessing Locators should be done through a property method as this keeps the locator as readonly.
<pre class="brush:py;toolbar:false;">
<pre class="brush:py;toolbar:false;">
Line 61: Line 56:
         return self.selenium.get_title()
         return self.selenium.get_title()
</pre>
</pre>
* Action methods
* We should use locators in the following order of preference (there will be exceptions):
** Methods that perform actions on the page should indicate the action in the method name
** ID
** Name
** CSS
** XPath
* Locators should include the strategy instead of using implied strategies.
<pre class="brush:py;toolbar:false;">
    # Good
    _my_locator = "id=content"
   
    # Bad
    _my_locator = "content"
</pre>
* CSS locators should use whitespace for readability when using direct descendants.
<pre class="brush:py;toolbar:false;">
    # Good
    _my_locator = "css=#content > p > a"
   
    # Bad
    _my_locator = "css=#content>p>a"
</pre>
 
== Actions ==
* Methods that perform actions on the page should indicate the action in the method name.
<pre class="brush:py;toolbar:false;">
<pre class="brush:py;toolbar:false;">
     # Good
     # Good
Line 71: Line 88:
</pre>
</pre>


== Test Style Guide ==
= Tests =
* Module names should be called test_ and then behavioural areas. E.g. test_search_positive.py
* Module names should be called test_ and then behavioral areas.
* Test setup should read in details from conftest.py
    test_search_positive.py
* Test Case names should always show the intent of the test case.
* Test method signature should include mozwebqa to use pytest-mozwebqa plugin.
<pre class="brush:py;toolbar:false;">
    def test_example(self, mozwebqa):
</pre>
* Test method names should always show the intent of the test case.
<pre class="brush:py;toolbar:false;">
<pre class="brush:py;toolbar:false;">
     # Good
     # Good
     def test_that_advanced_search_doesnt_find_item(self, testsetup):
     def test_that_advanced_search_does_not_find_item(self, mozwebqa):


     # Bad
     # Bad
     def test_advanced_search(self):
     def test_advanced_search(self, mozwebqa):
</pre>
</pre>
* Tests should handle the asserts not the Page objects
* Tests should handle the asserts -- not the page objects.
 
==Size of patches==


To make sure that we can review your patch as quickly and efficiently as possibly we would like patches to have 1 test in them and the necessary changes to the Page Objects. This also limits the chances of merge conflicts laters.
= Size of patches =
To make sure that we can review your patch as quickly and efficiently as possibly we would like patches to have 1 test in them and the necessary changes to the Page Objects. This also limits the chances of merge conflicts later.
Confirmed users
2,197

edits