BCA 204 P
Software Testing Lab
Practical File
Name: Kashvi Anand
Path: C:\kashvi_anand\stlab\practicals
Session: 2024–25
Program 1 — Identify and Classify Bugs
AIM: Write a small program in Python with intentional bugs. Identify and classify them as error, fault, or failure.
Code :-
# p01_bugs.py
# BUG 1: ERROR — ZeroDivisionError (crashes execution)
def divide(a, b):
return a / b # no check for b == 0
# BUG 2: FAULT — Wrong operator (wrong logic, no crash)
def add(a, b):
return a - b # should be a + b
# BUG 3: FAILURE — Off-by-one (wrong observable output)
def print_five():
for i in range(4): # should be range(5)
print(i)
print("=== Intentional Bug Program ===\n")
print("Bug 1 (Error) — Division by zero:")
try:
divide(10, 0)
except ZeroDivisionError as e:
print(f" ZeroDivisionError: {e}")
print(" >> Classified as: ERROR (crashes execution)\n")
print("Bug 2 (Fault) — Wrong operator:")
r = add(5, 3)
print(f" Output: {r} (expected: 8)")
print(" >> Classified as: FAULT (wrong logic, no crash)\n")
print("Bug 3 (Failure) — Off-by-one in loop:")
count = sum(1 for _ in range(4))
print(f" Loop ran {count} times instead of 5")
print(" >> Classified as: FAILURE (observable wrong output)")
Output :-
Program 2 — Test Case Document for Login Form
AIM: Create a test case document for a login form and perform testing.
Code :-
# p02_testcases.py
def login(username, password):
VALID_USER, VALID_PASS = "user", "pass123"
if not username or not password:
return "Error: Fields cannot be empty"
if "'" in username or "--" in username:
return "Error: Invalid characters"
if username == VALID_USER and password == VALID_PASS:
return "Login Successful"
return "Error: Invalid credentials"
test_cases = [
("TC01", "Valid credentials", "user", "pass123", "Login Successful"),
("TC02", "Empty username", "", "pass123", "Error:"),
("TC03", "Empty password", "user", "", "Error:"),
("TC04", "Both empty", "", "", "Error:"),
("TC05", "Wrong password", "user", "wrong", "Error:"),
("TC06", "SQL injection", "admin'--", "any", "Error:"),
("TC07", "Valid with spaces", "user", "pass123", "Login Successful"),
]
print("===== LOGIN FORM TEST CASES =====\n")
passed = 0
for tc, desc, u, p, exp in test_cases:
res = login(u, p)
ok = "PASS ✓" if exp in res else "FAIL ✗"
if "PASS" in ok: passed += 1
print(f"{tc} | {desc:<28} | {ok}")
print(f"\nTotal: {len(test_cases)} | Passed: {passed} | Failed: {len(test_cases)-passed}")
Output :-
Program 3 — STLC Flowchart
AIM: Create a flowchart / diagram of STLC using offline drawing tools (matplotlib).
Code :-
# p03_stlc.py
import [Link] as plt
import [Link] as mpatches
fig, ax = [Link](figsize=(6, 10))
ax.set_xlim(0, 6); ax.set_ylim(0, 10); [Link]('off')
phases = [
("1. Requirement Analysis", "Feasibility study, RTM creation", 9.0, "#4472C4"),
("2. Test Planning", "Strategy, scope, schedule", 7.5, "#ED7D31"),
("3. Test Case Design", "Write & review test cases", 6.0, "#A9D18E"),
("4. Environment Setup", "Configure tools & environment", 4.5, "#FFD966"),
("5. Test Execution", "Run tests, log defects", 3.0, "#F4B942"),
("6. Test Cycle Closure", "Reports & lessons learned", 1.5, "#9DC3E6"),
]
for title, sub, y, col in phases:
ax.add_patch([Link]((0.5, y-.55), 5, .9,
boxstyle="round,pad=0.1", facecolor=col, edgecolor='black', lw=1.5))
[Link](3, y+.1, title, ha='center', fontsize=10, fontweight='bold')
[Link](3, y-.25, sub, ha='center', fontsize=8, color='#333')
if y > 1.5:
[Link]('', xy=(3, y-.65), xytext=(3, y-.85),
arrowprops=dict(arrowstyle='->', color='black', lw=1.5))
[Link]("Software Testing Life Cycle (STLC)", fontsize=13, fontweight='bold')
plt.tight_layout()
[Link]('stlc_flowchart.png', dpi=120, bbox_inches='tight')
print("✓ STLC Flowchart saved.")
Output :-
Program 4 — Form Validation Test Cases
AIM: Write test cases for form validation and explain how it satisfies verification and validation.
Code :-
# p04_formvalidation.py
import re
from datetime import date
def validate_form(name, email, phone, dob):
errors = []
if not [Link]():
[Link]("Name required")
if not [Link](r'^[\w.-]+@[\w.-]+\.\w{2,}$', email):
[Link]("Invalid email")
if not [Link](r'^\d{10}$', phone):
[Link]("Phone must be 10 digits")
try:
y, m, d = map(int, [Link]('-'))
if date(y, m, d) > [Link]():
[Link]("DOB cannot be future")
except:
[Link]("Invalid date")
return errors if errors else ["VALID"]
cases = [
("Kashvi", "[Link]", "9876543210", "2000-01-01", "TC01 Email missing @"),
("Kashvi", "k@[Link]", "abc123", "2000-01-01", "TC02 Non-digit phone"),
("", "k@[Link]", "9876543210", "2000-01-01", "TC03 Empty name"),
("Kashvi", "k@[Link]", "9876543210", "2099-01-01", "TC04 Future DOB"),
("Kashvi", "k@[Link]", "9876543210", "2000-01-01", "TC05 All valid"),
]
print("===== FORM VALIDATION TEST CASES =====\n")
for name, email, phone, dob, label in cases:
res = validate_form(name, email, phone, dob)
ok = "PASS ✓" if ([Link]("TC05")) == (res==["VALID"]) else "FAIL ✗"
print(f" {label}: {res[0]} [{ok}]")
Output :-
Program 5 — Code Review — Logic, Formatting & Style
AIM: Review a piece of code for logic, formatting, and style issues.
Code :-
# p05_codereview.py
issues = {
"LOGIC": [
"Line 4: Off-by-one — range(len(nums)-1) skips last element",
"Line 8: Both branches of if-else return same value (redundant)",
],
"FORMATTING": [
"Line 2: Missing spaces around = (PEP8: use total = 0)",
"Line 6: Missing spaces around > (PEP8: use total > 42)",
],
"STYLE": [
"Line 1: camelCase name — use snake_case: calculate_sum",
"Line 6: Magic number 42 — define constant: THRESHOLD = 42",
],
}
print("===== CODE REVIEW REPORT =====\n")
print("File: sample_code.py\n")
total = 0
for cat, items in [Link]():
print(f"{cat} ISSUES:")
for item in items:
print(f" {item}")
total += 1
print()
print(f"Total Issues Found: {total} [Logic:2 | Format:2 | Style:2]")
Output :-
Program 6 — Black-Box Testing with Input Combinations
AIM: Write test cases with different input combinations without looking at the code.
Code :-
# p06_blackbox.py
# Testing add(a, b) as a black box — no source code visible
def add(a, b): # treated as black box
return a + b
cases = [
((2, 3), 5, "Positive integers"),
((-1, 1), 0, "Negative + Positive"),
((0, 0), 0, "Both zero"),
((1000, 2000), 3000, "Large numbers"),
(('a', 2), TypeError, "String input"),
((None, 5), TypeError, "None input"),
]
print("===== BLACK BOX TESTING =====\n")
passed = 0
for (a, b), exp, desc in cases:
try:
got = add(a, b)
status = "PASS ✓" if got == exp else "FAIL ✗"
disp = str(got)
except Exception as e:
status = "PASS ✓" if type(e) == exp else "FAIL ✗"
disp = type(e).__name__
if "PASS" in status: passed += 1
print(f" ({a}, {b}) => {disp:<10} {desc:<20} {status}")
print(f"\n{passed}/{len(cases)} tests passed.")
Output :-
Program 7 — Age Form — Boundary Value Analysis
AIM: Test a form that accepts age (1–100). Check with values 0, 1, 2, 99, 100, 101.
Code :-
# p07_age_bva.py
def validate_age(age):
if age < 1 or age > 100:
return "Invalid"
return "Valid"
# BVA: min-1, min, min+1, max-1, max, max+1
bva = [
(0, "Invalid", "Below minimum"),
(1, "Valid", "Lower boundary"),
(2, "Valid", "Just above min"),
(99, "Valid", "Just below max"),
(100, "Valid", "Upper boundary"),
(101, "Invalid", "Above maximum"),
]
print("===== AGE FORM — BOUNDARY VALUE ANALYSIS =====")
print(f"Valid Range: 1 to 100\n")
print(f"{'Age':<6} {'Expected':<12} {'Got':<12} {'Description':<22} Status")
print("-" * 65)
passed = 0
for age, exp, desc in bva:
got = validate_age(age)
status = "PASS ✓" if got == exp else "FAIL ✗"
if "PASS" in status: passed += 1
print(f"{age:<6} {exp:<12} {got:<12} {desc:<22} {status}")
print(f"\n{passed}/{len(bva)} BVA tests passed.")
Output :-
Program 8 — Mobile Number — Equivalence Partitioning
AIM: Test valid and invalid data classes for a mobile number field (10 digits).
Code :-
# p08_mobile.py
import re
def validate_mobile(n):
if not n: return "Invalid: Empty"
if not [Link](): return "Invalid: Non-numeric"
if len(n) != 10: return f"Invalid: Length={len(n)}"
if n[0] not in '6789': return "Invalid: Bad start digit"
return "Valid"
cases = [
("9876543210", "Valid", "10-digit, starts 9"),
("8001234567", "Valid", "10-digit, starts 8"),
("98765", "Invalid", "Too short"),
("98765432101","Invalid", "Too long"),
("abcdefghij", "Invalid", "Non-numeric"),
("0987654321", "Invalid", "Starts with 0"),
("", "Invalid", "Empty"),
]
print("===== MOBILE NUMBER — EQUIVALENCE PARTITIONING =====\n")
passed = 0
for num, exp_class, desc in cases:
res = validate_mobile(num)
got_class = "Valid" if res == "Valid" else "Invalid"
status = "PASS ✓" if got_class == exp_class else "FAIL ✗"
if "PASS" in status: passed += 1
print(f" '{num:<13}' => {res:<24} {status}")
print(f"\nTotal: {len(cases)} | Passed: {passed}")
Output :-
Program 9 — Decision Table for Login Credentials
AIM: Design a decision table for login credentials (valid/invalid username/password).
Code :-
# p09_decision_table.py
VALID_U, VALID_P = "admin", "admin123"
def login(u, p):
if u == VALID_U and p == VALID_P: return "Access Granted"
return "Show Error Message"
print("===== DECISION TABLE — LOGIN CREDENTIALS =====\n")
print("Condition | R1 | R2 | R3 | R4")
print("Valid Username | Yes | Yes | No | No")
print("Valid Password | Yes | No | Yes | No")
print("─" * 47)
print("Action | R1 | R2 | R3 | R4")
print("Grant Access | Yes | No | No | No")
print("Show Error Message | No | Yes | Yes | Yes\n")
rules = [
("R1", "admin", "admin123", "Access Granted"),
("R2", "admin", "wrongpwd", "Show Error Message"),
("R3", "unknown", "admin123", "Show Error Message"),
("R4", "wrong", "wrong", "Show Error Message"),
]
passed = 0
for rule, u, p, exp in rules:
res = login(u, p)
status = "PASS ✓" if res == exp else "FAIL ✗"
if "PASS" in status: passed += 1
print(f" {rule}: ({u}/{p}) => {res} [{status}]")
print(f"\nAll {passed}/{len(rules)} rules verified.")
Output :-
Program 10 — Cyclomatic Complexity
AIM: Write a program and calculate the cyclomatic complexity using the formula M = E − N + 2P.
Code :-
# p10_cyclomatic.py
# Formula: M = E - N + 2P
def grade_calculator(score):
if score >= 90: return 'A' # Decision 1
elif score >= 80: return 'B' # Decision 2
elif score >= 70: return 'C' # Decision 3
elif score >= 60: return 'D' # Decision 4
else: return 'F'
E, N, P = 13, 10, 1
M=E-N+2*P
print("===== CYCLOMATIC COMPLEXITY =====\n")
print(f"Function : grade_calculator(score)")
print(f"Decision Points : 4\n")
print(f"Formula : M = E - N + 2P")
print(f" E (Edges) = {E}")
print(f" N (Nodes) = {N}")
print(f" P (Components) = {P}")
print(f"\nCyclomatic Complexity M = {E} - {N} + 2x{P} = {M}")
print(f"Min independent paths = {M}\n")
for s in [95, 85, 75, 65, 55]:
print(f" score={s} => Grade {grade_calculator(s)}")
Output :-
Program 11 — Unit Testing — Factorial and Sum
AIM: Write unit test cases for Python functions — factorial and sum.
Code :-
# p11_unit_test.py
import unittest
def factorial(n):
if n < 0: raise ValueError("Undefined for negatives")
return 1 if n <= 1 else n * factorial(n - 1)
def sum_list(nums):
return sum(nums)
class TestFactorial([Link]):
def test_factorial_zero(self):
[Link](factorial(0), 1)
def test_factorial_one(self):
[Link](factorial(1), 1)
def test_factorial_positive(self):
[Link](factorial(5), 120)
def test_factorial_negative(self):
with [Link](ValueError):
factorial(-1)
class TestSumList([Link]):
def test_sum_positive(self):
[Link](sum_list([1, 2, 3, 4]), 10)
def test_sum_empty_list(self):
[Link](sum_list([]), 0)
if __name__ == '__main__':
[Link](verbosity=2)
Output :-
Program 12 — Integration Testing — Login + Dashboard
AIM: Integrate and test two modules: login module and dashboard module.
Code :-
# p12_integration.py
import unittest
# Module 1 — Login
def authenticate(username, password):
users = {"kashvi": "pass123", "admin": "admin123"}
if [Link](username) == password:
return f"token_{username}"
return None
# Module 2 — Dashboard
def load_dashboard(token):
if not token or not [Link]("token_"):
raise PermissionError("Access Denied: Invalid token")
return {"user": [Link]("token_", "")}
class TestIntegration([Link]):
def test_valid_login_loads_dashboard(self):
token = authenticate("kashvi", "pass123")
[Link](token)
data = load_dashboard(token)
[Link](data["user"], "kashvi")
def test_invalid_login_no_dashboard(self):
token = authenticate("kashvi", "wrongpass")
[Link](token)
with [Link](PermissionError):
load_dashboard(token)
if __name__ == '__main__':
[Link](verbosity=2)
Output :-
Program 13 — System Testing — Input → Output Correctness
AIM: Test the application as a whole — input to output correctness.
Code :-
# p13_system_test.py
class GradeSystem:
def __init__(self): [Link] = {}
def add_student(self, name, marks):
if not 0 <= marks <= 100:
raise ValueError("Marks out of range")
grade = 'A' if marks>=90 else 'B' if marks>=80 else \
'C' if marks>=70 else 'D' if marks>=60 else 'F'
[Link][name] = {"marks": marks, "grade": grade}
return grade
def get_student(self, name): return [Link](name)
def get_report(self): return [Link]
sys = GradeSystem()
tests = [
("Add Kashvi marks=85", lambda: sys.add_student("Kashvi", 85), "B"),
("Add Arjun marks=95", lambda: sys.add_student("Arjun", 95), "A"),
("Get Kashvi", lambda: sys.get_student("Kashvi"), True),
("Get unknown", lambda: sys.get_student("Nobody"), None),
("Invalid marks 150", lambda: sys.add_student("X", 150), ValueError),
("Report count", lambda: len(sys.get_report()), 2),
]
print("===== SYSTEM TESTING =====\n")
for desc, action, exp in tests:
try:
res = action()
ok = "PASS ✓" if (exp is True and res or res == exp) else "FAIL ✗"
print(f" {ok} | {desc}: got {res}")
except Exception as e:
ok = "PASS ✓" if exp == ValueError else "FAIL ✗"
print(f" {ok} | {desc}: {type(e).__name__} raised")
Output :-
Program 14 — User Acceptance Testing (UAT)
AIM: Create test cases that simulate client acceptance — UI and behavior testing.
Code :-
# p14_uat.py
import time
class MockUI:
def load_page(self, pg):
[Link](0.01)
return {"status": 200, "load_time": 1.2}
def find_element(self, eid):
data = {
"login-btn": {"visible": True, "clickable": True},
"error-msg": {"visible": True, "text": "Invalid credentials. Please try again."},
"form": {"responsive": True},
}
return [Link](eid, {})
def logout(self): return {"session": None}
def submit_form(self): return {"confirmation": "Data saved successfully!"}
ui = MockUI()
cases = [
("UAT01", "Page loads within 3s", ui.load_page("Home")["load_time"] < 3),
("UAT02", "Login button visible", ui.find_element("login-btn")["visible"]),
("UAT03", "Error message friendly", "Invalid" in ui.find_element("error-msg")["text"]),
("UAT04", "Mobile responsive", ui.find_element("form")["responsive"]),
("UAT05", "Logout clears session", [Link]()["session"] is None),
("UAT06", "Form shows confirmation", "saved" in ui.submit_form()["confirmation"]),
]
print("===== USER ACCEPTANCE TESTING (UAT) =====\n")
passed = 0
for tc, desc, res in cases:
ok = "PASS ✓" if res else "FAIL ✗"
if res: passed += 1
print(f" {tc} | {desc:<35} | {ok}")
print(f"\n{passed}/{len(cases)} scenarios passed.")
if passed == len(cases): print("Sign-off: APPROVED for production.")
Output :-
Program 15 — Test Plan Document
AIM: Draft a test plan covering objectives, scope, resources, responsibilities, and timeline.
Code :-
# p15_testplan.py
plan = {
"Project": "Student Grade Management System",
"Version": "1.0",
"Date": "2024-09-01",
"Prepared By": "Kashvi Anand",
"Objectives": [
"Verify all functional requirements are met",
"Ensure input validation works correctly",
"Validate end-to-end system behaviour",
],
"Scope": {
"In": ["Login Module","Grade Calculator","Dashboard","Reports"],
"Out": ["Mobile App","Third-party APIs","Payment Module"],
},
"Resources": {
"Tester": "Kashvi Anand",
"Tools": "pytest, Selenium, JIRA",
"Environment": "Ubuntu 22.04, Python 3.11, Chrome",
},
"Responsibilities": {
"Kashvi Anand": "Test design, execution, reporting",
"Instructor": "Review & approval",
},
"Timeline": {
"Week 1": "Test Case Design",
"Week 2-3": "Test Execution",
"Week 4": "Bug Fix & Retest",
"Week 5": "Final Sign-off",
},
}
print("=" * 48)
print(" TEST PLAN DOCUMENT")
print("=" * 48)
for k, v in [Link]():
if isinstance(v, str):
print(f"{k}: {v}")
elif isinstance(v, list):
print(f"\n{k}:"); [print(f" - {i}") for i in v]
elif isinstance(v, dict):
print(f"\n{k}:")
for ki, vi in [Link]():
print(f" {ki}: {', '.join(vi) if isinstance(vi,list) else vi}")
print("\n✓ Test Plan generated.")
Output :-