safetrustcr / Frontend

Interface for a decentralized platform enabling secure and trusted P2P transactions with cryptocurrency.
https://safetrust.vercel.app/
5 stars 22 forks source link

Set up Testing Infrastructure with Jest and Testing Library #90

Open rvalenciano opened 3 days ago

rvalenciano commented 3 days ago

[Frontend] Set up Testing Infrastructure with Jest and Testing Library

Set up comprehensive testing infrastructure for our React frontend application, including unit tests, component tests, and integration tests.

Problem

We need to:

Solution

Package Installation

# Core testing libraries
npm install --save-dev jest @testing-library/react @testing-library/jest-dom @testing-library/user-event
npm install --save-dev @jest/types jest-environment-jsdom

# For API mocking
npm install --save-dev msw

# For component snapshot testing
npm install --save-dev @testing-library/jest-dom

# For coverage reporting
npm install --save-dev @types/jest jest-coverage-badges

# For E2E testing
npm install --save-dev cypress @testing-library/cypress

Configuration Files

// jest.config.js
module.exports = {
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['<rootDir>/src/setupTests.ts'],
  moduleNameMapper: {
    '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
    '\\.(gif|ttf|eot|svg|png)$': '<rootDir>/test/__mocks__/fileMock.js',
    '^@/(.*)$': '<rootDir>/src/$1'
  },
  collectCoverageFrom: [
    'src/**/*.{js,jsx,ts,tsx}',
    '!src/**/*.d.ts',
    '!src/mocks/**',
    '!src/stories/**'
  ],
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80
    }
  }
};
// src/setupTests.ts
import '@testing-library/jest-dom';
import { server } from './mocks/server';

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
// src/test-utils.tsx
import { render } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { BrowserRouter } from 'react-router-dom';

const AllTheProviders = ({ children }) => {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
      },
    },
  });

  return (
    <QueryClientProvider client={queryClient}>
      <BrowserRouter>
        {children}
      </BrowserRouter>
    </QueryClientProvider>
  );
};

const customRender = (ui, options = {}) =>
  render(ui, { wrapper: AllTheProviders, ...options });

export * from '@testing-library/react';
export { customRender as render };

MSW Setup for API Mocking

// src/mocks/handlers.ts
import { graphql } from 'msw';

export const handlers = [
  graphql.query('GetUserProfile', (req, res, ctx) => {
    return res(
      ctx.data({
        users_by_pk: {
          id: '1',
          email: 'test@example.com',
          first_name: 'Test',
          last_name: 'User'
        }
      })
    );
  }),

  graphql.mutation('UpdateUserProfile', (req, res, ctx) => {
    const { data } = req.variables;
    return res(
      ctx.data({
        update_users_by_pk: {
          ...data,
          id: '1'
        }
      })
    );
  })
];

Example Test Cases

// src/components/UserProfile/UserProfile.test.tsx
import { screen, render, waitFor } from '@/test-utils';
import userEvent from '@testing-library/user-event';
import { UserProfile } from './UserProfile';

describe('UserProfile', () => {
  it('renders user information correctly', async () => {
    render(<UserProfile userId="1" />);

    await waitFor(() => {
      expect(screen.getByText('Test User')).toBeInTheDocument();
    });
  });

  it('handles profile update', async () => {
    render(<UserProfile userId="1" />);

    await userEvent.type(
      screen.getByLabelText(/first name/i),
      'Updated'
    );

    await userEvent.click(screen.getByRole('button', { name: /save/i }));

    await waitFor(() => {
      expect(screen.getByText('Profile updated')).toBeInTheDocument();
    });
  });
});

Scripts to Add in package.json

{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage",
    "test:e2e": "cypress open",
    "test:e2e:headless": "cypress run"
  }
}

Success Criteria

Prerequisites

Michaelkingsdev commented 3 days ago

Hello @rvalenciano I am a frontend developer with 3 years of experience. I can configure and setup testing infrastructure for this project.

To ensure the quality and reliability of this Nextjs frontend application, I will set up a comprehensive testing infrastructure that includes unit, component, and integration tests. The setup will leverage Jest for unit testing, React Testing Library for component testing, and MSW for API mocking. In addition, I will implement E2E testing with Cypress and configure test coverage reporting. The setup will be aligned with best practices and will ensure CI/CD integration. After completing the setup, I will document the testing process, ensuring that all configurations are functional and tests are ready for continuous integration.

I will make PR in 48hrs. Thanks

JosueBrenes commented 3 days ago

Hi @Michaelkingsdev have assigned the issue to you.

Michaelkingsdev commented 2 days ago

Hello @JosueBrenes
I am still working on this. I just want to let you know.