通过一个typescript的小游戏,使用单元测试实战(二)

题目:

复制代码
该游戏是一个猜数字的游戏,
玩家输入4位0-9 不重复的数字,和电脑生成4位 0-9不重复的数字进行一个比较
如果位置和大小都正确, 计入A
如果数字正确,位置不正确, 计入B
返回 1A1B

环境准备:

typescript 复制代码
- npm init -y
- npm install typescript
- npx tsc --init

- npm i  readline-sync    ----一个通过终端输入数字的工具包
- npm i --save-dev @types/node

## 使用 jest 测试
- npm install --save-dev jest
- npx create-jest    生成jest配置文件
- npm i --save-dev @types/jest
- npm i ts-jest -D
-修改jest配置文件 preset: "ts-jest",

1.utils函数准备

(1)生成一个min-max范围内的随机整数

javascript 复制代码
function getRandomInRange(min: number, max: number): number {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

为了测试各种情况,我们优化一下函数

javascript 复制代码
function getRandomInRange(min: number, max: number): number {
  if(typeof min !== "number" || typeof max !== "number") {
    throw new Error("min and max should be numbers");
  }
  if(min > max) {
    throw new Error("min should not be greater than max");
  }
  if(min === max) {
    return min;
  }
  if(!Number.isInteger(min) || !Number.isInteger(max)) {
    throw new Error("min and max should be integers");
  }
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

(2)判断数组内是否有重复的数

javascript 复制代码
function isRepeat(arr: number[] = []): boolean {
  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i] === arr[j]) {
        return true;
      }
    }
  }
  return false;
}

随机生成4个不重复的数 组成一个数组

javascript 复制代码
function getComNum(): number[] {
  let num: number = 0;
  let comNum: number[] = [];
  while (true) {
    comNum = [];
    for (let i = 0; i < 4; i++) {
      num = getRandomInRange(0, 9);
      comNum.push(num);
    }

    if (!isRepeat(comNum)) {
      return comNum;
    }
  }
}

2.主要功能

typescript 复制代码
const readline = require("readline-sync");
const { getComNum, isRepeat } = require("./utils/tools");

function main(): void {
  // guessNum 用户输入的数字
  let guessNum: string;
  let a: number = 0; //A的个数
  let b: number = 0; //B的个数
  let change: number = 10; //猜测的机会

  const comNum: number[] = getComNum(); //电脑生成的   4位不重复的数字

  while (change) {
    console.log("请输入你要猜测的数字");
    guessNum = readline.question("");
    if (guessNum.length !== 4) {
      console.log("长度必须为4");
    } else if (isNaN(Number(guessNum))) {
      console.log("输入的数字有问题");
    } else {
      //符合要求,进行一个判断
      let guessNum2: string[] = [...guessNum];
      if (!isRepeat(guessNum2)) {
        //玩家输入的数字合格
        //开始对比电脑的数字  跟玩家输入的数字
        for (let i = 0; i < comNum.length; i++) {
          for (let j = 0; j < guessNum2.length; j++) {
            if (comNum[i]?.toString() === guessNum2[j]) {
              if (i === j) {
                a++;
              } else {
                b++;
              }
            }
          }
        }

        if (a === 4) {
          // 说明玩家全部猜对了,跳出循环
          break;
        } else {
          console.log(`${a}A${b}B`);
          change--;

          if (change !== 0) {
            //鼓励语句
            const arr: string[] = [
              "加油!",
              "还差一点了!",
              "你马上就猜中了!",
              "很简单的,再想想!",
              "也许你需要冷静一下",
            ];
            let index = Math.floor(Math.random() * arr.length);
            console.log(`你还剩下${change}次机会,${arr[index]}`);
          }
          a = b = 0; //每次比对完成后,清空a和b的值
        }
      } else {
        console.log("你输入的数字重复了,请重新输入!");
      }
    }
  }

  //如果跳出了上面的while。说明游戏结束了
  if (change === 0) {
    console.log("很遗憾,你已经没有机会了!");
    console.log(`电脑生成的随机数为${comNum}`);
  } else {
    console.log("恭喜你,猜测正确,游戏结束");
    console.log("Tank you for playing");
  }
}
main();

3.效果展示

4.测试

创建__test__文件夹

(1)测试随机生成min-max整数的函数

  • getRandomInRange.test.ts
javascript 复制代码
const { getRandomInRange } = require('../tools');

describe('生成一个min - max范围内的随机整数', () => {
    test('返回指定范围内的数字', () => {
        const min = 5;
        const max = 15;
        const randomValue = getRandomInRange(min, max);
        expect(randomValue).toBeGreaterThanOrEqual(min);
        expect(randomValue).toBeLessThanOrEqual(max);
    });

    test('当min/max为负数时', () => {
        const min = -10;
        const max = -5;
        const randomValue = getRandomInRange(min, max);
        expect(randomValue).toBeGreaterThanOrEqual(min);
        expect(randomValue).toBeLessThanOrEqual(max);
    });

    test('当min大于max时抛出错误', () => {
        const min = 15;
        const max = 5;
        expect(() => getRandomInRange(min, max)).toThrow('min should not be greater than max');
    });

    test('当min或max不是数字时抛出错误', () => {
        expect(() => getRandomInRange('a', 10)).toThrow('min and max should be numbers');
        expect(() => getRandomInRange(5, 'b')).toThrow('min and max should be numbers');
    });
});

(2)测试一个数组内部是否有重复

  • isRepeat.test.ts
javascript 复制代码
const { isRepeat } = require("../utils/tools");

test("参数为string类型数组", () => {
  expect(isRepeat(["1", "1", "2", "3"])).toBe(true);
  expect(isRepeat(["1", "4", "2", "3"])).toBe(false);
});

test("参数为number类型数组", () => {
  expect(isRepeat([1, 1, 2, 3])).toBe(true);
  expect(isRepeat([1, 4, 5, 6])).toBe(false);
});

export {};

(3)测试随机生成的四位数字

-创建randomNum.test.ts

javascript 复制代码
const { getRandomInRange } = require("../utils/tools");

test("测试随机数", () => {
  // 得到一个 4 位数的数组
  const result = getRandomInRange();
  expect(result.length).toBe(4);
  expect(new Set(result).size).toBe(4);
  result.forEach((num: number) => {
    expect(num).toBeGreaterThanOrEqual(0);
    expect(num).toBeLessThanOrEqual(9);
  });
});

export {};

然后: npm run test
运行测试结果

找到10-11,13-14

修改增加:

javascript 复制代码
    test('当min和max相等时,返回min', () => {
        const min = 5;
        const max = 5;
        const randomValue = getRandomInRange(min, max);
        expect(randomValue).toBe(min);
    });
    test('当min和max不是整数时,抛出错误', () => {
        const min = 5.5;
        const max = 15.5;
        expect(() => getRandomInRange(min, max)).toThrow('min and max should be integers');
    });

重新运行:

以上就是此次实战示例的测试过程,

注意:

实战总结:

(1)使用到的jest匹配器:

// 大于

expect(value1).toBeGreaterThan(3);

// 大于等于

expect(value1).toBeGreaterThanOrEqual(4);

// 小于

expect(value1).toBeLessThan(5);

// 小于等于

expect(value1).toBeLessThanOrEqual(4);

toThrow 测试某个函数,调用之后是否会抛出异常

(2)在 node 环境中,如果模块化使用的是 commonjs 规范,导入的时候会提示报错"无法重新声明块范围变量"。

要解决这个问题,首先在 ts 配置文件中,将 esModuleInterrop 开启为 true,该配置项用于控制是否启用 ES 模块规范的兼容性处理。

接下来在 tools.ts 文件的最后一行添加 export { } ,这一行代码会让 ts 认为这是一个 ESModule,从而不存在变量重复声明的问题。

相关推荐
古一|5 小时前
vue3都有哪些升级相比vue2-核心响应式系统重构
javascript·vue.js·重构
HHHHHY5 小时前
http接口响应头类型不对,导致svg图片无法预览,前端解决方案
前端·javascript
啊森要自信5 小时前
【GUI自动化测试】Python 自动化测试框架 pytest 全面指南:基础语法、核心特性(参数化 / Fixture)及项目实操
开发语言·python·ui·单元测试·pytest
元亓亓亓5 小时前
考研408--组成原理--day1
开发语言·javascript·考研·计组
Mintopia6 小时前
🌌 知识图谱与 AIGC 融合:
前端·javascript·aigc
秋子aria6 小时前
作用域详解 立即执行函数详解
javascript
fox_6 小时前
写多参数函数总重复传值?用柯里化3步搞定参数复用与延迟执行
javascript
我叫黑大帅6 小时前
面对组件的不听话,我还是用了它…………
前端·javascript·vue.js
尔嵘6 小时前
vue2+elementUi实现自定义表格框选复制粘贴
前端·javascript·elementui