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):
-
Ensure API is Tested:
- Use
JUnit
for unit and integration tests. - Use
REST Assured
for API tests.
- Use
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"));
}
}
-
Mock External Dependencies:
- Use
MockServer
orWireMock
to mock external APIs.
- Use
-
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):
- Install Cypress:
npm install cypress --save-dev
-
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'); }); });
-
Mock APIs in Cypress:
- Use
cy.intercept()
to intercept backend API calls.
- Use
cy.intercept('POST', '/api/login', { statusCode: 200, body: { token: 'fake-token' } });
3. Writing E2E Tests
Scenario 1: User Login Workflow
-
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());
- Ensure
-
Frontend Test:
- Simulate user input on the login page and validate the redirection.
Scenario 2: Create and Display Item
-
Backend Test:
- Validate the
/createItem
API stores data and/items
API retrieves it.
- Validate the
@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"));
}
-
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');
});
});
4. Integrating E2E Tests with CI/CD
-
Backend Tests in CI:
- Use JUnit and a test database:
mvn test
-
Frontend Tests in CI:
- Run Cypress tests:
npx cypress run
-
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"
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
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
- Mock external APIs during tests to avoid flakiness.
- Use a dedicated test database for backend testing.
- Parallelize tests in CI to save time.
- 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)