Assignments > Backend Tests

Assignments > HW1: Backend Tests

Due Thu, 01/29 at 11:59pm

Overview

This assignment has three parts:

  1. Writing backend tests - Writing tests for the resources listed below
  2. Reviewing a Pull Request - Reviewing PRs created by your teammates
  3. Completing an individual reflection - Reflecting on what you learned about testing

This assignment builds on the pytest workshop and gives you practice writing contract-level API tests. Please ensure that you’ve read the Testing API Endpoints doc.

1. Write Backend Tests (70 points)

Each student will own a resource type and write comprehensive, contract-level tests for the endpoints listed below the resource. Each endpoint should have comprehensive test coverage. You’ll create one PR per student (4 PRs total, one per resource).

1.1. Select a resource

Each student on your team will select a resource You do not need to write tests for the optional resources (for now), but they are listed here just to make them visible.

Student 1: Group Resource (backend/routes/groups.py)

Endpoint Method Description
/api/groups GET List all accessible groups
/api/groups/{id} GET Get a single group with members
/api/groups POST Create a new group
/api/groups/{id} PATCH Update group
/api/groups/{id} DELETE Delete group
/api/groups/{id}/courses GET Get courses assigned to a group Optional
/api/groups/{id}/members/{user_id} POST Add member to group Optional
/api/groups/{id}/members/{user_id} DELETE Remove member from group Optional
/api/groups/{id}/members/{user_id}/role PATCH Update member role Optional

Student 2: Course Resource (backend/routes/courses.py)

Endpoint Method Description
/api/courses GET List all accessible courses
/api/courses/{id} GET Get a single course
/api/courses POST Create a new course
/api/courses/{id} PATCH Update course
/api/courses/{id} DELETE Delete course

Student 3: User Resource (backend/routes/users.py)

Note: Some tests already exist in tests/test_users.py as examples. You should extend this file with the missing tests.

Endpoint Method Description Status
/api/users GET List all users (admin only) Done
/api/users/{id} GET Get a single user Partial Partially tested (404 case only - add success case)
/api/users POST Create a new user (admin only) Done
/api/users/{id} PATCH Update user
/api/users/{id} DELETE Delete user
/api/users/{id}/status PATCH Update user status
/api/users/{id}/role PATCH Update user role

Note: some of the User tests have already been implemented, including

  • GET /api/users - Done
  • GET /api/users/{id} - Partial (auth required, 404 case done)
  • POST /api/users - Done

Student 4: Auth Resource (backend/routes/auth.py)

Endpoint Method Description
/api/auth/register POST Register a new user
/api/auth/login POST Login and get token
/api/auth/me GET Get current user profile
/api/auth/users GET List users (admin only)
/api/auth/users/disable PATCH Disable a user
/api/auth/users/role PATCH Change user role Optional
/api/auth/users/{user_id}/profile PATCH Update user profile Optional

Note: If your team wants to adjust the assignments (e.g., swap resources between students), that’s fine as long as all resources are covered and work is distributed evenly. Just document the changes in your PRs. If a team member finishes early, they can help with other resources or review PRs.

1.2. Write Behavior Contracts

For each endpoint in your assigned resource, create a GitHub issue with a behavior contract. This should include:

  1. Input: What the endpoint accepts (parameters, request body)
  2. Behavior: Step-by-step what happens (validation, database queries, business logic)
  3. Output: What the endpoint returns (status code, response body)
  4. Errors: What errors can occur and when

How to create the issue:

  1. Go to your repository → Issues tab → New issue
  2. Title format: [Resource] Endpoint: [Method] [Path] (e.g., “Auth: POST /api/auth/login”)
  3. Add the behavior contract in the description (see format below)
  4. Assign the issue to yourself
  5. Add labels (e.g., “backend”, “testing”, “hw1”)

Format:

## POST /api/auth/login

**Input:**
- username: string (required, 3-50 characters)
- password: string (required, minimum 8 characters)

**Behavior:**
1. Validate input format (username and password)
2. Look up user by username in database
3. If user doesn't exist, return 401 error
4. Verify password matches stored hash
5. If password incorrect, return 401 error
6. Generate JWT token with username
7. Return token and token_type

**Output:**
- Status: 200 OK
- Body: {"access_token": "...", "token_type": "bearer"}

**Errors:**
- 401: Invalid credentials (user not found or wrong password)
- 422: Validation error (invalid input format)

Note: Create one issue per endpoint. Individual issues make it easier to track progress and link to PRs.

1.3. Write Tests

Create a feature branch: git checkout -b my-feature-branch

Create your test file:

  • Groups: tests/test_groups.py
  • Courses: tests/test_courses.py
  • Users: Extend tests/test_users.py (some tests exist)
  • Auth: tests/test_auth.py

For each endpoint, write tests that verify the behavior contract:

  1. Success case - Test with valid input, verify status code and response structure
  2. Failure cases - Test at least 2 scenarios:
    • Invalid input (422 validation errors)
    • Missing data (404, 401, 403)
    • Authorization errors (403 for unauthorized access)
    • Edge cases (empty strings, invalid IDs, etc.)

How to write tests:

  • Reference tests/test_users.py for the pattern
  • Use fixtures from tests/conftest.py: client, test_db, admin_user, auth_headers
  • Clear test names: test_[endpoint]_[scenario]_[expected_result]
  • Use @pytest.mark.asyncio for async test functions
  • Tests should be independent and fast

Run tests: docker exec -it tma_backend poetry run pytest

1.4. Create a Pull Request

4 PRs total (one per student)

Before you create your PR:

  1. Run the linter and formatter (see cheatsheet - scroll down to “Backened Commands”)
  2. Ensure that all tests pass
  3. Note your commit history - every commit should be intentional

Requirements for the PR

  1. Create PR on GitHub with a reasonable title
  2. The description must include:
    • Which endpoint(s) you’re testing (from the assigned list above)
    • Links to the related GitHub issues (e.g., “Closes #45, #46, #47”)
    • Brief summary of what was implemented
  3. Don’t forget to assign someone from your team to review the PR

Note: When you reference issues in your PR (e.g., “Closes #45”), GitHub will automatically link them and close the issues when the PR is merged. The behavior contracts are already documented in the issues, so you don’t need to repeat them in the PR description.

Part 2: Peer Review (20 points)

Review at least PR from your team (not your own). Provide feedback on:

  1. Test Coverage: Success, failure, edge cases
  2. Test Quality: Clear names, organization, fixtures
  3. Test Correctness: Right assertions, would catch bugs

Comment on the PR with specific, constructive feedback. Approve if the PR is good, request changes only if broken. Everyone should review at least one PR. If you and your team decide to submit different endpoint tests ad different PRs, then you will need to review more than one PR (please make sure that this is equitable).

3. Individual Reflection (10 points)

Write a brief reflection under a heading with today’s date in your Google Doc (LastName_FirstName_373). Briefly answer the following questions (300-400 words total):

  1. What did you learn? - About writing tests, pytest, and the backend code
  2. What was challenging? - What was hard or confusing?
  3. What makes a good test? - Based on your experience

When you’re done, copy your reflection and paste it into the Weekly Reflection Form.

Submission Checklist

Team Requirements:

All 4 resources have tests (Groups, Courses, Users, Auth)
Clear contracts for all tested endpoints (in GitHub issues)
All tested endpoints have working success case tests
All tested endpoints have at least 2 failure case tests
Clear names, good fixtures, independent, fast, proper async usage
Well-documented PRs with clear descriptions and team links

Individual Submission:

You wrote all of your tests and submitted a PR
You have reviewed at least one of your team's PRs
You have pasted your reflection into the Weekly Reflection Form

UNC Asheville Department of Computer Science