Module 4 ยท Python for SDETs

Negative &
validation testing

Break things on purpose โ€” and assert the API fails the right way

400 / 401 404 / 409 validation matrix xfail a bug
AI with Rufat
The mindset

Happy path proves it works. Negative tests prove it fails safely.

๐ŸŽฏ

Right status

400 / 401 / 404 / 409 for the right reason โ€” a wrong code (or a 500 crash) is itself a bug.

๐Ÿ’ฌ

Useful message

the error body tells the caller what went wrong.

๐Ÿ›

Where bugs live

untested error paths are exactly where real defects hide.

AI with Rufat
Each failure, its status

The 4xx family

400
Bad Request
missing / invalid input
401
Unauthorized
bad credentials
404
Not Found
resource doesn't exist
409
Conflict
duplicate / clashes
๐Ÿ”’Security touch: wrong password and unknown email both return the same 401 โ€” so the API never leaks which emails exist.
AI with Rufat
One test, a table of bad inputs
@pytest.mark.parametrize(
"payload, expected",
[
(valid, 200), # control
(bad_pw, 401),
(missing, 400),
])
pytest -v
test_login[valid] PASSED
test_login[bad-password] PASSED
test_login[missing] PASSED
Keep one valid control row โ€” a failing negative row is then about the input, not a broken endpoint.
AI with Rufat
When the API fails wrong

Negative testing finds real bugs

POST duplicate name โ†’ 500 ๐Ÿ’ฅ
โ†’
encode it: @xfail(strict=True) asserting 409
โ†’
XFAIL today ยท XPASS+fail when fixed
๐Ÿท๏ธA strict=True xfail documents a known bug, keeps the suite green today, and fails loudly the moment it's fixed โ€” so the stale marker can't linger.
AI with Rufat
๐Ÿ›ก๏ธ

Fail the
right way

Assert the status precisely, the message loosely โ€” and file the crashes

๐Ÿงช
Practice
Trigger 400 / 401 / 404 / 409 and assert each
๐Ÿท๏ธ
xfail
Capture the dup-name 500 with a strict xfail asserting 409
โžก๏ธ
Module 5
Test data setup & teardown โ€” control every test's state
AI with Rufat
โ† / โ†’ ยท space