NervJS / taro

开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5/React Native 等应用。 https://taro.zone/
https://docs.taro.zone/
Other
35.47k stars 4.79k forks source link

Taro 3x 版本该如何进行jest单元测试? #8632

Closed kiana-god closed 2 years ago

kiana-god commented 3 years ago

相关平台

微信小程序

小程序基础库: 2.13.1 使用框架: React

复现步骤

官网推荐使用jest进行单元测试,但就没有下文了,希望能够这方面的使用说明。在git中,有用户提出按照taro-ui进行单元测试,也有提出用taro-testing-library,但它又说3.0版本后需要react-testing-library,烦恼了很久都没能正常运行。只能完成纯函数方法的单元测试。对于引入了 import { View, Button } from '@tarojs/components'; 这样的页面,都无法运行

期望结果

希望能有这方面的解决方法

实际结果

Details:

/Users/mac/work/invest-kc/node_modules/@tarojs/components/dist-h5/react/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import reactifyWc from './utils/reactify-wc';
                                                                                         ^^^^^^

SyntaxError: Cannot use import statement outside a module

  1 | import React from 'react';
> 2 | import { View, Button } from '@tarojs/components';
    | ^
  3 | import './index.less';
  4 | 
  5 | interface ChooseBoxInfo {

  at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
  at Object.<anonymous> (src/components/ChooseBox/index.tsx:2:1)

环境信息

👽 Taro v3.0.22

  Taro CLI 3.0.22 environment info:
    System:
      OS: macOS High Sierra 10.13.6
      Shell: 5.3 - /bin/zsh
    Binaries:
      Node: 12.18.4 - /var/folders/74/hq3d66xj7d9807zk25c_hz8c0000gn/T/yarn--1612248949469-0.1381571842473257/node
      Yarn: 1.22.10 - /var/folders/74/hq3d66xj7d9807zk25c_hz8c0000gn/T/yarn--1612248949469-0.1381571842473257/yarn
      npm: 6.14.6 - /usr/local/bin/npm
    npmPackages:
      @tarojs/cli: 3.0.22 => 3.0.22 
      @tarojs/components: 3.0.22 => 3.0.22 
      @tarojs/mini-runner: 3.0.22 => 3.0.22 
      @tarojs/react: 3.0.22 => 3.0.22 
      @tarojs/runtime: 3.0.22 => 3.0.22 
      @tarojs/taro: 3.0.22 => 3.0.22 
      @tarojs/webpack-runner: 3.0.22 => 3.0.22 
      babel-preset-taro: 3.0.22 => 3.0.22 
      eslint-config-taro: 3.0.22 => 3.0.22 
      react: ^16.10.0 => 16.14.0 
      taro-ui: ^3.0.0-alpha.3 => 3.0.0-alpha.3 

补充信息

希望能有解决方式,全天等待

Chen-jj commented 3 years ago

6608

kiana-god commented 3 years ago

6608

方便提供taro3.x 小程序项目的jest 配置和 demo么 , 非常感谢. -0.0-

kiana-god commented 3 years ago

6608

是小程序,不是h5

Chen-jj commented 3 years ago

目前人力有限,计划在 Q1 内能推出一个完整的单测方案,也欢迎提供思路或贡献代码~

kiana-god commented 3 years ago

目前人力有限,计划在 Q1 内能推出一个完整的单测方案,也欢迎提供思路或贡献代码~ 您好。taro-testing-library 中注明 For Taro 3.x 使用 react-testing-library;按照说明依次操作 1、yarn add --dev @testing-library/react 2、moduleNameMapper: { '@tarojs/components': '@tarojs/components/dist-h5/react', ... }, 3、yarn test

按此流程操作,就会报出

● Test suite failed to run

/Users/mac/work/invest-kc/node_modules/@tarojs/components/dist-h5/react/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import reactifyWc from './utils/reactify-wc';
                                                                                                ^^^^^^^^^^

SyntaxError: Unexpected identifier

  1 | import React from 'react';
> 2 | import { View, Button } from '@tarojs/components';
    | ^
  3 | import './index.less';
  4 |
  5 | interface ChooseBoxInfo {

  at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
  at Object.<anonymous> (src/components/ChooseBox/index.tsx:2:1)

Test Suites: 1 failed, 1 total Tests: 0 total Snapshots: 0 total Time: 5.663 s Ran all test suites related to changed files.

请问,这种哪方面的问题?

ariesjia commented 3 years ago

@kiana-god 你这个是jest的问题哈, 看你的文件名字,你应该用的是babel吧。你配置下 babel-jest吧

ariesjia commented 3 years ago

@kiana-god 可以参考这个工程 https://github.com/Kevin170113664/taro-dojo

对于3.x + React,无论是使用jest+enzyme还是jest+testing library 都一样, 配置moduleNameMapper即可

kiana-god commented 3 years ago

@kiana-god 可以参考这个工程 https://github.com/Kevin170113664/taro-dojo

对于3.x + React,无论是使用jest+enzyme还是jest+testing library 都一样, 配置moduleNameMapper即可

感谢前辈

wangshuaixue commented 3 years ago

请问这是什么问题呀 查不到解法呢 配置了babel也不好使 taro还需要配置别的么

Details:

/Users/julive/Desktop/comjia/julive-miniprogram/node_modules/_@tarojs_runtime@3.0.10@@tarojs/runtime/dist/runtime.esm.js:3659
export { Current, CurrentReconciler, Events, FormElement, Style, TaroElement, TaroEvent, TaroNode, TaroRootElement, TaroText, caf as cancelAnimationFrame, connectReactPage, connectVuePage, createComponentConfig, createDocument, createEvent, createPageConfig, createReactApp, createRecursiveComponentConfig, createVue3App, createVueApp, document$1 as document, eventCenter, getComputedStyle, getCurrentInstance, hydrate, injectPageInstance, navigator, nextTick, now, options, raf as requestAnimationFrame, stringify, useAddToFavorites, useDidHide, useDidShow, useOptionMenuClick, usePageScroll, usePullDownRefresh, usePullIntercept, useReachBottom, useReady, useResize, useRouter, useScope, useShareAppMessage, useShareTimeline, useTabItemTap, useTitleClick, window$1 as window };
^^^^^^

SyntaxError: Unexpected token export

  at Runtime.createScriptFromCode (node_modules/_jest-runtime@26.6.3@jest-runtime/build/index.js:1350:14)
  at Object.<anonymous> (node_modules/_@tarojs_api@3.0.10@@tarojs/api/dist/index.js:5:15)
wangshuaixue commented 3 years ago

请问这是什么问题呀 查不到解法呢 配置了babel也不好使 taro还需要配置别的么

Details:

/Users/julive/Desktop/comjia/julive-miniprogram/node_modules/_@tarojs_runtime@3.0.10@@tarojs/runtime/dist/runtime.esm.js:3659
export { Current, CurrentReconciler, Events, FormElement, Style, TaroElement, TaroEvent, TaroNode, TaroRootElement, TaroText, caf as cancelAnimationFrame, connectReactPage, connectVuePage, createComponentConfig, createDocument, createEvent, createPageConfig, createReactApp, createRecursiveComponentConfig, createVue3App, createVueApp, document$1 as document, eventCenter, getComputedStyle, getCurrentInstance, hydrate, injectPageInstance, navigator, nextTick, now, options, raf as requestAnimationFrame, stringify, useAddToFavorites, useDidHide, useDidShow, useOptionMenuClick, usePageScroll, usePullDownRefresh, usePullIntercept, useReachBottom, useReady, useResize, useRouter, useScope, useShareAppMessage, useShareTimeline, useTabItemTap, useTitleClick, window$1 as window };
^^^^^^

SyntaxError: Unexpected token export

  at Runtime.createScriptFromCode (node_modules/_jest-runtime@26.6.3@jest-runtime/build/index.js:1350:14)
  at Object.<anonymous> (node_modules/_@tarojs_api@3.0.10@@tarojs/api/dist/index.js:5:15)
ariesjia commented 3 years ago

@wsx123456 配置下 babel jest

wangshuaixue commented 3 years ago

我的jest.config配置了 还是不行
这是babelconfig // babel-preset-taro 更多选项和默认值: // https://github.com/NervJS/taro/blob/next/packages/babel-preset-taro/README.md const apis = require("@tarojs/taro-h5/dist/taroApis");

module.exports = { presets: [ ['taro', { framework: 'react', ts: true }], ['@babel/preset-env', { targets: { node: 'current' } }], "@babel/preset-typescript" ], plugins: [ ["@babel/plugin-transform-modules-commonjs", { "allowTopLevelThis": true }], [ "babel-plugin-transform-taroapi", { apis } ] ] }

下面是jestconfig const path = require('path')

module.exports = { rootDir: path.resolve(__dirname, './'), preset: "./jest-preset.json", moduleNameMapper: { '^@/(.*)$': '/src/$1', '\.(css|less|sass|scss|stylp)$': 'identity-obj-proxy', '@tarojs/components': '@tarojs/components/dist-h5/react' }, transform: { '^.+\.(js|jsx|ts|tsx)$': '/node_modules/babel-jest', '^.+\.esm.js?$': 'ts-jest', },

transformIgnorePatterns: ["^.+\.(css|sass|scss|less)$", "/node_modules/", "/src/@types/", "\.pnp\.[^\\/]+$"], testPathIgnorePatterns: ["/node_modules/"], // jest默认查找后缀名 moduleFileExtensions: [ 'js', 'json', 'ts', 'jsx', 'tsx' ], collectCoverage: true, coverageDirectory: "coverage", setupFiles: [ "./test/weapp/mockPage.js" ], testEnvironment: "node", reporters: [ "default", ["./node_modules/jest-html-reporter", { "pageTitle": "Test Report" // "outputPath": "public/jest-report.html" }] ] };

kiana-god commented 3 years ago

我的jest.config配置了 还是不行 这是babelconfig // babel-preset-taro 更多选项和默认值: // https://github.com/NervJS/taro/blob/next/packages/babel-preset-taro/README.md const apis = require("@tarojs/taro-h5/dist/taroApis");

module.exports = { presets: [ ['taro', { framework: 'react', ts: true }], ['@babel/preset-env', { targets: { node: 'current' } }], "@babel/preset-typescript" ], plugins: [ ["@babel/plugin-transform-modules-commonjs", { "allowTopLevelThis": true }], [ "babel-plugin-transform-taroapi", { apis } ] ] }

下面是jestconfig const path = require('path')

module.exports = { rootDir: path.resolve(__dirname, './'), preset: "./jest-preset.json", moduleNameMapper: { '^@/(.*)$': '/src/$1', '.(css|less|sass|scss|stylp)$': 'identity-obj-proxy', '@tarojs/components': '@tarojs/components/dist-h5/react' }, transform: { '^.+.(js|jsx|ts|tsx)$': '/node_modules/babel-jest', '^.+.esm.js?$': 'ts-jest', },

transformIgnorePatterns: ["^.+.(css|sass|scss|less)$", "/node_modules/", "/src/@types/", ".pnp.[^\/]+$"], testPathIgnorePatterns: ["/node_modules/"], // jest默认查找后缀名 moduleFileExtensions: [ 'js', 'json', 'ts', 'jsx', 'tsx' ], collectCoverage: true, coverageDirectory: "coverage", setupFiles: [ "./test/weapp/mockPage.js" ], testEnvironment: "node", reporters: [ "default", ["./node_modules/jest-html-reporter", { "pageTitle": "Test Report" // "outputPath": "public/jest-report.html" }] ] };

参考下我的吧。jest.config

module.exports = { roots: ['/src'], setupFiles: ['/src/setupTests.js'], clearMocks: true, // 在每个测试前自动清理mock的调用和实例instance。等效于在每个test之前调用 coverageDirectory: 'coverage', // Jest输出覆盖率以及添加输出覆盖率文件的名称utils collectCoverageFrom: ['/src/*/.{js,jsx,tsx,ts}'], // 哪些文件需要收集覆盖率信息/src//.{js,jsx,tsx,ts} coverageProvider: 'babel', // 声明到底用哪个provider来用于指导代码的覆盖测试 testPathIgnorePatterns: [ '/.next/', '/node_modules/', '[/\\]node_modules[/\\].+\.(js|jsx|mjs)$' ], // 转换时需忽略的文件 verbose: true, // 是否应在运行期间报告每个单独的测试。执行后,所有错误也仍将显示在底部。 moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json'], // 代表支持加载的文件名 moduleNameMapper: { '@tarojs/components': '@tarojs/components/dist-h5/react', '^.+\.(css|scss|less)$': '/src/config/jest/style-mock.js', '@/(.)$': '/src/$1' }, // 代表需要被 Mock 的资源名称。如果需要 Mock 静态资源(如less、scss等),则需要配置 Mock 的路径 testMatch: ['/src//*.{spec,test}.{js,jsx,ts,tsx}'], // Jest用于检测测试文件的全局模式 transform: { '^.+\.(js|jsx|ts|tsx)$': '/node_modules/babel-jest' }, // 用于编译 ES6/ES7 语法 snapshotResolver: '/src/config/jest/snapshotResolver.js', // 快照路径配置 transformIgnorePatterns: ['^.+\.(css|sass|scss|less)$', '/dist/'] // 忽略转换 };

guaizi149 commented 3 years ago

目前人力有限,计划在 Q1 内能推出一个完整的单测方案,也欢迎提供思路或贡献代码~

Q1快结束了,这个提上日程了吗?

ds147000 commented 3 years ago

em....急需一个单元测试案例

wangshuaixue commented 3 years ago

小程序里面模拟taro/taro 导出的Current变量以及子项 怎么模拟 有写过的吗

kamo9527 commented 3 years ago

jest 单测无法通过useReady, useDidShow钩子函数。希望官方能提供解决单测方案 报错:Too many re-renders. React limits the number of renders to prevent an infinite loop.

wangshuaixue commented 3 years ago

请问下你们现在 单测写到什么程度呢 业务代码有测试吗

ds147000 commented 3 years ago

请问下你们现在 单测写到什么程度呢 业务代码有测试吗

业务代码也写,部分需要操作进行模拟点击完成

kiana-god commented 3 years ago

@wsx123456 配置下 babel jest

大佬,我想问,Taro的jest,如何处理 useReady, useDidShow, useDidHide ,这些Taro钩子 如果单纯的mock自调用,钩子内使用了useState会告警,重复渲染。 有这方面的见解吗?

wangshuaixue commented 3 years ago

请问下你们现在 单测写到什么程度呢 业务代码有测试吗

业务代码也写,部分需要操作进行模拟点击完成

那你们写的过程中没有报引入taro一些内部函数错误的问题吗

wangshuaixue commented 3 years ago

请问下你们现在 单测写到什么程度呢 业务代码有测试吗

业务代码也写,部分需要操作进行模拟点击完成

有没有3.x的示例

goldEli commented 3 years ago

目前人力有限,计划在 Q1 内能推出一个完整的单测方案,也欢迎提供思路或贡献代码~

@Chen-jj 你好请问,完整的单侧方案有了吗?

chenjunjia97 commented 3 years ago

我的jest.config配置了 还是不行 这是babelconfig // babel-preset-taro 更多选项和默认值: // https://github.com/NervJS/taro/blob/next/packages/babel-preset-taro/README.md const apis = require("@tarojs/taro-h5/dist/taroApis");

module.exports = { presets: [ ['taro', { framework: 'react', ts: true }], ['@babel/preset-env', { targets: { node: 'current' } }], "@babel/preset-typescript" ], plugins: [ ["@babel/plugin-transform-modules-commonjs", { "allowTopLevelThis": true }], [ "babel-plugin-transform-taroapi", { apis } ] ] }

下面是jestconfig const path = require('path')

module.exports = { rootDir: path.resolve(__dirname, './'), preset: "./jest-preset.json", moduleNameMapper: { '^@/(.*)$': '/src/$1', '.(css|less|sass|scss|stylp)$': 'identity-obj-proxy', '@tarojs/components': '@tarojs/components/dist-h5/react' }, transform: { '^.+.(js|jsx|ts|tsx)$': '/node_modules/babel-jest', '^.+.esm.js?$': 'ts-jest', },

transformIgnorePatterns: ["^.+.(css|sass|scss|less)$", "/node_modules/", "/src/@types/", ".pnp.[^\/]+$"], testPathIgnorePatterns: ["/node_modules/"], // jest默认查找后缀名 moduleFileExtensions: [ 'js', 'json', 'ts', 'jsx', 'tsx' ], collectCoverage: true, coverageDirectory: "coverage", setupFiles: [ "./test/weapp/mockPage.js" ], testEnvironment: "node", reporters: [ "default", ["./node_modules/jest-html-reporter", { "pageTitle": "Test Report" // "outputPath": "public/jest-report.html" }] ] };

请问解决了吗????

qmy777 commented 2 years ago

小程序里面模拟taro/taro 导出的Current变量以及子项 怎么模拟 有写过的吗

同求该问题的解决方案呀~我这边模仿taro-ui的babel.config.js里面配置的babel-plugin-transform-taroapi 压根就没啥作用;还是会报Taro.xxxxx is not a function;我严重怀疑某些Taro.xxxx的方法可能是需要实例化一个APP(如 微信小程序)出来,才可以进行正常调用的

ZakaryCode commented 2 years ago

Jest 参考文档