В чем разница между Self и Cls?

«В чем разница между Self и Cls?» — вопрос из категории Python, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Вопрос не соответствует категории "QA / Тестирование". В контексте тестирования на Python, self и cls используются при создании вспомогательных классов, фикстур или паттернов (например, Page Object).

  • self — это ссылка на экземпляр класса. Используется в обычных методах для доступа к атрибутам и методам конкретного объекта. В тестах через self мы обращаемся к драйверу браузера, данным теста или вспомогательным методам.
  • cls — это ссылка на сам класс. Используется в методах класса, помеченных декоратором @classmethod. Такие методы полезны для настройки, общей для всех тестов в классе (например, одноразовая инициализация).

Практический пример в тестах с использованием Pytest и Page Object Model:

import pytest
from selenium.webdriver.common.by import By

class LoginPage:
    # Элементы страницы
    USERNAME_INPUT = (By.ID, "username")
    PASSWORD_INPUT = (By.ID, "password")
    SUBMIT_BUTTON = (By.ID, "submit")

    def __init__(self, driver):
        # 'self.driver' - это конкретный экземпляр WebDriver для этого объекта страницы
        self.driver = driver

    # Обычный метод экземпляра (использует self)
    def login(self, username, password):
        self.driver.find_element(*self.USERNAME_INPUT).send_keys(username)
        self.driver.find_element(*self.PASSWORD_INPUT).send_keys(password)
        self.driver.find_element(*self.SUBMIT_BUTTON).click()

class TestLogin:
    # Метод класса (использует cls). Выполняется один раз перед всеми тестами в классе.
    @classmethod
    def setup_class(cls):
        # 'cls.driver' будет атрибутом класса, доступным всем тестам
        cls.driver = webdriver.Chrome()
        cls.driver.implicitly_wait(10)

    # Каждый тестовый метод - это метод экземпляра (использует self)
    def test_valid_login(self):
        # 'self.driver' здесь наследуется от класса
        login_page = LoginPage(self.driver)
        login_page.login("test_user", "secure_pass")
        assert "Dashboard" in self.driver.title

    @classmethod
    def teardown_class(cls):
        cls.driver.quit()

Таким образом, self работает с состоянием конкретного теста или объекта, а cls — с настройками, общими для всей группы тестов.