This project was created to demonstrate practical skills for an SDET (Software Developer in Test) role using a Django-based REST API. It simulates key responsibilities listed in a typical SDET job description—such as test automation, CI/CD pipelines, security scanning, containerized environments, and API validation.
It is designed to be:
- 🔒 Secure
- ⚙️ Test-driven
- 📦 Dockerized
- 🚀 CI/CD-ready
- ✅ Fully covered by tests (100% coverage)
- JWT-based authentication
- CRUD for task management with status tracking
- Security, XSS, and SQL injection tests
- 49 total tests with 100% code coverage
- API documentation via Swagger + ReDoc
- Docker & Docker Compose for local + test environments
- Fully automated CI with GitHub Actions
- Security scans via Bandit and Safety
Complete interactive documentation generated using drf-spectacular.

A visual summary of complete test coverage across all components.

Example of successful automated builds and tests across multiple workflows.

Pre-commit hooks ensure code is clean and consistent before pushing.

Integrated with Codecov for coverage visualization and CI enforcement.

- Python 3.13
- Django 5.2
- Django REST Framework 3.16.0
- JWT Authentication (djangorestframework-simplejwt 5.5.0)
- PostgreSQL database
- Docker & Docker Compose
- pytest 8.3.5 for testing
- drf-spectacular 0.28.0 for API documentation
- GitHub Actions for CI/CD
- Python 3.13 or higher
- Docker and Docker Compose (for containerized setup)
- PostgreSQL (for local development without Docker)
- UV (optional, for dependency management)
-
Clone the repository:
git clone https://github.com/nim444/sdet-django-api.git cd sdet-django-api -
Create and activate a virtual environment:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt
Alternatively, if using UV:
uv pip install -r requirements.txt
-
Set up a PostgreSQL database or use SQLite for development.
-
Configure environment variables:
export DEBUG=1 export DATABASE_URL=sqlite:///db.sqlite3 # Or your PostgreSQL connection string
-
Apply migrations:
python manage.py migrate
-
Create a superuser (optional):
python manage.py createsuperuser
-
Run the development server:
python manage.py runserver
-
Access the API at http://localhost:8000/api/ and the admin interface at http://localhost:8000/admin/
-
Build and start the containers:
docker-compose up --build
-
The API will be available at http://localhost:8000/api/
-
To create a superuser in Docker:
docker-compose exec web python manage.py createsuperuser
-
Make sure you have installed the test dependencies:
pip install -r requirements.txt
-
Run the tests with pytest:
python -m pytest
-
To generate a coverage report:
python -m pytest --cov=. --cov-report=html
This will create a coverage report in the
htmlcovdirectory.
-
Use the test-specific Docker Compose file:
docker-compose -f docker-compose.test.yml up --build
-
This will run the tests in a containerized environment with a dedicated PostgreSQL instance.
-
To view test results:
docker-compose -f docker-compose.test.yml logs -f test
The project has 49 tests covering different aspects of the application:
Compatibility Tests (5 tests)
test_django_version - Verifies Django version compatibility
test_drf_jwt_compatibility - Checks JWT compatibility with Django
test_python_version - Ensures correct Python version
test_required_dependencies_installed - Validates all dependencies are installed
test_dependency_versions - Checks dependency version requirements
Fixture Tests (5 tests)
test_api_client_fixture - Tests the API client fixture
test_create_user_fixture_with_defaults - Tests user creation with defaults
test_create_user_fixture_with_custom_values - Tests user creation with custom values
test_authenticated_client_fixture - Tests authenticated client fixture
test_create_task_fixture - Tests task creation fixture
Registration Tests (5 tests)
test_successful_registration - Tests successful user registration
test_passwords_not_matching - Tests handling of non-matching passwords
test_duplicate_username - Tests duplicate username validation
test_invalid_email - Tests invalid email validation
test_missing_required_fields - Tests handling of missing required fields
Security Tests (9 tests)
# Authentication
test_authentication_required_for_api_endpoints - Tests auth requirements
test_authentication_not_required_for_public_endpoints - Tests public endpoints
test_jwt_token_expiration - Tests token expiration
test_refresh_token_rotation - Tests token refresh
# Authorization
test_user_cannot_access_others_tasks - Tests task access control
test_user_can_only_see_own_tasks - Tests task listing isolation
test_user_cannot_access_others_profile - Tests profile access control
# Input Sanitization
test_xss_sanitization_in_task_fields - Tests XSS prevention
test_sql_injection_prevention - Tests SQL injection prevention
test_validation_on_task_fields - Tests field validation
Task API Tests (10 tests)
test_task_str_method - Tests Task model string representation
test_list_tasks - Tests task listing API
test_create_task - Tests task creation API
test_retrieve_own_task - Tests retrieving user's tasks
test_cannot_retrieve_other_users_task - Tests task access restrictions
test_update_task - Tests task update API
test_cannot_update_other_users_task - Tests update restrictions
test_delete_task - Tests task deletion API
test_cannot_delete_other_users_task - Tests deletion restrictions
test_filter_tasks_by_status - Tests task filtering by status
Token API Tests (7 tests)
test_obtain_token_pair_success - Tests successful token acquisition
test_obtain_token_pair_invalid_credentials - Tests invalid credentials handling
test_obtain_token_pair_missing_fields - Tests missing fields validation
test_refresh_token_success - Tests token refresh success
test_refresh_token_invalid - Tests invalid refresh token handling
test_access_protected_endpoint_with_token - Tests endpoint access with token
test_access_protected_endpoint_without_token - Tests unauthorized access handling
Deployment Configuration Tests (8 tests)
test_asgi_config - Tests ASGI configuration initialization
test_wsgi_config - Tests WSGI configuration initialization
test_manage_main - Tests Django's manage.py main function
test_manage_import_error - Tests error handling in manage.py
test_manage_command_line_execution - Tests manage.py CLI execution
test_manage_command_line_execution_with_exec - Tests direct execution path in manage.py
test_settings_database_url - Tests database URL configuration
The test suite achieves 100% code coverage across all application modules, including Django configuration files that are often overlooked in testing (asgi.py, wsgi.py, settings.py, manage.py).
Once the server is running, you can access the API documentation:
- Swagger UI: http://localhost:8000/api/schema/swagger-ui/
- ReDoc: http://localhost:8000/api/schema/redoc/
- Download schema: http://localhost:8000/api/schema/
This project maintains the highest standards for code quality and test coverage:
- Every line of code in the application is covered by tests
- Coverage includes all Django configuration files (settings.py, asgi.py, wsgi.py, manage.py)
- Run
python -m pytest --cov=. --cov-report=htmlto generate a detailed HTML coverage report
To ensure code quality is maintained throughout development, the project uses:
- Pre-commit hooks for code formatting and linting
- CI coverage threshold enforcing 100% coverage for all new code
- Codecov integration for visualizing coverage reports
- Black - Code formatting
- Flake8 - Style guide enforcement
- isort - Import sorting
- pre-commit - Git hooks for code quality checks
To set up pre-commit hooks for code quality checks:
-
Install pre-commit:
pip install pre-commit
-
Install the hooks:
pre-commit install
-
The hooks will run automatically on every commit.
-
To run pre-commit checks manually:
pre-commit run --all-files
docker build -t task-management-api .docker run -p 8000:8000 -e DATABASE_URL=postgres://postgres:postgres@db:5432/postgres -e DEBUG=1 task-management-api- Start services:
docker-compose up - Start services in background:
docker-compose up -d - Stop services:
docker-compose down - View logs:
docker-compose logs -f - Rebuild services:
docker-compose up --build - Run migrations:
docker-compose exec web python manage.py migrate
.
├── api/ # Main application code
│ ├── migrations/ # Database migrations
│ ├── tests/ # Test files
│ ├── models.py # Data models
│ ├── serializers.py # API serializers
│ ├── views.py # API views
│ └── urls.py # API URL routing
├── epam/ # Django project settings
│ ├── settings.py # Project settings
│ ├── urls.py # Project URL routing
│ └── wsgi.py # WSGI configuration
├── docker-compose.yml # Docker Compose configuration
├── docker-compose.test.yml # Docker Compose for testing
├── Dockerfile # Docker configuration for production
├── Dockerfile.test # Docker configuration for testing
├── requirements.txt # Python dependencies
├── wait-for-postgres.sh # Script to wait for PostgreSQL availability
└── docker-entrypoint.sh # Docker container entry script
-
Update the settings for production (disable DEBUG, set SECRET_KEY, etc.)
-
Build the Docker image:
docker build -t task-management-api . -
Run the container with appropriate environment variables:
docker run -p 8000:8000 -e DATABASE_URL=<your-production-db-url> -e DEBUG=0 -e SECRET_KEY=<your-secret-key> task-management-api
The project uses GitHub Actions to automate testing, code quality checks, and Docker build validation:
Three workflows are configured:
-
Django CI (.github/workflows/ci.yml)
- Runs linting with pre-commit hooks
- Executes all tests against a PostgreSQL database
- Generates and uploads code coverage reports
- Triggered on push to main/master and pull requests
-
Docker Build and Test (.github/workflows/docker.yml)
- Validates Docker container builds
- Runs tests inside Docker containers
- Uses the test-specific docker-compose.test.yml
- Triggered on push to main/master and pull requests
-
Security Scans (.github/workflows/security.yml)
- Checks dependencies for security vulnerabilities with safety
- Performs static code analysis with bandit
- Generates security reports
- Runs weekly and on code changes
To manually trigger any workflow:
- Go to your GitHub repository
- Navigate to Actions tab
- Select the workflow you want to run
- Click "Run workflow" button
The CI workflows can be extended to deploy to various environments:
deploy:
needs: [test, docker-build-and-test]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- name: Deploy to production
run: |
# Add deployment steps hereThis project is licensed under the MIT License. See the LICENSE file for details.