Software Testing & QA

Testing Web Applications

40 分

The test client

def test_home_page_loads(client):
    resp = client.get("/")
    assert resp.status_code == 200
    assert b"PandaDev" in resp.data

Logging in during tests

def login(client, email, password="CorrectHorse9!"):
    return client.post("/auth/login", data={"email": email, "password": password},
                       follow_redirects=True)

CSRF in tests

Most apps disable CSRF in the testing config (WTF_CSRF_ENABLED = False) for convenience. Keep at least one test with it enabled to prove protection works:

def test_post_without_csrf_token_is_rejected(app, client):
    app.config["WTF_CSRF_ENABLED"] = True
    resp = client.post("/collaboration", data={"email": "a@b.com"})
    assert resp.status_code == 400

Test permissions explicitly

Security bugs are usually missing checks. For every protected route, test each kind of user:

import pytest

@pytest.mark.parametrize("role, expected", [
    (None, 404),           # anonymous: the admin area does not reveal itself
    ("user", 404),
    ("sub_admin", 403),    # staff without this permission
    ("admin", 200),
])
def test_staff_page_access(client, make_user, role, expected):
    if role:
        make_user(f"{role}@example.com", role=role)
        login(client, f"{role}@example.com")
    assert client.get("/admin/staff").status_code == expected

Also test ownership: user A must not see or edit user B's data by changing an ID in the URL. That bug class (IDOR) is one of the most common real-world vulnerabilities.

Test the database effects

def test_review_approval_updates_rating(client, admin, project, review):
    client.post(f"/admin/reviews/{review.id}/approve")
    db.session.refresh(project)
    assert project.rating_count == 1

Assert on what changed in the database, not only on the response.

Test input handling

  • Malformed query strings: /projects/filter?category=abc should return 200 or 400, never 500.
  • Over-long input, unicode, HTML and script tags in text fields.
  • Missing required fields.

A smoke test that requests every GET route as each kind of user and asserts no 500s catches a surprising number of bugs cheaply.

Exercise

Write tests for a "delete my comment" route: the owner can delete, another user gets 403 or 404, an anonymous user is redirected to login, and the comment is really gone from the database afterwards.

進捗はこのブラウザーにのみ保存されます。

レビューに提出(10 ポイント)