为什么我的React测试库测试如此缓慢?

huangapple go评论83阅读模式
英文:

Why are my React Testing Library tests so slow?

问题

我的工作场所有一个相当大的单页应用程序,它是在2020年构建的,使用Create React App作为构建工具。不幸的是,几乎每个组件的测试都需要很长时间。有时超过300秒,有时100秒,我见过的最快测试完成时间是30秒。这种情况是否正常?如果不正常,为什么测试会花这么长时间?

虽然这个代码示例无法重现,但我希望有人可以阅读一下它,并指出一些可能存在问题的地方:

以下是相关的依赖项:

"dependencies": {
  "@types/node": "^12.12.50",
  "@types/react": "^17.0.52",
  "@types/react-dom": "^17.0.18",
  "@types/react-router-dom": "^5.1.7",
  "@types/react-leaflet": "^2.8.1",
  "aws-amplify": "^4.3.26",
  "leaflet": "^1.7.1",
  "react": "^17.0.1",
  "react-dom": "^17.0.1",
  "react-leaflet": ">=3.1.0 <3.2.0 || ^3.2.1",
  "@react-leaflet/core": ">=1.0.0 <1.1.0 || ^1.1.1",
  "react-router-dom": "^6.4.3",
  "typescript": "^3.7.5"
}
"devDependencies": {
  "react-scripts": "^5.0.1",
  "@testing-library/dom": "^7.28.1",
  "@testing-library/jest-dom": "^5.11.6",
  "@testing-library/react": "^12.1.5",
  "@testing-library/user-event": "^13.5.0",
  "@types/jest": "^26.0.4",
  "jest": "^26.6.3",
  "node-sass": "^6.0.1"
}

本地开发的Node版本:v16.15.1

英文:

My workplace has largish single page application, it was built in 2020 and uses Create React App for the build tool. Unfortunately, nearly every component takes an excessive amount of time to test. Sometimes it is longer than 300seconds, sometimes 100seconds, the fastest I've ever seen a test complete is 30seconds. Is this normal behaviour, if not, why are these tests taking such a long time?

为什么我的React测试库测试如此缓慢?

While this code example is not reproducable, I am hoping that somebody may be able to take a read through it and highlight some possible problem areas:

// required imports from React &amp; 3rd party libraries
import React from &#39;react&#39;;
import { render, screen, within } from &#39;@testing-library/react&#39;;
import { API } from &#39;aws-amplify&#39;;

// react component to be tested, plus context and helper functions
import { MyComponent } from &#39;./MyComponent&#39;;
import { Store, UserContext, FurtherDetailContext } from &#39;store/store&#39;;
import * as helpers from &#39;helpers&#39;;

// mock data
import userContextMock from &#39;../../../tests/fixtures/userContext/userContext.json&#39;;
import furtherDetailContextMock from &#39;../../../tests/fixtures/furtherDetailContext/furtherDetailContext.json&#39;;
import gqlQueryResponse1 from &#39;../../../tests/fixtures/gql/gqlQueryResponse1.json&#39;;
import gqlQueryResponse2 from &#39;../../../tests/fixtures/gql/gqlQueryResponse2.json&#39;;
const mockJson = {
    this: &#39;is&#39;,
    an: &#39;example&#39;,
    response: true
};

const arrange = async () =&gt; {
    const mockToggleOpen = jest.fn();
    render(
        &lt;Store&gt;
            &lt;UserContext.Provider
                value={{
                    userContext: userContextMock,
                    setUserContext: () =&gt; {
                        // do nothing
                    }
                }}&gt;
                &lt;FurtherDetailContext.Provider
                    value={{
                        furtherDetailContext: furtherDetailContextMock,
                        setFurtherDetailContext: () =&gt; {
                            /*do nothing */
                        }
                    }}&gt;
                    &lt;MyComponent myProps={mockJson} toggleOpen={mockToggleOpen} /&gt;
                &lt;/FurtherDetailContext.Provider&gt;
            &lt;/UserContext.Provider&gt;
        &lt;/Store&gt;
    );

    // this component performs a network request before rendering
    await screen.findByText(&#39;text on the screen&#39;);
    const testid1 = screen.getByTestId(&#39;test-id-example&#39;);
    const testid2 = screen.getByTestId(&#39;test-id-example-2&#39;);
    return { testid1, testid2 };
};

describe(&#39;MyComponent&#39;, () =&gt; {
    beforeEach(() =&gt; {
        // get auth token
        jest.spyOn(helpers, &#39;getAuthtoken&#39;).mockResolvedValue(&#39;validAuthToken&#39;);
    });
    describe(&#39;all calls mocked&#39;, () =&gt; {
        beforeEach(() =&gt; {
            // mock graphql requests
            API.graphql = jest.fn().mockImplementation((url) =&gt; {
                const gqlQuery = url.query;
                if (RegExp(&#39;.*.mockGqlQuery*&#39;).test(gqlQuery)) {
                    return gqlQueryResponse1;
                }
                if (RegExp(&#39;.*.mockGql2*&#39;).test(gqlQuery)) {
                    return gqlQueryResponse2;
                }

                return;
            });
        });

        it(&#39;shows the original text on component mount&#39;, async () =&gt; {
            const { testid1 } = await arrange();
            expect(within(testid1).getByText(&#39;this text should be here&#39;)).toBeInTheDocument();
        });
    });
});

Here are the relevant dependencies:

&quot;dependencies&quot;: {
  &quot;@types/node&quot;: &quot;^12.12.50&quot;,
  &quot;@types/react&quot;: &quot;^17.0.52&quot;,
  &quot;@types/react-dom&quot;: &quot;^17.0.18&quot;,
  &quot;@types/react-router-dom&quot;: &quot;^5.1.7&quot;,
  &quot;@types/react-leaflet&quot;: &quot;^2.8.1&quot;,
  &quot;aws-amplify&quot;: &quot;^4.3.26&quot;,
  &quot;leaflet&quot;: &quot;^1.7.1&quot;,
  &quot;react&quot;: &quot;^17.0.1&quot;,
  &quot;react-dom&quot;: &quot;^17.0.1&quot;,
  &quot;react-leaflet&quot;: &quot;&gt;=3.1.0 &lt;3.2.0 || ^3.2.1&quot;,
  &quot;@react-leaflet/core&quot;: &quot;&gt;=1.0.0 &lt;1.1.0 || ^1.1.1&quot;,
  &quot;react-router-dom&quot;: &quot;^6.4.3&quot;,
  &quot;typescript&quot;: &quot;^3.7.5&quot;,
}
&quot;devDependencies&quot;: {
  &quot;react-scripts&quot;: &quot;^5.0.1&quot;,
  &quot;@testing-library/dom&quot;: &quot;^7.28.1&quot;,
  &quot;@testing-library/jest-dom&quot;: &quot;^5.11.6&quot;,
  &quot;@testing-library/react&quot;: &quot;^12.1.5&quot;,
  &quot;@testing-library/user-event&quot;: &quot;^13.5.0&quot;,
  &quot;@types/jest&quot;: &quot;^26.0.4&quot;,
  &quot;jest&quot;: &quot;^26.6.3&quot;,
  &quot;node-sass&quot;: &quot;^6.0.1&quot;,
}

local development node version: v16.15.1

答案1

得分: 1

这是一个众所周知的问题,create-react-app的速度相当慢;而这个问题也延伸到了测试中。

问题可能出在webpack,你的打包程序上,可悲的是你不能轻易将使用create-react-app构建的应用与它分离。

我的建议是转向使用vite,然后使用vite的测试库:vitest

(我认为你可以保留正常的create-react-scripts,并且仅仅在测试中使用vitetest。)

我理解这可能不是你想要得到的答案类型 - 这不仅仅是_又一个依赖项_,它还意味着改变了很多基础架构;但总的来说,我发现从create-react-app转向vite非常有用;速度差异如天与地之别。

这是一个vitest的迁移指南,你可能会找到它很有用。

英文:

It's a well known issue that create-react-app is quite slow; and this issue is also extended to the tests.

The problem is probably webpack, your bundler program, sadly you can't easily decouple an app built with create-react-app from it.

My recommendation is to switch over to vite, and then to use vite's testing library: vitest in particular.

(I believe you might keep your normal create-react-scripts and only use vitetest for testing.)

I understand that this is not the type of answer you might like to receive - it's not only Yet Another Dependency it also means changing a lot of the plumbing; but overall I found it incredibly useful to switch from create-react-app to vite; the speed difference is night and day.

Here's a migration guide for vitest that you might find useful.

huangapple
  • 本文由 发表于 2023年6月15日 17:36:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76481130.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定