Search code examples
pythonbddacceptance-testing

'User changes password' acceptance test in behave


I was automating acceptance tests using behave (python), when I encountered a problem of writing test for changing password scenario.

This are my steps in test_change_password.py

from behave import *
from features.steps.common_steps import fill_in_email, fill_in_password, show_main_page, register_user, logout
from features.steps.constants import *
import time

CHANGE_PASSWORD_USER_EMAIL = 'change_password@gmail.com'

use_step_matcher("re")


def login(context, password):
    context.browser.visit("/login")
    context.browser.is_element_present_by_css("//input")
    fill_in_email(context, 'test@gmail.com')
    fill_in_password(context, password)
    context.browser.find_by_xpath("//button").first.click()

def change_password_fields_and_logout(context):
    old_pass_field = context.browser.find_by_xpath('//form/div[%s]/input' % OLD_PASS_INDEX)
    old_pass_field.fill(NEW_PASSWORD)
    new_pass_field = context.browser.find_by_xpath('//form/div[%s]/input' % NEW_PASS_INDEX)
    new_pass_field.fill(OLD_PASSWORD)
    confirm_new_pass_field = context.browser.find_by_xpath('//form/div[%s]/input' % CONFIRM_NEW_PASS_INDEX)
    confirm_new_pass_field.fill(OLD_PASSWORD)
    context.browser.find_by_xpath('//button[text()="Submit"]').first.click()
    logout(context)


@given("change password user login")
def step_impl(context):
    context.browser.visit('/login')
    context.browser.is_element_present_by_css('//h1')
    fill_in_email(context, CHANGE_PASSWORD_USER_EMAIL)
    fill_in_password(context, NEW_PASSWORD)
    context.browser.find_by_xpath("//button[@type='submit']").first.click()
    if not context.browser.is_element_present_by_text('first name last name'):
        NEW_PASSWORD, OLD_PASSWORD = OLD_PASSWORD, NEW_PASSWORD
        fill_in_password(context, NEW_PASSWORD)


@when("user changed his password")
def step_impl(context):
    context.browser.is_element_present_by_text('first name last name')
    context.browser.find_by_text("first name last name").first.click()
    context.browser.is_element_present_by_text('Change password')
    context.browser.find_by_xpath('//a[text()="Change password"]').first.click()
    change_password_fields_and_logout(context)


@then("user login with new password")
def step_impl(context):
    login(context, NEW_PASSWORD)

It works as expected the first time I run tests, but because it changes user's password in DB, I have to swap values of NEW_PASSWORD and OLD_PASSWORD or truncate DB and seed my fixtures before running tests.

I think that there are better, more automated ways of doing it.


Solution

    1. Connect to database and insert new user in set up method.
    2. Test changing the password for added user in step 1.
    3. Remove user from the database in the test clean up.

      You can use environmental-controls for set up and clean up or you could write you own steps for that.