How to run unit tests with Cypress.io?

北慕城南 提交于 2021-02-11 13:23:42

问题


I have been using Cypress.io to run end-to-end tests. Recently, I have been using it to run unit tests as well. However, I have some issues with some small helper functions that I have built with NodeJs.

I have a create file called utils.spec.js in the following path <my-project-name>/cypress/integration/unit/utils.spec.js & I have written the following tests:

File: utils.spec.js

// Path to utils.js which holds the regular helper javascript functions
import { getTicketBySummary } from '../../path/to/utils';

describe('Unit Tests for utils.js methods', () => {
  /**
   * Array of objects mocking Tickets Object response
   */
  const mockedTickets = {
    data: {
      issues: [
        {
          id: 1,
          key: 'ticket-key-1',
          fields: {
            summary: 'This is ticket number 1',
          },
        },
        {
          id: 2,
          key: 'ticket-key-2',
          fields: {
            summary: 'This is ticket number 2',
          },
        },
      ],
    },
  };

  const mockedEmptyTicketsArray = [];
  it('returns an array containing a found ticket summary', () => {
    expect(
      getTicketBySummary({
        issues: mockedTickets,
        summaryTitle: 'This is ticket number 1',
      })
    ).eq(mockedTickets.data.issues[0]);
  });
  it('returns an empty array, when no ticket summary was found', () => {
    expect(
      getTicketBySummary({
        issues: mockedTickets,
        summaryTitle: 'This is ticket number 3',
      })
    ).eq(mockedEmptyTicketsArray);
  });
});

File: utils.js

const fs = require('fs');

/**
 * Method to search for an issue by its title
 * Saving the search result into an array
 *
 * @param {array} - issues - an array containing all existing issues.
 * @param {string} - summaryTitle - used to search an issue by title
 */
const getTicketBySummary = ({ issues, summaryTitle }) =>
  issues.data.issues.filter(issueData => {
    return issueData.fields.summary === summaryTitle ? issueData : null;
  });

/**
 * Method to read a file's content
 * Returns another string representing the file's content
 *
 * @param {str} - file - a passed string representing the file's path
 */
const readFileContent = file => {
  return new Promise((resolve, reject) => {
    fs.readFile(file, 'utf8', (err, data) => {
      if (err) return reject(err);
      return resolve(data);
    });
  });
};

module.exports = { getTicketBySummary, readFileContent };

However, when I run the command: npx cypress run --spec=\"cypress/integration/unit/utils.spec.js\" --env mode=terminal, I get the error:Module not found: Error: Can't resolve 'fs'.

Also if I commented out the fs import & its function I get another error:

1) An uncaught error was detected outside of a test:
     TypeError: The following error originated from your test code, not from Cypress.

  > Cannot assign to read only property 'exports' of object '#<Object>'

When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.

Cypress could not associate this error to any specific test.

We dynamically generated a new test to display this failure

I did some digging on the second error & it seems the describe method is defined. How can I fix both issues? What am I doing wrong?


回答1:


You can use tasks to execute node code. In your plugins.js create the task with the arguments you need, returning the calculated value:

  on('task', {
    // you can define and require this elsewhere
    getTicketBySummary('getTicketBySummary', { issues, summaryTitle }) {
      return issues.data.issues.filter(...);
    }
  })
}

In your test, execute the task via cy.task:

  it('returns an array containing a found ticket summary', () => {
    cy.task('getTicketBySummary', {
      issues: mockedTickets,
      summaryTitle: 'This is ticket number 1',
    }).then(result => {
      expect(result).eq(mockedTickets.data.issues[0]);
    })
  });

That being said, getTicketBySummary looks like a pure function that doesn't depend on fs. Perhaps separate helper functions that actually need node as that could avoid need cy.task. If you want to be able to import commonjs (require) via ES6 import/export you would usually need to setup build tools (babel/rollup/etc) to be able to resolve that effectively.

Hopefully that helps!



来源:https://stackoverflow.com/questions/66055150/how-to-run-unit-tests-with-cypress-io

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!