Lesson 08-Next.js Application Routing-Testing, Validation, and Deployment

Testing

Vitest

Vitest is a fast JavaScript testing framework that supports React and other frontend frameworks.

Install Vitest

npm install --save-dev vitest @vitest/ui

Configure Vitest

Create or update the vitest.config.js file to configure Vitest.

Example Configuration

// vitest.config.js
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    environment: 'jsdom',
    include: ['**/__tests__/**', '**/?(*.)+(spec|test).[jt]s?(x)'],
    exclude: ['node_modules'],
    setupFiles: ['./setupTests.js'],
    reporters: ['default', 'junit'],
  },
});

Write Tests

// tests/app/page.test.ts
import { render, screen } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import Page from '../app/page';

describe('Page component', () => {
  it('renders correctly', () => {
    render(<Page />);
    expect(screen.getByText(/Welcome to My App/i)).toBeInTheDocument();
  });

  it('handles button click', async () => {
    render(<Page />);
    const button = screen.getByRole('button', { name: /Click me!/i });
    await userEvent.click(button);
    expect(screen.getByText(/Clicked!/i)).toBeInTheDocument();
  });
});

Jest

Jest is a widely used JavaScript testing framework.

Install Jest

npm install --save-dev jest @testing-library/react @testing-library/jest-dom

Configure Jest

Create or update the jest.config.js file to configure Jest.

Example Configuration

// jest.config.js
module.exports = {
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
  moduleNameMapper: {
    '\\.(css|less|scss|sass)$': '<rootDir>/__mocks__/styleMock.js',
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
      '<rootDir>/__mocks__/fileMock.js',
  },
  transform: {
    '^.+\\.(js|jsx|ts|tsx)$': '<rootDir>/node_modules/babel-jest',
  },
};

Write Tests

// tests/app/page.test.js
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Page from '../app/page';

describe('Page component', () => {
  it('renders correctly', () => {
    render(<Page />);
    expect(screen.getByText(/Welcome to My App/i)).toBeInTheDocument();
  });

  it('handles button click', async () => {
    render(<Page />);
    const button = screen.getByRole('button', { name: /Click me!/i });
    await userEvent.click(button);
    expect(screen.getByText(/Clicked!/i)).toBeInTheDocument();
  });
});

Playwright

Playwright is a Node.js library for automating web application testing.

Install Playwright

npm install --save-dev playwright @playwright/test

Write Tests

// tests/app/playwright/page.spec.ts
import { test, expect } from '@playwright/test';

test('has title', async ({ page }) => {
  await page.goto('http://localhost:3000/');
  await expect(page).toHaveTitle(/My App/);
});

test('displays welcome message', async ({ page }) => {
  await page.goto('http://localhost:3000/');
  await expect(page.locator('text=Welcome to My App')).toBeVisible();
});

Cypress

Cypress is a popular end-to-end testing framework.

Install Cypress

npm install --save-dev cypress

Write Tests

// cypress/integration/page.spec.js
describe('Page', () => {
  it('displays welcome message', () => {
    cy.visit('/');
    cy.contains('Welcome to My App').should('be.visible');
  });

  it('handles button click', () => {
    cy.visit('/');
    cy.get('[data-test="click-button"]').click();
    cy.contains('Clicked!').should('be.visible');
  });
});

Summary

  • Vitest: A fast testing framework suitable for unit and integration tests.
  • Jest: A widely used testing framework suitable for most testing scenarios.
  • Playwright: A Node.js library for end-to-end testing, supporting multiple browsers.
  • Cypress: A popular end-to-end testing framework, easy to write and maintain.

Validation

The goal of the validation phase is to ensure the application works correctly in different environments and meets expected functional and performance requirements.

Unit Testing

Unit tests verify that individual components or functions work as expected. Jest or Vitest can be used to write and run unit tests.

Integration Testing

Integration tests ensure that different parts of the application work together without issues. Playwright and Cypress are commonly used for integration testing.

End-to-End Testing

End-to-end tests simulate real user interactions from the user’s perspective, ensuring the entire application flow works correctly. Cypress and Playwright are well-suited for end-to-end testing.

Performance Testing

Performance tests ensure the application maintains good response times and stability under high load. Tools like LoadRunner, JMeter, or Artillery (a simple Node.js tool) can be used for performance testing.

Security Testing

Security tests ensure the application is protected from common vulnerabilities. Tools like OWASP ZAP and Burp Suite can be used for security testing.

Deployment

The deployment phase aims to release the application to a production environment, making it accessible to users.

Choosing a Deployment Platform

Common deployment platforms include Vercel, Netlify, AWS Amplify, and Heroku.

Deploying with Vercel

Vercel is the officially recommended deployment platform for Next.js, supporting one-click deployments.

Install Vercel CLI

npm install -g vercel

Log in to Vercel

vercel login

Deploy the Project

vercel

Deploying with Netlify

Netlify is another popular deployment platform, supporting automatic deployments and continuous integration.

Install Netlify CLI

npm install -g netlify-cli

Initialize Netlify

netlify init

Deploy the Project

netlify deploy

Deploying with AWS Amplify

AWS Amplify provides a complete deployment solution, including CI/CD.

Install Amplify CLI

npm install -g @aws-amplify/cli

Initialize Amplify

amplify init

Deploy the Project

amplify push

Deploying with Heroku

Heroku is a general-purpose PaaS platform supporting multiple languages and frameworks.

Install Heroku CLI

npm install -g heroku

Log in to Heroku

heroku login

Deploy the Project

git push heroku main

Static Deployment and Server-Side Deployment

Build the Application

Before deployment, build your Next.js application to generate an optimized production version.

npm run build

Static Deployment

Static deployment involves compiling the application into static HTML files and related assets, then deploying to a service that supports static file hosting. This is suitable for applications without dynamic content.

Build a Static Site

Use the next export command to convert the application into a static site.

npm run export

This generates static files in the .out directory.

Deploy the Static Site

Upload the contents of the .out directory to a static file hosting service, such as GitHub Pages, Netlify, or Vercel.

GitHub Pages

git subtree push --prefix .out origin gh-pages

Netlify

Configure the .out directory as the deployment source in Netlify.

Vercel

Use the Vercel CLI or Vercel website to deploy the .out directory.

Server-Side Rendering Deployment

Server-side rendering (SSR) involves generating HTML content on the server and sending it to the client. This is suitable for applications requiring dynamic content or SEO optimization.

Build the SSR Version

After running npm run build, Next.js generates all files needed for SSR.

Deploy the SSR Application

Deploy the built files to a server that supports Node.js.

Start the Server Locally

npm start

Deploy to Vercel

Use the Vercel CLI or Vercel website for deployment.

Other Cloud Providers

Deploy the built files to AWS Lambda, Google Cloud Functions, or similar services.

Share your love