Testing Strategies for Micro Frontends [Testμ 2023]

LambdaTest Team - Nov 2 '23 - - Dev Community

Integrating end-to-end testing in Micro Frontends architecture can be challenging as there is a requirement for a systematic approach that demonstrates the streamlined utilization of modern testing tools and guides the integration of their outputs to derive accurate code coverage metrics for effective pipeline decision-making. Starting from the basic setup of each framework to combining code coverage metrics for RTL and Cypress testing suites.

In this session, Ioannis covered how to test React MFEs with modern tools like Cypress. Ioannis also covered why dev teams would use Vite over Webpack and how Cypress and RTL can be configured all the way. He gave an idea on code coverage metrics combined from RTL and Cypress to get some SLOs injected in the pipeline.

About the Speaker

Ioannis Papadakis has 13 years of experience in the field of QA engineering. Through his working life, he has gained knowledge of agile methodologies and agile techniques in testing. He is currently working in GWI as Director of QA, helping industries to shape testing strategies in reach platforms.

During the remarkable session at the 2023 Testμ Conference, Ioannis Papadakis discussed testing React MFEs using contemporary tools such as Cypress. Ioannis also explored the reasons behind development teams’ preference for Vite over Webpack and comprehensive guidance on configuring Cypress and RTL.

If you couldn’t catch all the sessions live, don’t worry! You can access the recordings at your convenience by visiting the LambdaTest YouTube Channel.

Agenda

The agenda of this session planned by Ioannis Papadakis was as follows:

  • Introduction to Micro-Frontend Architecture

  • Testing Strategy in React MFE Architecture

  • Non-Functional Testing in MFE

  • Optimize CI/CD with GHA & LambdaTest

    Introduction to Micro-Frontend (MFE) Architecture

UI Monolithic, a traditional web development approach, consolidates web app components and pages into a single codebase. This integration results in complexity, affecting maintenance, scalability, and collaboration. Micro frontend architecture, in contrast, divides units into smaller components, accelerating development and improving code quality through manageable, scalable units.

Unlike the modern approach like Mirco frontend, where the units are broken down into smaller units so that each works on different features, this approach helps fasten the development process and improve code quality. They are maintained in smaller units, so managing and scaling is easy.

Why choose Micro Frontend Architecture?

This architecture can be useful because of its organized and modern approach.

  • MFE can be isolated

  • MFE allows development teams to make changes without impacting the overall speed of the app.

  • MFE is not limited to the web but is more effective there.

Advantages of Micro Frontend Architecture

The contemporary method enables the organization of the codebase, reducing the intricacies of managing numerous features within a single unit. This approach offers numerous advantages and benefits.

Let’s view the benefits of using the MFE approach.

  • Design and development flexibility: It allows you to design and develop different parts of a web app separately, making it easier to change and improve each piece without affecting the rest.

  • Separate code bases: Each team will have its codebase to work on different parts without getting in each other’s way.

  • Favors native browsers over custom API: Micro Frontends use what web browsers already understand, making things smoother and more reliable instead of building some different and unique tools in terms of API.

  • Freedom to innovate: When implementing each part of the web application. The teams can use different technologies. Encouraging team creativity and using the best tool for the job.

  • Fault seclusion: The best part is if one part of the website fails, it does not bring the whole site down. Only the failed part is affected.

  • Faster build time: Since the code base of each team is more petite, the builds are quicker, so you can get changes and updates out to users faster.

  • Technology agnosticism: You can use a mix and match of technologies that are your best fit. There is no rule to use one technology as such.

  • Autonomous teams: Each team working on different parts of the site can make decisions independently.

  • Maintainability: Since MFE maintains a smaller codebase than a big one, It’s easier to find and fix issues, making maintainability easy.

  • Reusability: Components created for one part of the site can be reused in another, helping the team save time and effort.

How to test MFE?

Testing Micro-Frontend Architecture involves several steps to ensure the smooth functioning of the individual sections (micro frontends) and their collaboration within the more significant application. Begin with unit tests for each micro frontend’s components, followed by integration tests to verify communication.

Use end-to-end testing to simulate user interactions and perform cross-browser checks to ensure compatibility. Assess performance, isolate failures, and test API contracts for consistency.

Check error handling, accessibility, and security, and gather user feedback for usability. Covering these aspects ensures that each micro frontend works autonomously and harmoniously, contributing to a robust and reliable application.

Testing Milestone

  • Starting with unit testing, individual micro frontends are examined to ensure their components function accurately.

  • Integration testing follows, validating seamless collaboration among micro frontends.

  • Progressing to end-to-end testing, user interactions are simulated to ensure the comprehensive functionality of the entire application.

  • Cross-browser testing guarantees compatibility across different web browsers, while performance testing assesses the efficiency of micro frontends.

  • Error handling capabilities are tested, ensuring robustness in unexpected scenarios.

  • Security and API testing verify the safety of micro frontends and adherence to API agreements.

  • Usability testing gathers valuable user feedback, refining the overall user experience.

These milestones contribute to the reliability and high-quality Micro Frontend Architecture.

Traditional Testing Pyramid

  • The Traditional Testing Pyramid is like a guideline for testing software. Ioannis continues to explain about the pyramid and its three layers.

  • He started with the bottom; there were Unit Tests. These are like the base of the pyramid. They check small parts of the code, like building blocks. These tests are quick and dependable, helping to find problems early.

  • In the middle, you have Integration Tests. They ensure that different pieces of the code work well together, like how different machines in a factory cooperate. These tests make sure everything fits and works correctly.

  • At the top, there are End-to-End (E2E) Tests. They’re like the tip of the pyramid. These tests act like real users, trying out the whole application as if they were using it in real life. They make sure everything works perfectly together.

Ioannis gives an idea about what a pyramid idea is. The pyramid says you should have many Unit Tests, fewer Integration Tests, and even fewer End-to-End Tests. This is because catching problems at the bottom levels is cheaper and faster than using top-level tests.

He concludes that new software-making methods, like MFE Architecture, might need different testing strategies. So, the pyramid is a good guide, but sometimes it needs to be adjusted.

Shift Left Testing Approach

Ioannis explained the Shift Left Testing approach by briefly explaining the testing and the approach. Shift Left Testing is a strategy where testing activities start earlier in the software development process. Instead of waiting until the end to test, issues are identified and fixed as early as possible.

This approach improves quality, reduces costs, and speeds up development by catching and addressing problems sooner, often during coding or design phases. It involves collaboration between developers and testers, leading to a more efficient and reliable development process.

Shift Left Testing Benefits

There are some benefits that the left shift offers.

  • Shift Left testing offers a higher-quality codebase.

  • High customer satisfaction.

  • Reduce the cost of solving bugs.

  • Product overshoot estimate timeline.

  • High-quality product.

  • Uncover bugs earlier.

Development Workflow with MFE

Imagine making something cool using Micro Frontend Architecture (MFE). First, you plan how it should work, like drawing a picture. Then, you start building it, just like putting LEGO blocks together. After that, you check if it works well, like making sure your toy car rolls smoothly. Once it’s perfect, you gather all the parts and make sure they play nicely together, like friends rehearsing for a play. Finally, you let your creation shine for everyone to see, like showing your artwork to the world. So, MFE takes you from planning and building to testing, practicing, and finally, putting your creation on the stage for everyone to enjoy.

Unit Testing Stack

When testing your React components with React Testing Library, you’re like a detective checking how your app behaves when users click and type. Mock Service Workers act like a pretend server, letting you test how your app handles different server responses. Test Code Coverage is like making sure you colored all the parts of a picture and tested all your code. This stack helps you create a solid and reliable app, making it work well and stay strong.

The Problem

Ioannis gets into more detail by discussing the problem statement.

The Solution

Ioannis also provided a solution to the problem.

Mock Service Worker (MSW)

Mock Service Workers, often called MSW, are like friendly stands for real servers. They help you test how your app talks to the server without connecting. You tell MSW how you want it to respond, like giving it a script to follow. This way, you can check if your app behaves correctly in different situations without needing a live server. MSW is like a practice stage for your app’s communication, preparing it for the real world.

Code implementation using MFE

Ioannis explained code implementation, as shown in the image below. Along with the code implementation, Ioannis also explains why mocks are effective.

Advantages of MSW

MSW lets you test your app without needing a real server. You control how it responds, helping you test different situations TypeScript backend project’s instrumenting, creating your app more reliable.

  • Native TypeScript Support: TypeScript is like a language with superhero powers for JavaScript, and here, it’s supported right out of the box, making your code stronger and safer.

  • Rest API & GraphQL: These are different ways your app talks to servers: by asking questions (GraphQL) or following orders (Rest API).

  • Client-side Execution: Your app’s code runs on users’ devices, making it faster and smoother.

  • Composable Functional Syntax: This is like building with LEGO blocks — combining small, functional parts to create something big and extraordinary.

  • Interception at the Network Level: It’s like catching a letter before it reaches your mailbox; it’s catching messages between your app and servers, giving you control and power.

WebPack vs. Vite

With the help of tabular representation, Ioannis took some tasks and recorded them saved based on WebPack, and Vite captures the amount of time saved on each task execution.

Unit Testing Coverage

Ioannis highlighted the code and explained each set of instructions, as shown in the image below. This image shows the instrumenting of the TypeScript backend project and creates README badges.

Integration Testing:

As we have seen in the above content, Ioannis addressed the problem statement in unit testing; Ioannis also highlighted the problem statement for integration testing.

Ioannis then resolved the problem.

Integration Testing Commands

Ioannis underscored that the page object acts like the hub for the commands received from UI and API.

Code Implementation of Page Object

The code implemented by Ioannis will help you understand Page Object with the mapping DOM model.

Code Implementation with Command UI

Code Implementation with Command API

Integration Testing — Test Cases

Why use Mocks?

Mocks are used to simulate real servers when testing, helping you catch and fix issues in a controlled environment before they reach the real world.

Using Mocks with MSW

Using Mocks with MSW is like setting up friendly versions of servers that your app talks to during testing. This helps you see how your app behaves without actually using real servers, making testing smoother and more reliable.

Record Mocks

Record Mocks are memory keepers for your tests. Acts like a variable in code that remembers the value of the variable and similarly records a mock to remember how your app talked to servers during testing so that you can play them later to validate if everything works just as it did before.

ZOD

This is used to validate the record mocks. It ensures that the recorded conversations between your app and the mock servers are accurate and reflect in real-life scenarios, just like a watchful guardian, ZOD checks if your app is correctly replaying those interactions, helping ensure your app behaves as expected during testing.

Process flow of ZOD

Integration Testing & Code Coverage

Later Ioannis shows the combination of the React App Instrumentation along with Cypress Code Coverage.

Code Implementation between WebPack vs. Vite

React App Instrumentation

Cypress Code Coverage

Cypress Code Coverage Report

Combined Coverage

Combining unit coverage, end-to-end testing code coverage, and merging into one for better execution time.

Code Implementation of Combined Coverage

There’s certainly more to explore in this session. To gain deeper insights into the non-functional testing aspects, you can go through the complete video that will be made live on the LambdaTest YouTube Channel shortly.

Q&A Session

Q. Could you share insights on how testing strategies must adapt to handle cross-component interaction challenges, ensuring compatibility and maintaining a practical user experience across different micro-frontends?

Ioannis: Certainly! Testing strategies for micro-frontends must evolve to address the intricacies of cross-component interactions. As micro-frontends comprise multiple smaller units, ensuring seamless compatibility and user experience is essential

Q. Could you elaborate on effective approaches for end-to-end testing? Specifically, how do you address challenges like data sharing, UI integration, and synchronization between micro-frontends to provide a comprehensive testing framework?

Ioannis: Effective end-to-end testing involves careful planning of test scenarios and leveraging automation for consistent results. Challenges like data sharing, UI integration, and synchronization between micro-frontends can be addressed by using mock data, UI testing tools, wait for mechanisms, and API verification. Running tests in parallel, ensuring realistic environments, and integrating testing into development pipelines are essential. Error handling, feedback incorporation, and detailed documentation further enhance testing quality, enabling comprehensive identification and resolution of issues.

To ask questions, share inquiries, or pose your queries, feel free to become part of the LambdaTest Community.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .