В предишните ни статии се запознахме със стратегиите за ефективно тестване и дебъгване на Python код, както и с използването на визуализации за подобряване на процеса на дебъгване. Днес ще разгледаме един интересен и полезен подход за тестване – Разработване чрез поведение (Behavior-Driven Development или BDD) с помощта на инструмента pytest-bdd. Ще видим как BDD тестовете могат да ни помогнат да пишем по-ясен, четим и поддържан тестов код, който служи и като жива документация за поведението на нашите системи. Да започваме!

Какво е Разработване чрез поведение (BDD)?

BDD е техника за разработка на софтуер, която комбинира идеите от Разработката чрез тестове (Test-Driven Development или TDD) и Приемащото тестване (Acceptance Testing). Основната цел на BDD е да подобри комуникацията и сътрудничеството между разработчици, тестери и нетехнически заинтересовани страни (като мениджъри на продукти и бизнес анализатори) чрез използване на общ, разбираем език за описване на желаното поведение на системата.

В BDD, изискванията или функционалностите се описват като сценарии или примери във формат „Given-When-Then“:

  • Given (Дадено): Начално състояние или предпоставка;
  • When (Когато): Събитие или действие, което се случва;
  • Then (Тогава): Очаквания резултат или изход.

Например:


Feature: Login
  Scenario: Successful Login
    Given a user with a valid account
    When the user enters their correct credentials
    Then the user should be logged in and redirected to the dashboard

Tези сценарии служат като база за комуникация и се използват за генериране на изпълними тестове, които валидират дали системата се държи според очакванията.

BDD с pytest-bdd

Pytest-bdd е плъгин за популярната тестова рамка pytest, който позволява писането на BDD тестове на Python. Той използва формат, подобен на Gherkin (езикът, използван в инструменти като Cucumber) за дефиниране на тестови сценарии и ни позволява да ги изпълняваме като нормални pytest тестове.

Нека видим как можем да напишем BDD тестове с pytest-bdd, използвайки примера за вход на потребител от по-горе.

Първо, инсталираме pytest-bdd:


pip install pytest-bdd

След това създаваме файл login.feature за нашия тестов сценарий:


Feature: Login
  Scenario: Successful Login
    Given a user with a valid account
    When the user enters their correct credentials
    Then the user should be logged in and redirected to the dashboard

Сега създаваме файл test_login.py за нашите тестови стъпки:


from pytest_bdd import given, when, then, scenario
from myapp.models import User

@scenario('login.feature', 'Successful Login')
def test_successful_login():
    pass

@given('a user with a valid account')
def user():
    return User.objects.create(username='testuser', password='password')

@when('the user enters their correct credentials')
def login(user, client):
    client.post('/login', {'username': 'testuser', 'password': 'password'})

@then('the user should be logged in and redirected to the dashboard')
def check_login(user, client):
    response = client.get('/dashboard')
    assert response.status_code == 200
    assert b'Welcome, testuser' in response.content

Нека да анализираме какво се случва тук:

  1. Използваме декоратора @scenario за да свържем нашата тестова функция test_successful_login със сценария ‘Successful Login’ от login.feature.
  2. Дефинираме стъпките given, when и then като функции, декорирани със съответните декоратори. Тези функции приемат аргументи, генерирани от pytest-bdd въз основа на сценария (напр. user и client).
  3. В @given стъпката създаваме потребител в базата данни. Това е предпоставката за нашия тест.
  4. В @when стъпката симулираме изпращане на форма за вход с правилните идентификационни данни на потребителя.
  5. В @then стъпката проверяваме дали потребителят е влязъл успешно и е пренасочен към таблото, като правим проверки върху отговора.

Вече можем да изпълним нашия BDD тест с pytest:


pytest test_login.py

Pytest-bdd автоматично ще открие сценария и стъпките и ще изпълни теста. Ако всичко е наред, ще видим, че тестът преминава успешно.

Ползи от използването на BDD тестове

Писането на BDD тестове с инструмент като pytest-bdd носи няколко ключови ползи:

  1. Подобрена комуникация: BDD сценариите служат като обща основа за разработчици, тестери и бизнес заинтересовани страни. Те са написани на прост, разбираем език, който насърчава сътрудничеството и подобрява комуникацията.
  2. Изпълнима документация: BDD сценариите действат като изпълнима документация за поведението на системата. Те винаги са в крак с актуалния код и дават ясна картина на това какво прави системата.
  3. Фокус върху потребителската гледна точка: Чрез описване на функционалностите като сценарии, BDD ни помага да се съсредоточим върху ползите за крайния потребител, вместо върху техническите детайли. Това води до софтуер, който по-добре отговаря на реалните нужди.
  4. Четим и поддържан тестов код: BDD тестовете следват ясна структура и използват езикови конструкции от високо ниво. Това ги прави по-лесни за четене и поддръжка в сравнение с традиционните unit тестове.
  5. Интеграция с инструменти за отчети: Много BDD инструменти, включително pytest-bdd, поддържат генериране на HTML доклади, които показват резултатите от тестовете заедно с оригиналните сценарии. Това прави резултатите лесно разбираеми за всички заинтересовани страни.

Най-добри практики при използване на BDD тестове

За да извлечете максимална полза от BDD тестовете, имайте предвид следните най-добри практики:

  1. Включете цялостни сценарии: Стремете се да покриете най-важните сценарии за използване на вашата система, включително щастливите пътища и често срещаните граници и грешки. Фокусирайте се върху тестване от гледна точка на потребителя.
  2. Поддържайте стъпките прости: Всяка стъпка трябва да представлява едно ясно действие или проверка. Избягвайте сложни условия или разклонения в стъпките. В случай на нужда, разделете сценариите на по-малки.
  3. Използвайте параметризация: Pytest-bdd поддържа параметризация на сценариите чрез примери. Това позволява изпълнение на един и същ сценарий с различни входни данни, което подобрява покритието на тестовете.
  4. Споделяйте контекста между стъпките: Използвайте функции-фикстури на pytest за инжектиране на общи обекти (като клиенти на уеб приложения или обекти от базата данни) в стъпките. Това намалява дублирането и прави стъпките по-независими.
  5. Интегрирайте с CI/CD: Включете изпълнението на BDD тестовете във вашия непрекъснат интеграционен процес. Това осигурява постоянна обратна връзка за състоянието на функционалностите и помага за ранното откриване на регресии.

Заключение

В тази статия разгледахме какво представлява BDD и как можем да пишем BDD тестове на Python с помощта на pytest-bdd. Видяхме как BDD сценариите могат да подобрят комуникацията, да служат като изпълнима, „жива“ документация и да доведат до по-четим и поддържан тестов код.

Въпреки че BDD не е универсално решение и не премахва нуждата от други видове тестове (като unit и интеграционни тестове), той е мощен инструмент в арсенала на всеки отговорен софтуерен екип. Чрез описване на очакваното поведение в общ език и автоматизация на тези сценарии, можем да постигнем по-добро съгласуване между заинтересованите страни и по-високо качество на софтуера.

Надяваме се тази статия да е предизвикала интереса ви към BDD и pytest-bdd. Ефективното тестване е ключова практика в модерната софтуерна разработка – и BDD може да бъде мощен съюзник в тази задача.

Последно обновяване: май 31, 2024