← Back to Module

Project Finalisation

CMM721: Web Application Development - Session 12

Birmingham Newman University

Lecturer: James Williams

Masters Level Conversion Course

3-hour session • 18 slides • 2 tasks • Testing & deployment demos

Session Timeline:

  • 10 min: Registration & waiting
  • 20 min: Opening slides
  • 45 min: Task 1
  • 15 min: Break/Catch up
  • 20 min: Secondary slides
  • 45 min: Task 2
  • Remaining: Self-study

Learning Objectives

  • Implement comprehensive testing strategies
  • Perform load testing and optimization
  • Write effective documentation
  • Deploy applications to production
  • Set up CI/CD pipelines
  • Prepare professional project presentations

Testing Strategy Overview

The Testing Pyramid

E2E Tests (Few)
Integration Tests (Some)
Unit Tests (Many)

More tests at the bottom, fewer at the top

Unit Testing

Unit Test: Test individual functions/components in isolation

Python (Django) - pytest:

# test_models.py
import pytest
from django.contrib.auth.models import User
from blog.models import Post

@pytest.mark.django_db
def test_post_creation():
  user = User.objects.create(username='test')
  post = Post.objects.create(
    title='Test Post',
    content='Content',
    author=user
  )
  assert post.title == 'Test Post'
  assert post.author == user

# Run: pytest

JavaScript Unit Testing

Jest (React):

// Counter.test.js
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';

test('increments counter on button click', () => {
  render(<Counter />);
  
  const button = screen.getByText('Increment');
  const count = screen.getByText('0');
  
  fireEvent.click(button);
  
  expect(screen.getByText('1')).toBeInTheDocument();
});

// Run: npm test

Integration Testing

Integration Test: Test how multiple components work together
# test_views.py
from django.test import TestCase, Client
from django.urls import reverse

class PostViewTests(TestCase):
  def setUp(self):
    self.client = Client()
    self.user = User.objects.create_user('test', password='pass')

  def test_post_list_view(self):
    response = self.client.get(reverse('post_list'))
    self.assertEqual(response.status_code, 200)
    self.assertContains(response, 'Blog Posts')

  def test_create_post_authenticated(self):
    self.client.login(username='test', password='pass')
    response = self.client.post(reverse('post_create'), {
      'title': 'New Post',
      'content': 'Content'
    })
    self.assertEqual(response.status_code, 302)

End-to-End (E2E) Testing

E2E Test: Test complete user workflows in real browser

Playwright:

// e2e/login.spec.js
const { test, expect } = require('@playwright/test');

test('user can login successfully', async ({ page }) => {
  await page.goto('http://localhost:3000/login');
  
  await page.fill('input[name="username"]', 'testuser');
  await page.fill('input[name="password"]', 'password123');
  await page.click('button[type="submit"]');
  
  await expect(page).toHaveURL('http://localhost:3000/dashboard');
  await expect(page.locator('h1')).toContainText('Welcome');
});

// Run: npx playwright test

🎯 Test Coverage Example

Coverage Report

blog/models.py
95%
blog/views.py
78%
blog/serializers.py
100%
TOTAL
87%

Aim for 80%+ coverage, but quality > quantity

Task 1: Comprehensive Testing

Objective:

Implement full test suite for your project

Requirements:

  1. Write 10+ unit tests for models/functions
  2. Write 5+ integration tests for API endpoints
  3. Write 3+ E2E tests for critical user flows
  4. Achieve minimum 80% code coverage
  5. Set up test database
  6. Run all tests successfully
  7. Generate coverage report

Test Scenarios to Cover:

  • User registration and authentication
  • CRUD operations on main entities
  • Form validation
  • Error handling
  • Permission checks

Load Testing

Load Testing: Test how app performs under high traffic

Tools:

  • Locust: Python-based, write tests in code
  • Apache JMeter: GUI-based, widely used
  • k6: Modern, JavaScript-based

Locust Example:

# locustfile.py
from locust import HttpUser, task, between

class WebsiteUser(HttpUser):
  wait_time = between(1, 3)

  @task(3)
  def view_posts(self):
    self.client.get("/api/posts/")

  @task(1)
  def view_post_detail(self):
    self.client.get("/api/posts/1/")

# Run: locust -f locustfile.py

Performance Optimization

Backend Optimization:

  • Database query optimization (select_related, prefetch_related)
  • Caching (Redis, Memcached)
  • Database indexing
  • Pagination for large datasets
  • Async tasks (Celery)

Frontend Optimization:

  • Code splitting (React.lazy)
  • Image optimization (WebP, lazy loading)
  • Minification and bundling
  • CDN for static assets
  • Service workers for offline support

Documentation Best Practices

Essential Documentation:

  • README.md: Project overview, setup, usage
  • Installation Guide: Dependencies, environment setup
  • API Documentation: Endpoints, request/response examples
  • User Guide: How to use the application
  • Developer Guide: Architecture, contributing
  • Changelog: Version history
  • License: MIT, GPL, etc.

README.md Template

# Project Title
Brief description of your project.

## Features
- Feature 1
- Feature 2

## Tech Stack
- Frontend: React, Tailwind CSS
- Backend: Django, PostgreSQL
- Deployment: Heroku

## Installation
\`\`\`bash
git clone https://github.com/user/project.git
cd project
pip install -r requirements.txt
python manage.py migrate
python manage.py runserver
\`\`\`

## Usage
Visit http://localhost:8000

## Testing
\`\`\`bash
pytest
\`\`\`

## License
MIT

Deployment Strategies

Platform as a Service (PaaS)

Options: Heroku, Railway, Render, PythonAnywhere

Pros: Easy setup, managed infrastructure, auto-scaling

Cons: Less control, more expensive at scale

Infrastructure as a Service (IaaS)

Options: AWS EC2, DigitalOcean, Google Cloud, Azure

Pros: Full control, cost-effective at scale

Cons: More setup, requires DevOps knowledge

Serverless

Options: Vercel, Netlify (frontend), AWS Lambda (backend)

Pros: Auto-scaling, pay per use, zero maintenance

Cons: Cold starts, limited execution time

🎯 Deployment Checklist

Pre-Deployment:

  • ✅ Set DEBUG=False
  • ✅ Configure ALLOWED_HOSTS
  • ✅ Use environment variables for secrets
  • ✅ Set up production database
  • ✅ Configure static files (collectstatic)
  • ✅ Set up HTTPS/SSL
  • ✅ Configure CORS
  • ✅ Run security checks
  • ✅ Create backup strategy
  • ✅ Set up monitoring (Sentry, LogRocket)

CI/CD Pipeline

CI/CD: Continuous Integration / Continuous Deployment

GitHub Actions Example:

# .github/workflows/django.yml
name: Django CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: 3.11
    - name: Install dependencies
      run: pip install -r requirements.txt
    - name: Run tests
      run: pytest
    - name: Deploy
      if: github.ref == 'refs/heads/main'
      run: # deployment command

Task 2: Deploy Your Project

Objective:

Deploy your application to a live production environment

Requirements:

  1. Choose deployment platform (Heroku/Railway/Render)
  2. Set up production database (PostgreSQL)
  3. Configure environment variables
  4. Set DEBUG=False, configure ALLOWED_HOSTS
  5. Set up static files serving (WhiteNoise or CDN)
  6. Configure HTTPS
  7. Deploy backend and frontend
  8. Test all functionality in production
  9. Set up CI/CD pipeline (GitHub Actions)
  10. Document deployment process

Deliverables:

  • Live application URL
  • Deployment documentation
  • CI/CD configuration files

Project Presentation Tips

Structure (10-15 minutes):

  1. Introduction (1 min): Title, your name, overview
  2. Problem (2 min): What problem does it solve?
  3. Demo (5 min): Live walkthrough of key features
  4. Technical (3 min): Architecture, tech stack, challenges
  5. Testing (2 min): Testing strategy, coverage
  6. Conclusion (2 min): Achievements, future work, Q&A

Best Practices:

  • Practice multiple times
  • Prepare backup (video if live demo fails)
  • Focus on highlights, not every feature
  • Show code for interesting parts
  • Be ready to answer questions

🎯 Presentation Slide Structure

Slide 1: Title

Project name, your name, date

Slide 2-3: Problem & Solution

What problem? Why does it matter? Your solution

Slide 4: Architecture

System diagram, tech stack

Slide 5-7: Features

Screenshots, key functionality

Slide 8: Technical Challenges

What was hard? How did you solve it?

Slide 9: Testing & Quality

Coverage, performance, security

Slide 10: Conclusion

Achievements, lessons learned, future work

Final Project Checklist

Before Submission:

  • ✅ All features working
  • ✅ Tests passing (80%+ coverage)
  • ✅ Code well-documented
  • ✅ README.md complete
  • ✅ API documentation
  • ✅ Deployed to production
  • ✅ HTTPS enabled
  • ✅ Responsive design
  • ✅ Accessibility checked
  • ✅ Performance optimized
  • ✅ Security best practices
  • ✅ Error handling
  • ✅ No sensitive data in repo
  • ✅ Clean git history
  • ✅ License included
  • ✅ Presentation prepared

Module Review

What We've Covered:

  • Web architecture
  • HTML5 & semantics
  • CSS3 & responsive design
  • JavaScript fundamentals
  • Async JS & APIs
  • Django basics
  • Django ORM & CRUD
  • Django REST Framework
  • React & state management
  • Web app critique
  • Comparative analysis
  • Testing & deployment
You now have full-stack development skills!

Congratulations!

You've completed CMM721

🎉

Remember:

  • Keep learning - technology evolves rapidly
  • Build projects - practice is key
  • Contribute to open source
  • Stay curious and keep coding!

Contact: JWilliams@Staff.newman.ac.uk

Good luck with your projects and future careers!