Naming convention
Last modified on Fri 22 Jul 2022

Talent wins games, but teamwork and intelligence win championships. – Michael Jordan

Why follow a naming convention:

On a small project, or while working alone, you might get away with naming inconsistency. As the project grows, or more people join, the code becomes less readable and the work and maintenance more difficult.

Basic principles:

When it comes to name casing, you should use snake_case (lower case with underscores separating the words) as per Python naming convention.

Code examples are in Python and comply with PEP 8 – Style Guide for Python Code.

Variables

You should use nouns or short phrases with adjectives to describe what is stored in the variable.

Bad:

dwtz

User_with_name_and_age

Better:

date_with_timezone

user_data

Boolean

When naming a variable that stores a boolean value, think of it as asking a question to which the answer is Yes or No.

Bad:

ok

correct

Better:

is_valid

is_correct

Constants

For constants, use all capital letters with underscores separating words. Constants should store values that never change.

Bad:

name_of_the_app

Better:

APP_NAME

Methods / Functions

Functions and methods perform an action such as returning a value after a calculation, checking if a value is valid, etc. You typically want to use verbs or short phrases with adjectives that describe what the function or method does.

For example, when getting a value, always prefix the name with get_. Use the prefix consistently throughout the project. Do not switch between synonyms like fetch or retrieve.

Bad:

name()

Better:

get_name()

Boolean

When a function returns a boolean value, it must be clear from the name that the return type is a boolean value.

Bad:

valid_email()

name_in()

Better:

is_email_valid()

has_name()

Depending on whether you are writing a function that stands on its own, or a method which belongs to an object, you might want to consider the name length. If a function stands on its own, it would be better to write a clearer name, such as save_user_data. If a method belongs to the User object, you could name it save_data.

Classes

Use nouns or short phrases with nouns that describe the object the class creates.

When it comes to name casing, use upper camel case for class names.

Bad:

pagethathandleslogin

dialog_window

Better:

LoginPage

DialogWindow

Packages and modules

As defined in PEP 8, packages and modules should have short, all-lowercase names. The use of underscores is discouraged, however, you can add them to improve readability or to avoid name collision.

NOTE: Be careful with short names such as email because it might collide with the existing email module and break your code. In this case, you could use email_methods or similar instead.

Bad:

emailmodule

helperMethods

Better:

email_module

helper_methods

Example: UI elements and methods

The tables below show a few examples on how to use suffixes and prefixes in your project to make the code easy to understand. Use them consistently.

Variables

UI Suffix Example
Button _button submit_button
Image _image profile_image
Label _label project_name_label
Slider _slider volume_slider

Methods / Functions

Action Prefix Example
Get current time get_ get_current_time()
Generate a name generate_ generate_random_name()
Clear name field clear_ clear_name_field()
Open user details open_ open_user_details()

Example: page and test classes

Tests are methods so consider the naming convention when writing the test name as well. In most frameworks, a test method must have either the prefix test_ or the suffix _test. The rest is up to you. Following the basic principles, write meaningful and concise names without redundant information.

In case of a page class, you can add __ before the locator name to make it "private" and only available to the methods of the page class.

Page class

class CreateProjectPage(BasePage):

    def __init__(self, driver, environment, package_name, platform):
        super().__init__(driver, environment, package_name, platform)

        self.__create_project_button_locator = {
            ANDROID: (MobileBy.ID, f"{self.package_name}:id/btnSubmit"),
            IOS: (MobileBy.ACCESSIBILITY_ID, "Create")
        }

        self.__project_name_input_locator = {
            ANDROID: (MobileBy.ACCESSIBILITY_ID, "Project name"),
            IOS: (MobileBy.ACCESSIBILITY_ID, "Project name")
        }

    @property
    def create_project_button(self):
        return self.get_present_element(self.__create_project_button_locator[self.platform])

    @property
    def project_name_input(self):
        return self.get_present_element(self.__project_name_input_locator[self.platform])

Test class

class TestProjectScenarios:

    def test_create_project(self, initialize_pages):

        project_name = "Project"            

        self.create_project_page.project_input.send_keys(project_name)
        self.create_project_page.create_project_button.click()

        check.is_equal(self.project_page.project_name_label.text, project_name)