DEV Community

Satyendra Pandey
Satyendra Pandey

Posted on

End-To-End Testing for Java+React Applications

End-to-End (E2E) Testing for a Java and React Application: Complete Guide

End-to-End (E2E) testing ensures that your application works as a whole by simulating real user workflows across the backend (Java) and frontend (React). This guide covers the tools, setup, and steps for implementing E2E testing.


1. Choosing the Right Tools

For E2E testing in a Java-React stack, use tools that can interact with both the backend and frontend:

  • Frontend Testing Tools:

    • Cypress: Modern E2E testing tool for frontend testing.
    • Playwright or Puppeteer: Headless browser automation.
    • Selenium: Browser automation that works for both frontend and backend.
  • Backend Testing Tools:

    • REST Assured: Test REST APIs in Java.
    • JUnit: Java testing framework for backend logic.
  • Integration Tools:

    • TestContainers: For testing with Docker containers.
    • MockServer: To mock APIs during tests.
    • Allure: For reporting test results.

2. Setting Up the Environment

Backend (Java):

  1. Ensure API is Tested:
    • Use JUnit for unit and integration tests.
    • Use REST Assured for API tests.

Example (REST Assured test for an API):

   import io.restassured.RestAssured;
   import org.junit.jupiter.api.Test;

   import static io.restassured.RestAssured.given;
   import static org.hamcrest.Matchers.equalTo;

   public class ApiTest {
       @Test
       public void testGetUser() {
           RestAssured.baseURI = "http://localhost:8080";
           given()
               .when()
               .get("/users/1")
               .then()
               .statusCode(200)
               .body("name", equalTo("John Doe"));
       }
   }
Enter fullscreen mode Exit fullscreen mode
  1. Mock External Dependencies:

    • Use MockServer or WireMock to mock external APIs.
  2. Containerize Backend:

    • Use Docker to create a consistent environment for backend testing.
    • Example Dockerfile:
     FROM openjdk:11
     COPY target/myapp.jar /app/myapp.jar
     ENTRYPOINT ["java", "-jar", "/app/myapp.jar"]
    

Frontend (React):

  1. Install Cypress:
   npm install cypress --save-dev
Enter fullscreen mode Exit fullscreen mode
  1. Create Cypress Tests:

    • Example: Testing login functionality:
     describe('Login Page', () => {
       it('should log in successfully', () => {
         cy.visit('http://localhost:3000/login');
         cy.get('input[name="username"]').type('admin');
         cy.get('input[name="password"]').type('password123');
         cy.get('button[type="submit"]').click();
         cy.url().should('include', '/dashboard');
       });
     });
    
  2. Mock APIs in Cypress:

    • Use cy.intercept() to intercept backend API calls.
   cy.intercept('POST', '/api/login', { statusCode: 200, body: { token: 'fake-token' } });
Enter fullscreen mode Exit fullscreen mode

3. Writing E2E Tests

Scenario 1: User Login Workflow

  1. Backend Test:

    • Ensure /login API returns a valid token.
    • Example:
     given()
         .contentType("application/json")
         .body("{ \"username\": \"admin\", \"password\": \"password123\" }")
         .when()
         .post("/login")
         .then()
         .statusCode(200)
         .body("token", notNullValue());
    
  2. Frontend Test:

    • Simulate user input on the login page and validate the redirection.

Scenario 2: Create and Display Item

  1. Backend Test:
    • Validate the /createItem API stores data and /items API retrieves it.
   @Test
   public void testCreateAndRetrieveItem() {
       String itemJson = "{ \"name\": \"Test Item\" }";

       // Create Item
       given()
           .contentType("application/json")
           .body(itemJson)
           .post("/createItem")
           .then()
           .statusCode(201);

       // Retrieve Items
       given()
           .get("/items")
           .then()
           .statusCode(200)
           .body("[0].name", equalTo("Test Item"));
   }
Enter fullscreen mode Exit fullscreen mode
  1. Frontend Test:
    • Verify the UI shows the created item.
   describe('Item Management', () => {
     it('should display the newly created item', () => {
       cy.visit('http://localhost:3000/items');
       cy.get('button#create-item').click();
       cy.get('input[name="itemName"]').type('Test Item');
       cy.get('button#save-item').click();
       cy.contains('Test Item').should('exist');
     });
   });
Enter fullscreen mode Exit fullscreen mode

4. Integrating E2E Tests with CI/CD

  1. Backend Tests in CI:

    • Use JUnit and a test database:
     mvn test
    
  2. Frontend Tests in CI:

    • Run Cypress tests:
     npx cypress run
    
  3. Full Integration:

    • Use Docker Compose to run backend and frontend together:
     version: '3.8'
     services:
       backend:
         build: ./backend
         ports:
           - "8080:8080"
       frontend:
         build: ./frontend
         ports:
           - "3000:3000"
    
  4. GitHub Actions for CI:

   name: E2E Tests

   on:
     push:
       branches:
         - main

   jobs:
     test:
       runs-on: ubuntu-latest
       steps:
         - name: Checkout Code
           uses: actions/checkout@v3

         - name: Set up Node.js
           uses: actions/setup-node@v3
           with:
             node-version: 16

         - name: Install Dependencies
           run: |
             cd frontend
             npm install

         - name: Run Cypress Tests
           run: npx cypress run

         - name: Set up Java
           uses: actions/setup-java@v3
           with:
             java-version: 11

         - name: Run JUnit Tests
           run: mvn test
Enter fullscreen mode Exit fullscreen mode

5. Reporting

  • Allure for Java:

    • Integrate Allure for detailed test reports:
    mvn surefire-report:report
    
  • Cypress Dashboard:

    • Use the Cypress Dashboard to track test runs:
    npx cypress open
    

6. Best Practices

  1. Mock external APIs during tests to avoid flakiness.
  2. Use a dedicated test database for backend testing.
  3. Parallelize tests in CI to save time.
  4. Clean up test data after each run.

This guide sets up a robust E2E testing framework for a Java and React application. Let me know if you need help implementing any specific part!

Top comments (0)