Defect lifecycle in Testing Fundamentals - Build an Automation Script
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 DefectLifecyclePage: def __init__(self, driver): self.driver = driver self.status_dropdown = (By.ID, 'defect-status') self.save_button = (By.ID, 'save-defect') self.status_text = (By.ID, 'current-status') def select_status(self, status): dropdown = WebDriverWait(self.driver, 10).until( EC.element_to_be_clickable(self.status_dropdown)) dropdown.click() option = WebDriverWait(self.driver, 10).until( EC.element_to_be_clickable((By.XPATH, f"//select[@id='defect-status']/option[text()='{status}']"))) option.click() def save_defect(self): save_btn = WebDriverWait(self.driver, 10).until( EC.element_to_be_clickable(self.save_button)) save_btn.click() def get_status(self): status_element = WebDriverWait(self.driver, 10).until( EC.visibility_of_element_located(self.status_text)) return status_element.text class TestDefectLifecycle(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome() self.driver.get('http://defect-tracker.example.com/defect/123') # Assume user is already logged in for simplicity self.page = DefectLifecyclePage(self.driver) def test_defect_status_transitions(self): statuses = ['Assigned', 'Fixed', 'Retest', 'Closed'] for status in statuses: self.page.select_status(status) self.page.save_defect() current_status = self.page.get_status() self.assertEqual(current_status, status, f"Expected status to be '{status}' but got '{current_status}'") def tearDown(self): self.driver.quit() if __name__ == '__main__': unittest.main()
This script uses Selenium with Python and unittest framework to automate the defect lifecycle status changes.
The DefectLifecyclePage class represents the defect details page. It uses explicit waits to ensure elements are clickable or visible before interacting. This avoids timing issues.
The test_defect_status_transitions method changes the defect status through the lifecycle states one by one. After each change, it saves and verifies the status text matches the expected value.
Assertions include clear messages to help understand failures.
The setUp and tearDown methods handle browser start and cleanup.
This structure follows the Page Object Model for maintainability and uses best practices like explicit waits and meaningful assertions.
Now add data-driven testing with 3 different defect IDs to verify lifecycle transitions for multiple defects.
Practice
Solution
Step 1: Understand the meaning of 'New' state
The 'New' state means the defect is just reported and has not been assigned yet.Step 2: Compare with other states
'Fixed' means the bug is corrected, 'Retest' means testing the fix, and 'Closed' means the bug is resolved and accepted.Final Answer:
New -> Option AQuick Check:
New = Bug found but unassigned [OK]
- Confusing 'New' with 'Open' or 'Assigned'
- Thinking 'Fixed' means bug is new
- Mixing 'Retest' with initial bug discovery
Solution
Step 1: Recall the standard defect lifecycle sequence
The typical order is New (reported), Assigned (developer assigned), Open (work started), Fixed (bug fixed), Retest (testing fix), Closed (bug resolved).Step 2: Match the options with this sequence
New -> Assigned -> Open -> Fixed -> Retest -> Closed matches the correct order exactly; others have states out of order.Final Answer:
New -> Assigned -> Open -> Fixed -> Retest -> Closed -> Option AQuick Check:
Lifecycle order = B [OK]
- Mixing 'Assigned' and 'Open' order
- Placing 'Fixed' before 'Assigned'
- Confusing 'Retest' and 'Closed' positions
defect_states = ['New', 'Assigned', 'Open', 'Fixed', 'Retest', 'Closed'] current_state = 'Fixed' next_state = defect_states[defect_states.index(current_state) + 1] print(next_state)
What will be the output?
Solution
Step 1: Find the index of 'Fixed' in the list
'Fixed' is at index 3 in defect_states list.Step 2: Calculate next_state using index + 1
Index 3 + 1 = 4, so next_state = defect_states[4] which is 'Retest'.Final Answer:
Retest -> Option BQuick Check:
Next after Fixed = Retest [OK]
- Choosing 'Closed' instead of 'Retest'
- Confusing index positions
- Assuming current_state prints itself
Solution
Step 1: Understand the defect lifecycle phases
After fixing, the defect should be retested before closing to confirm the fix.Step 2: Identify the problem with skipping Retest
Marking as 'Closed' without retesting skips verification, risking unresolved bugs.Final Answer:
Skipping the Retest phase -> Option DQuick Check:
Retest must happen before Close [OK]
- Closing defect without verification
- Confusing 'Closed' with 'Fixed'
- Ignoring defect assignment order
Solution
Step 1: Understand 'Reopened' state meaning
'Reopened' means the defect was fixed but failed retesting, so it needs fixing again.Step 2: Determine the next lifecycle step
The defect should be assigned back to the developer to fix the issue properly before retesting.Final Answer:
Assign the defect back to the developer for fixing -> Option CQuick Check:
Reopened = Assign to developer [OK]
- Closing defect after failed retest
- Resetting defect to 'New' incorrectly
- Skipping fix and retesting again
Ready to prove it?
Pass the test and this pattern moves unknown
