Skip to content

Testing

Tatiana edited this page Apr 2, 2021 · 6 revisions

All bot commands must be tested. For each command file you create, you will also need to create a <command>.test.js file. You will need to ensure that the regex, as well as the callback, are tested with a variety of test cases.

Each spec file will need to test for the regex and the callback using the following format:

const command = require('./command')

describe('/commandname', () => {
  describe('regex', () => {
    /* Jest requires an array of arrays (also called a table) to be passed in so we may test each string with the same case
    For more information: https://jestjs.io/docs/en/api#testeachtablename-fn-timeout */
    it.each([
      ['/string'],
      [' /string'],
      ['/string @odin-bot'],
      ['@odin-bot /string'],
    ])('correct strings trigger the callback', (string) => {
      expect(command.regex.test(string)).toBeTruthy()
    })
    
    it.each([
     /* Incorrect variations of the string such as typos, misspellings, similar words, etc */
      ['/strng'],
      ['/strong'],
      ['/strings],
      ['string'],
    ])("'%s' does not trigger the callback", (string) => {
      expect(command.regex.test(string)).toBeFalsy()
    })

    // We also want to check to see if commands can be called from anywhere in a message
    it.each([
      ['Check this out! /string'],
      ['Don\'t worry about /string'],
      ['Hey @odin-bot, /string'],
      ['/@odin-bot ^ /me /time /string$*']
    ])("'%s' - command can be anywhere in the string", (string) => {
      expect(command.regex.test(string)).toBeTruthy()
    })
    
    // Commands should not trigger unless they are their own distinct phrase or word
    it.each([
      ['@user/string'],
      ['it\'s about/string'],
      ['/stringsanillusion'],
      ['/string/'],
      ['/string*'],
      ['/string...']
    ])("'%s' - command should be its own word/group - no leading or trailing characters", (string) => {
      expect(command.regex.test(string)).toBeFalsy()
    })
  })
  
  // This generates a snapshot test - https://jestjs.io/docs/snapshot-testing#:~:text=Snapshot%20tests%20are%20a%20very,file%20stored%20alongside%20the%20test

  describe('callback', () => {
    it('returns correct output', () => {
      expect(command.cb()).toMatchSnapshot()
      // If your command behaves differently based on mentions being passed in, import generateMentions from mockData.js and pass it in as an argument with your desired number of mentions
     // NOTE: This "it" block MUST use an async callback for these snapshots to be generated properly
      expect(await command.cb(generateMentions(0))).toMatchSnapshot();
      expect(await command.cb(generateMentions(1))).toMatchSnapshot();
      expect(await command.cb(generateMentions(2))).toMatchSnapshot();
      expect(await command.cb(generateMentions(3))).toMatchSnapshot();
  })
})

Once you have filled out your test suite, make sure you have saved <command>.js, then run npm test <command>.test.js to ensure all tests for your command pass and a snapshot is generated in the __snapshots__ directory. If your command produces a different output based on number of mentions, or other variable factors in a message, such as the user calling the command, server roles, etc, you must create snapshots for each of these scenarios. Once you have confirmed that your snapshot file matches the correct output, you may submit a pull request for review. Your tests must pass in order for your pull request to be merged.

NOTE: If your changes alters the output of a command, you can run npm test -- -u to update the corresponding snapshot. You must verify that your snapshots match the expected output.

Clone this wiki locally