Testing SharePoint Framework (SPFx) Components with Jest and React Testing Library

Pexels Thisisengineering 3861972
Photo by ThisIsEngineering

Introduction

Testing is a crucial aspect of any software development process, including SharePoint Framework (SPFx) development. Here are some reasons why testing is important:

  1. Quality Assurance: Testing helps ensure the quality of your SPFx components by catching bugs and issues early in the development process. This can save a lot of time and effort in the long run.
  2. Performance Verification: Through testing, you can verify whether your SPFx components perform as expected under various conditions. This includes checking load times, responsiveness, and more.
  3. Improved User Experience: By identifying and fixing issues through testing, you can provide a better user experience. A thoroughly tested SPFx component will be more reliable and efficient, leading to improved user satisfaction.
  4. Maintenance and Scalability: Well-tested code is typically easier to maintain and scale. As your SPFx components grow and evolve, having a solid suite of tests can make it easier to add new features and capabilities.
  5. Collaboration and Communication: Tests can serve as a form of documentation, showing what your code is supposed to do. This can be particularly useful in a team setting, where tests can help communicate the intended functionality of your SPFx components to other developers.

Testing is an essential part of SPFx development. It helps ensure the quality, reliability, and performance of your components, leading to a better end product and a smoother user experience.

Image 5

How to test?

First, we need to install Jest, React Testing Library, and their types and presets:

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

Then, we create a jest.config.js file in our project root:

module.exports = {
  // The root of our source code
  roots: ['<rootDir>/src'],

  // Use ts-jest for transpiling TypeScript code to JavaScript
  transform: {
    '^.+\\.tsx?$': 'ts-jest',
  },

  // The regex for finding test files
  testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',

  // The file extensions Jest should understand
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],

  // Enable coverage reporting
  collectCoverage: true,
  coverageReporters: ['json', 'lcov', 'text', 'cobertura'],

  // Enable verbose output
  verbose: true,

  // Use jest-junit for outputting test results in a format that reporting tools understand
  testResultsProcessor: 'jest-junit',

  // Map CSS imports to identity-obj-proxy for mocking
  moduleNameMapper: {
    '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
  },
};

Writing Tests

Let’s say we have a simple React component in our SPFx project:

// src/webparts/helloWorld/components/HelloWorld.tsx

// Define the props for our component
export interface IHelloWorldProps {
  name: string;
}

// Define the component
export const HelloWorld: React.FC<IHelloWorldProps> = (props) => {
  // Render a greeting message
  return <h1>Hello, {props.name}!</h1>;
};

We can write a test for this component like so:

// src/webparts/helloWorld/components/__tests__/HelloWorld.test.tsx
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import { HelloWorld } from '../HelloWorld';

it('renders hello message', () => {
  // Render the component with React Testing Library's render function
  render(<HelloWorld name="SPFx" />);

  // Check if the rendered component includes the text "Hello, SPFx!"
  expect(screen.getByText('Hello, SPFx!')).toBeInTheDocument();
});

Mocking

When testing components that have dependencies, we can use Jest’s mocking capabilities. However, it’s important to use mocks sparingly to keep our tests focused and maintainable.

For example, if we have a component that uses a service to fetch data, we could mock this service in our test. This allows us to isolate the behavior of the component from its dependencies:

// src/webparts/helloWorld/components/HelloWorld.tsx
import { IDataService } from '../../../services/IDataService';

// Define the props for our component
export interface IHelloWorldProps {
  dataService: IDataService;
}

// Define the component
export const HelloWorld: React.FC<IHelloWorldProps> = (props) => {
  // Initialize state for storing the fetched data
  const [data, setData] = React.useState(null);

  // Fetch data when the component mounts
  React.useEffect(() => {
    props.dataService.fetchData().then(setData);
  }, [props.dataService]);

  // Render the fetched data
  return <h1>{data}</h1>;
};

In our test, we could create a mock data service and pass it to the HelloWorld component:

// src/webparts/helloWorld/components/__tests__/HelloWorld.test.tsx
import { render, screen, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import { HelloWorld } from '../HelloWorld';

it('renders data from the service', async () => {
  // Create a mock data service
  const mockDataService = {
    fetchData: jest.fn().mockResolvedValue('Hello, SPFx!'),
  };

  // Render the component with the mock data service
  render(<HelloWorld dataService={mockDataService} />);

  // Wait for the Promise to resolve and the component to re-render
  await waitFor(() => screen.getByText('Hello, SPFx!'));

  // Check if the rendered component includes the fetched data
  expect(screen.getByText('Hello, SPFx!')).toBeInTheDocument();

  // Check if the fetchData method of the mock data service was called
  expect(mockDataService.fetchData).toHaveBeenCalled();
});

Don’t forget the Dev Proxy with SharePoint Framework (SPFx)

How Dev Proxy facilitates the testing of SPFx solutions by intercepting and simulating web requests, while also highlighting the importance of proper configuration to avoid interference with the workbench.

Dev Proxy with SharePoint Framework (SPFx) solutions testing:

  • SPFx & Dev Proxy: SharePoint Framework (SPFx) is a model for extending SharePoint and other Microsoft services. Dev Proxy is used to intercept and analyze web requests made by SPFx solutions.
  • Configuration: Before starting Dev Proxy, configure it to intercept specific requests, such as those to Microsoft Graph and SharePoint REST APIs, by defining URLs in the urlsToWatch property.
  • Testing with Workbench: SPFx solutions are tested using the SharePoint Framework workbench in the browser. Dev Proxy, by default, intercepts all browser requests, which can interfere with workbench testing.
  • Excluding Workbench API: To prevent Dev Proxy from blocking workbench requests, update the urlsToWatch property to exclude the web part API. The SPFx preset from the Sample Solution Gallery already excludes this URL.

Reference: learn.microsoft.com

Unit test are not enough, believe me ! What about the (CI/CD) and DevOps practices?

Image 6

In a comprehensive testing strategy, unit tests, integration tests, and functional tests all play important roles:

  1. Unit Tests: These are the tests we’ve been discussing so far. They test individual components or functions in isolation. In the context of SPFx, this might mean testing individual React components or utility functions.
  2. Integration Tests: These tests check how different parts of your system work together. In an SPFx project, this could involve testing the interaction between a React component and a SharePoint list, for example. You’d mock the SharePoint list in your test and check if your component correctly adds, updates, or deletes items in the list.
  3. Functional Tests: Also known as end-to-end tests, these tests check the functionality of your application as a whole. They simulate user interactions and check if the application behaves as expected. In an SPFx project, you might use a tool like Puppeteer or Cypress for functional testing. These tools can simulate user interactions with your SharePoint site and check if your SPFx components behave as expected.

By combining unit tests, integration tests, and functional tests, you can ensure that your SPFx components work correctly on their own (unit tests), in conjunction with other components or services (integration tests), and as part of the overall SharePoint site (functional tests).

Continuous Integration/Continuous Deployment (CI/CD) and DevOps practices. Here’s why:

  1. Early Bug Detection: Automated tests that are run on every commit allow teams to catch and fix issues early in the development cycle. This can save a lot of time and effort compared to finding bugs in production.
  2. Confidence in Code Quality: A comprehensive suite of tests gives developers confidence that their code is functioning as expected. This is particularly important when making changes to existing code, as tests can help ensure that the changes don’t break anything.
  3. Faster Development Cycle: Automated testing is a key part of CI/CD, which aims to automate parts of the development process to speed up the release cycle. By automating testing, teams can get immediate feedback on their code and integrate smaller pieces of code more frequently.
  4. Risk Mitigation: Automated tests help mitigate risk by catching regressions and errors that could impact the user experience or system stability. This is especially important in a DevOps culture, where rapid iteration and frequent deployments are common.
  5. Improved Collaboration: In a DevOps culture, developers, operations teams, and other stakeholders must work together closely. Automated testing provides a safety net and a common language that can improve collaboration across these different roles.
  6. Continuous Improvement: In a CI/CD pipeline, tests are continuously run, providing regular feedback on the health of the system. This allows for continuous improvement of both the code and the tests themselves.

Testing is not just a quality assurance activity, but a core component of modern, agile software development practices like CI/CD and DevOps. It enables teams to move faster, deliver higher quality software, and respond to changes and challenges with greater agility.

11749548

Use Case: Testing in SharePoint Framework (SPFx) Development for XYZ LLC

Objective:


XYZ LLC aims to ensure the delivery of high-quality, reliable, and efficient components in their SharePoint Framework (SPFx) development projects. By implementing robust testing practices, they strive to build better, more reliable, and user-friendly products for their clients.

Scenario:

As a reputable technology firm specializing in SharePoint solutions, XYZ LLC is committed to delivering cutting-edge products that meet and exceed client expectations. With a team of experienced developers dedicated to SPFx projects, they understand the critical role of testing in maintaining product quality and customer satisfaction.

Use Case Steps:

Project Initiation:

    • XYZ LLC initiates a new SPFx development project, outlining the project scope, requirements, and objectives.
    • The development team collaborates closely with stakeholders to ensure a comprehensive understanding of project goals and user expectations.

    Testing Strategy Development:

      • Based on the project requirements, XYZ LLC formulates a comprehensive testing strategy encompassing unit testing, integration testing, and end-to-end testing.
      • Key functionalities, user scenarios, and edge cases are identified for testing to ensure maximum coverage and reliability.

      Test Environment Setup:

        • XYZ LLC sets up dedicated testing environments that closely mimic the production environment for SPFx development.
        • Utilizing industry-standard testing tools and frameworks such as Jest and Enzyme, they establish an efficient testing infrastructure.

        Continuous Integration/Continuous Deployment (CI/CD) Integration:

          • XYZ LLC integrates testing seamlessly into their CI/CD pipeline, enabling automated testing for every code change.
          • Automated tests are triggered automatically upon code commits, providing rapid feedback to developers and identifying any regressions at an early stage.

          Test Execution and Analysis:

            • Developers write unit tests to validate the functionality and behavior of individual SPFx components.
            • Integration tests are conducted to ensure seamless interaction between different components within the SPFx solution.
            • End-to-end tests simulate real user interactions and workflows to validate the overall functionality and user experience of the SPFx application.
            • Test results are meticulously analyzed, and any failures or issues are promptly addressed by the development team.

            Regression Testing and Bug Fixing:

              • XYZ LLC conducts regular regression testing to detect and mitigate any unintended changes or defects introduced during development.
              • Detected bugs are logged, prioritized, and assigned to developers for swift resolution.
              • Once fixed, the affected components undergo retesting to ensure the issues have been effectively addressed.

              User Acceptance Testing (UAT):

                • Before deployment, XYZ LLC conducts thorough UAT sessions with end-users or stakeholders to validate that the SPFx solution meets their requirements and expectations.
                • Feedback gathered during UAT sessions is carefully considered to fine-tune the application and address any last-minute issues or enhancements.

                Deployment and Monitoring:

                  • Upon successful completion of testing and UAT, the SPFx solution is deployed to the production environment.
                  • XYZ LLC implements robust monitoring procedures to track the performance, reliability, and user satisfaction of the deployed application.
                  • Any issues or concerns identified post-deployment are promptly addressed to ensure a seamless user experience.

                  Benefits:

                  • By integrating testing into their SPFx development process, XYZ LLC ensures the delivery of high-quality, reliable, and user-friendly products to their clients.
                  • Automated testing in the CI/CD pipeline enables rapid feedback and early detection of issues, facilitating prompt resolution and continuous improvement.
                  • Thorough testing reduces the risk of bugs and regressions, enhancing the overall stability and robustness of SPFx solutions delivered by XYZ LLC.

                  Conclusion

                  In conclusion, testing in SharePoint Framework (SPFx) development, as in all software development, is not just a necessity but a cornerstone of good development practices. It ensures the delivery of high-quality, reliable, and efficient components. When integrated into a CI/CD pipeline and a DevOps culture, testing becomes a powerful tool that provides immediate feedback, facilitates collaboration, and promotes continuous improvement. It’s the safety net that allows teams to innovate with confidence, knowing that any issues will be caught early and fixed promptly. So, whether you’re developing a small web part or a large-scale SharePoint solution, remember – testing isn’t just about finding bugs; it’s about building a better, more reliable, and user-friendly product. Happy testing! 

                  joao

                  Joao Livio

                  João has over two decades of IT experience and holds several certifications, including Microsoft Certified Professional (MCP) and Microsoft Certified Technology Specialist (MCTS). He is also a Lean Specialist with expertise in Lean Management, Nintex, and other training programs from LinkedIn and Udemy, including exams related to Azure and the Power Platform. As a Consultant and Advisor for Modern Work, João assists clients in unlocking their digital potential and optimizing productivity and collaboration. His approach is agnostic to technology, focusing on practical solutions that align with business goals. He has consistently been recognized as a Microsoft Most Valuable Professional (MVP) for 10 consecutive years. His commitment to excellence extends beyond technical expertise; he also values consistency, mental health, creative thinking, teamwork, and fun at work. João believes that learning every day within a team context is the key to continuous improvement.

                  You may also like...

                  Leave a Reply

                  Your email address will not be published. Required fields are marked *