0
0
Testing Fundamentalstesting~15 mins

Why Agile changes testing dynamics in Testing Fundamentals - Automation Benefits in Action

Choose your learning style9 modes available
Verify Agile sprint testing process updates
Preconditions (3)
Step 1: Open the Agile project management tool
Step 2: Navigate to the current sprint backlog
Step 3: Select a user story marked as 'Ready for Testing'
Step 4: Execute the associated test cases for the user story
Step 5: Log any defects found during testing
Step 6: Update the test status to 'Passed' if no defects found
Step 7: Verify that test results are visible in the sprint dashboard
✅ Expected Result: Test cases execute successfully, defects are logged if any, and test status updates reflect correctly in the sprint dashboard
Automation Requirements - Selenium with Python
Assertions Needed:
Verify user story status is 'Ready for Testing'
Verify test execution completes without errors
Verify defect logging functionality works
Verify test status updates to 'Passed' after successful execution
Verify sprint dashboard displays updated test results
Best Practices:
Use explicit waits to handle dynamic page elements
Use Page Object Model to organize locators and actions
Use clear and descriptive assertion messages
Avoid hardcoded waits and brittle locators
Clean up test data after execution if needed
Automated Solution
Testing Fundamentals
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import unittest

class AgileSprintTesting(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.get('https://agile-tool.example.com/login')
        self.wait = WebDriverWait(self.driver, 10)
        # Login
        self.driver.find_element(By.ID, 'username').send_keys('tester')
        self.driver.find_element(By.ID, 'password').send_keys('TestPass123')
        self.driver.find_element(By.ID, 'login-btn').click()

    def test_agile_sprint_testing(self):
        driver = self.driver
        wait = self.wait

        # Navigate to current sprint backlog
        wait.until(EC.element_to_be_clickable((By.ID, 'sprint-backlog-link'))).click()

        # Select user story with status 'Ready for Testing'
        user_stories = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.user-story')))
        target_story = None
        for story in user_stories:
            status = story.find_element(By.CSS_SELECTOR, '.status').text
            if status == 'Ready for Testing':
                target_story = story
                break
        self.assertIsNotNone(target_story, 'No user story with status Ready for Testing found')

        # Open user story details
        target_story.find_element(By.CSS_SELECTOR, '.details-btn').click()

        # Execute test cases
        test_cases = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.test-case')))
        for test_case in test_cases:
            test_case.find_element(By.CSS_SELECTOR, '.execute-btn').click()
            # Wait for execution result
            result = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, '.execution-result'))).text
            self.assertIn(result, ['Pass', 'Fail'], 'Execution result should be Pass or Fail')
            if result == 'Fail':
                # Log defect
                test_case.find_element(By.CSS_SELECTOR, '.log-defect-btn').click()
                defect_desc = wait.until(EC.visibility_of_element_located((By.ID, 'defect-description')))
                defect_desc.send_keys('Automated defect logged during test execution')
                driver.find_element(By.ID, 'submit-defect-btn').click()

        # Update test status to Passed if no defects
        defects = driver.find_elements(By.CSS_SELECTOR, '.defect')
        if len(defects) == 0:
            driver.find_element(By.ID, 'update-status-btn').click()
            status_text = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, '.status'))).text
            self.assertEqual(status_text, 'Passed', 'Test status should update to Passed')

        # Verify sprint dashboard shows updated results
        driver.find_element(By.ID, 'sprint-dashboard-link').click()
        dashboard_status = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, f'.user-story-status[data-story-id="{target_story.get_attribute("data-id")}"]'))).text
        self.assertIn(dashboard_status, ['Passed', 'Failed'], 'Sprint dashboard should show updated test status')

    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main()

This test script automates the Agile sprint testing process using Selenium with Python.

Setup: Opens the browser, navigates to the Agile tool login page, and logs in with test credentials.

Test Steps: Navigates to the current sprint backlog, finds a user story ready for testing, executes its test cases, logs defects if any test fails, updates the test status to 'Passed' if no defects, and verifies the sprint dashboard reflects the updated status.

Assertions: Check that the user story is ready for testing, test execution results are valid, defects can be logged, status updates correctly, and dashboard shows the latest status.

Best Practices: Uses explicit waits to handle dynamic elements, uses clear selectors, and includes meaningful assertion messages to help identify issues.

Common Mistakes - 4 Pitfalls
Using hardcoded sleep() calls instead of explicit waits
Using brittle XPath locators that break easily
{'mistake': "Not verifying that the user story is in 'Ready for Testing' status before proceeding", 'why_bad': 'Test may run on wrong data leading to false results', 'correct_approach': 'Assert the status before executing test cases'}
Not cleaning up or resetting test data after test execution
Bonus Challenge

Now add data-driven testing with 3 different user stories having different statuses

Show Hint