В предишните ни статии се запознахме със стратегиите за ефективно тестване и дебъгване на 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
Нека да анализираме какво се случва тук:
- Използваме декоратора
@scenario
за да свържем нашата тестова функцияtest_successful_login
със сценария ‘Successful Login’ отlogin.feature
. - Дефинираме стъпките
given
,when
иthen
като функции, декорирани със съответните декоратори. Тези функции приемат аргументи, генерирани от pytest-bdd въз основа на сценария (напр.user
иclient
). - В
@given
стъпката създаваме потребител в базата данни. Това е предпоставката за нашия тест. - В
@when
стъпката симулираме изпращане на форма за вход с правилните идентификационни данни на потребителя. - В
@then
стъпката проверяваме дали потребителят е влязъл успешно и е пренасочен към таблото, като правим проверки върху отговора.
Вече можем да изпълним нашия BDD тест с pytest:
pytest test_login.py
Pytest-bdd автоматично ще открие сценария и стъпките и ще изпълни теста. Ако всичко е наред, ще видим, че тестът преминава успешно.
Ползи от използването на BDD тестове
Писането на BDD тестове с инструмент като pytest-bdd носи няколко ключови ползи:
- Подобрена комуникация: BDD сценариите служат като обща основа за разработчици, тестери и бизнес заинтересовани страни. Те са написани на прост, разбираем език, който насърчава сътрудничеството и подобрява комуникацията.
- Изпълнима документация: BDD сценариите действат като изпълнима документация за поведението на системата. Те винаги са в крак с актуалния код и дават ясна картина на това какво прави системата.
- Фокус върху потребителската гледна точка: Чрез описване на функционалностите като сценарии, BDD ни помага да се съсредоточим върху ползите за крайния потребител, вместо върху техническите детайли. Това води до софтуер, който по-добре отговаря на реалните нужди.
- Четим и поддържан тестов код: BDD тестовете следват ясна структура и използват езикови конструкции от високо ниво. Това ги прави по-лесни за четене и поддръжка в сравнение с традиционните unit тестове.
- Интеграция с инструменти за отчети: Много BDD инструменти, включително pytest-bdd, поддържат генериране на HTML доклади, които показват резултатите от тестовете заедно с оригиналните сценарии. Това прави резултатите лесно разбираеми за всички заинтересовани страни.
Най-добри практики при използване на BDD тестове
За да извлечете максимална полза от BDD тестовете, имайте предвид следните най-добри практики:
- Включете цялостни сценарии: Стремете се да покриете най-важните сценарии за използване на вашата система, включително щастливите пътища и често срещаните граници и грешки. Фокусирайте се върху тестване от гледна точка на потребителя.
- Поддържайте стъпките прости: Всяка стъпка трябва да представлява едно ясно действие или проверка. Избягвайте сложни условия или разклонения в стъпките. В случай на нужда, разделете сценариите на по-малки.
- Използвайте параметризация: Pytest-bdd поддържа параметризация на сценариите чрез примери. Това позволява изпълнение на един и същ сценарий с различни входни данни, което подобрява покритието на тестовете.
- Споделяйте контекста между стъпките: Използвайте функции-фикстури на pytest за инжектиране на общи обекти (като клиенти на уеб приложения или обекти от базата данни) в стъпките. Това намалява дублирането и прави стъпките по-независими.
- Интегрирайте с CI/CD: Включете изпълнението на BDD тестовете във вашия непрекъснат интеграционен процес. Това осигурява постоянна обратна връзка за състоянието на функционалностите и помага за ранното откриване на регресии.
Заключение
В тази статия разгледахме какво представлява BDD и как можем да пишем BDD тестове на Python с помощта на pytest-bdd. Видяхме как BDD сценариите могат да подобрят комуникацията, да служат като изпълнима, „жива“ документация и да доведат до по-четим и поддържан тестов код.
Въпреки че BDD не е универсално решение и не премахва нуждата от други видове тестове (като unit и интеграционни тестове), той е мощен инструмент в арсенала на всеки отговорен софтуерен екип. Чрез описване на очакваното поведение в общ език и автоматизация на тези сценарии, можем да постигнем по-добро съгласуване между заинтересованите страни и по-високо качество на софтуера.
Надяваме се тази статия да е предизвикала интереса ви към BDD и pytest-bdd. Ефективното тестване е ключова практика в модерната софтуерна разработка – и BDD може да бъде мощен съюзник в тази задача.