Модульное тестирование React в действии

модульный тест React.js
  • суг команда
  • Автор: Ди

предисловие

Преимущества модульного тестирования:

  • Это может обеспечить согласованность полученных результатов и повысить стабильность проектов и компонентов.
  • Разработчики пишут код в соответствии с идеей модульного тестирования, что может прояснить структуру кода и улучшить читаемость кода.

Поскольку проекты, разработанные автором, становятся все больше и больше, а возможность повторного использования общедоступных компонентов высока, его стабильность особенно важна. Поэтому крайне необходимо внедрять юнит-тесты.

плохое модульное тестирование:

  • Это займет определенную стоимость разработки и увеличит рабочую нагрузку разработки.
  • Добавление юнит-тестов к старым проектам сильно изменило ситуацию, и здесь будут определенные риски.
  • Будет определенная стоимость обучения, а требования к разработчикам относительно высоки.
  • Если модульное тестирование используется в некоторых компонентах с низкой возможностью повторного использования, оно будет неэффективным, а стоимость разработки будет высокой.

Выбор

Прежде чем делать проект по тестированию подразделения, я ссылаюсь на ряд статей и официальных документов в Интернете, окончательный выбор для jest + React-test-Render + фермент.

  • Jest

    Jest — это среда тестирования, созданная Facebook.По сравнению с другими средами тестирования, одной из ее основных особенностей является то, что она объединяет такие функции, как Mocha, chai, jsdom, sinon и т. д., и имеет встроенные общие инструменты тестирования, такие как встроенный - в утверждениях, инструментах тестового покрытия и из коробки.

  • react-test-render

    Вместе с react-test-render Jest предоставляет возможности тестирования моментальных снимков.

    Когда тест моментального снимка запускается в первый раз, будет создан удобочитаемый снимок.При повторном выполнении теста будет оцениваться, пройден ли тест, путем сравнения файла моментального снимка с вновь созданным снимком.

    Когда Jest выполняется, если он находитtoMatchSnapshotметод, папка __snapshots__ будет создана в каталоге того же уровня для хранения файлов снимков, и каждый тест будет сравниваться с снимком, созданным в первый раз.

  • Enzyme

    React официально предоставил библиотеку инструментов для тестирования: react-dom/test-utils. Но пользоваться им неудобно, поэтому есть сторонние библиотеки для упаковки, например Enzyme от Airbnb. Две его основные характеристики:

    • Предоставляет набор лаконичных и мощных API, а также встроенный Cheerio.
    • Реализована обработка DOM в стиле jQuery, и опыт разработки очень удобен.

    Три метода рендеринга

    shallow: поверхностный рендеринг, который является инкапсуляцией официального поверхностного рендерера. Рендеринг компонентов в виртуальные объекты DOM будет отображать только первый слой, а подкомпоненты не будут отображаться, что делает его очень эффективным. Не требует среды DOM и может использовать jQuery для доступа к информации о компонентах.

    render: статический рендеринг, он преобразует компонент React в статическую строку HTML, а затем использует библиотеку Cheerio для анализа этой строки и возвращает объект экземпляра Cheerio, который можно использовать для анализа структуры HTML компонента.

    mount: Полная визуализация, при которой компонент визуализируется и загружается в реальный узел DOM, который используется для проверки взаимодействия DOM API и жизненного цикла компонента. jsdom используется для имитации среды браузера.

    Среди трех методов,shallowа такжеmountПоскольку он возвращает объект DOM, вы можете использовать имитацию для интерактивного моделирования иrenderметод не может. в общемshallowМетод может соответствовать требованиям.Если вам нужно судить о подкомпонентах, вам нужно использоватьrender, если вам нужно протестировать жизненный цикл компонента, вам нужно использоватьmountметод.

    Уведомление:enzymeТакже необходимо установить адаптеры в соответствии с версией React, таблица соответствия адаптеров выглядит следующим образом:

строить планы

Сказав так много раньше, пришло время кодировать.

  • содержание

    Я создаю новый в корневом каталогеunitTestкаталог, его структура каталогов:

    • jest.config.js: файл конфигурации jest

    • mocks: фиктивный каталог файлов

    • компоненты: общедоступный каталог тестовых наборов компонентов проекта.

    • component/__ snapshots __: каталог для хранения снимков, автоматически создаваемых при запуске модульных тестов.

  • Установка (поскольку автором является версия react16, установленная версия адаптера — фермент-адаптер-реагировать-16)

    npm install jest enzyme enzyme-adapter-react-16 react-test-renderer

  • настроить

    Jest поддерживает запись конфигурации непосредственно в файл package.json, но автор имеет небольшую привычку к чистоте и любит записывать файл конфигурации вunitTestВнутри легко найти и прочитать.

    // package.json
    {
        "scripts": {
            "jest": "jest --config ./unitTest/jest.config.js", // 单元测试
            "jestupdate": "jest --config ./unitTest/jest.config.js --updateSnapshot" // 单元测试快照更新
            "jestreport": "jest --config ./unitTest/jest.config.js --coverage" // 单元测试并生成覆盖率报告
        }
    }
    
    // jest.config.js
    module.exports = {
        testURL: 'http://localhost/',
        setupFiles: [],
        moduleFileExtensions: ['js', 'jsx'],
        testPathIgnorePatterns: ['/node_modules/'],
        testRegex: '.*\\.test\\.js$',
        collectCoverage: false,
        collectCoverageFrom: ['src/components/**/*.{js}'],
        moduleNameMapper: {
            '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
                '<rootDir>/mocks/fileMock.js',
            '\\.(css|less|scss)$': '<rootDir>/mocks/styleMock.js'
        }
    };
    
    
    • testURL: URL-адрес запуска jsdom, по умолчанию «about:blank», если не задано, будет ошибка при попытке доступа к localStorage.
    • setupFiles: перед запуском тестового кода Jest запустит файл конфигурации, указанный в setupFile, чтобы инициализировать тестовую среду.
    • moduleFileExtensions: расширения файлов, поддерживающие модульное тестирование.
    • testPathIgnorePatterns: соответствие правилам игнорирования файлов.
    • testRegex: соответствие правилам тестового файла.
    • collectCoverage: следует ли генерировать отчет о покрытии тестами, включение которого увеличит время тестирования.
    • collectCoverageFrom: указывает набор файлов, из которых должна быть собрана информация о покрытии. Информация о покрытии будет собираться для файла, если он соответствует указанному шаблону подстановки, даже если для этого файла не существует тестов, и он никогда не требуется в наборе тестов.
    • Модуленамемаппер: Может использоваться для отображения путей модуля к разным модулям. По умолчанию предустановка будет сопоставлять все изображения к модулю заглушки изображения, но если модуль не найден, эта опция может быть настроена.
  • фиктивный файл

    // fileMock.js
    module.exports = {};
    
    // styleMock.js
    module.exports = {};
    
  • Пишите модульные тесты

    // button.test.js
    import Button from '../../src/common/components/Button';
    import renderer from 'react-test-renderer';
    import React from 'react';
    import { shallow, configure } from 'enzyme'; // shallow(浅渲染,只渲染父组件)
    import Adapter from 'enzyme-adapter-react-16'; // 适应React-16
    configure({ adapter: new Adapter() }); // 适应React-16,初始化
    const props = {
        text: '按钮测试用例',
        type: 'white',
        style: { marginTop: 15 },
        size: 'big',
        disabled: false,
        height: 'middle',
        isLock: true,
        cname: 'hello',
        onClick: () => {}
    };
    describe('test Button', () => {
        it('button render correctly', () => {
            const tree = renderer.create(<Button {...props} />).toJSON();// 生成快照
            expect(tree).toMatchSnapshot(); // 匹配之前的快照
        });
    
        it('button has class', () => {
            const item = shallow(<Button {...props} />); //浅渲染
            expect(item.hasClass('hello')).toBe(true); // 断言有item有hello的className
        });
    });
    
    
    

постскриптум

Меры предосторожности:

1. Если testURL не настроен, будет выдано сообщение об ошибке: localStorage недоступен для непрозрачных источников

2. Этот документ описывает только план практики автора для справки. Для конкретного введения и использования шума и фермента, пожалуйста, обратитесь к