当前位置: 首页 > news >正文

如何在Visual Studio Code中用Mocha对TypeScript进行测试

目录

使用TypeScript编写测试用例

在Visual Studio Code中使用调试器在线调试代码


首先,本文不是一篇介绍有关TypeScript、JavaScript或其它编程语言数据结构和算法的文章。如果你正在准备一场面试,或者学习某一个课程,互联网上可以找到许多相关的资源,我个人比较推崇hackerrank.com。

  本文的主要目的在于帮助你了解并熟知以下两点:

  1. 如何用TypeScript编写并运行测试用例?
  2. 如何在Visual Studio Code中使用调试器在线调试代码,并发现代码中的bug?

使用TypeScript编写测试用例

  在我的电脑中,我创建了一个目录ts-algorithms,在终端上运行下面的命令:

mkdir ts-algorithms
cd ts-algorithms
npm init -y

  这将创建一个最简单的项目结构,其中包含一个package.json文件,你可以根据自己的需要随意修改其中的内容,通常我会加入license、作者、描述和关键字等信息。

  接下来,我们编写一些代码,将其放在src目录中,和测试相关的代码则放在test目录中。手动创建这两个目录,然后用TypeScript编写一个模块。例如,下面是我编写的src/Stack.ts文件的代码:

/*** Implementation of a classic stack.*/
export class Stack<T> {// Internal storage for the stackprivate _items: T[] = [];/*** Creates a pre-populated stack.** @param {T[]} initialData the initial contents of the stack*/constructor(initialData: Array<T> = []) {this._items.push(...initialData)}/*** Adds an item to the top of the stack.** @param {T} item the item to be added to the stack*/push(item: T): void {this._items.push(item);}/*** Removes an item from the top of the stack, returning it.** @returns {T} the item at the top of the stack.*/pop(): T {return this._items.pop();}/*** Take a peek at the top of the stack, returning the top-most item,* without removing it.** @returns {T} the item at the top of the stack.*/peek(): T {if (this.isEmpty())return undefined;elsereturn this._items[this._items.length - 1];}/*** @returns {boolean} true if the stack is empty.*/isEmpty(): boolean {return this._items.length === 0;}/*** @returns {number} the number of items in the stack.*/size(): number {return this._items.length;}
}

   同时我还在src目录下添加了index.ts文件,用来导出所有的模块。目前只有简单的一行代码:

export { Stack } from './Stack';

  为了进行单元测试,我使用了mocha和chai这两个包,我们通过下面的命令将它们安装到项目里:

npm install --save-dev mocha chai

  由于mocha不会自动运行TypeScript代码,所以我们还需要用到ts-node

npm install --save-dev ts-node typescript

  另外,如果能让Visual Studio Code编辑器理解mochachai的类型并为其提供智能感知功能那就太好了,所以我们加上下面这两个包:

npm install --save-dev @types/chai @types/mocha

  然后,我们在package.json中加入一个script的入口,这样我们就可以通过一个命令行来运行我们的测试程序:

"scripts": {"tests": "mocha --require ts-node/register test/**/*.ts"
},

  注意这里的--require ts-node/register很重要,它将TypeScript注册为解释器,这样我们就可以用TypeScript编写测试用例了。

  让我们创建文件test/stack.ts,编写测试用例以对src/Stack.ts进行测试:

import { expect } from 'chai';
import { Stack } from '../src';describe('Stack', () => {it('can be initialized without an initializer', () => {const s = new Stack<number>();expect(s.size()).to.equal(0);});it('can be initialized with an initializer', () => {const s = new Stack<number>([ 1, 2, 3, 4 ]);expect(s.size()).to.equal(4);});it('can be pushed upon', () => {const s = new Stack<number>([ 1, 2, 3, 4 ]);s.push(5);expect(s.size()).to.equal(5);expect(s.peek()).to.equal(5);});it('can be popped', () => {const s = new Stack<number>([ 1, 2, 3, 4 ]);expect(s.pop()).to.equal(4);expect(s.size()).to.equal(3);});it('can be peeked', () => {const s = new Stack<number>([ 1, 2, 3, 4 ]);expect(s.peek()).to.equal(4);expect(s.size()).to.equal(4);});it('isEmpty() returns true when empty', () => {const s = new Stack<number>();expect(s.isEmpty()).to.be.true;});it('isEmpty() is false when not empty', () => {const s = new Stack<number>([1, 2, 3, 41]);expect(s.isEmpty()).to.be.false;});it('cannot pop when no elements', () => {const s = new Stack<number>();expect(s.pop()).to.be.undefined;});it('cannot peek when empty', () => {const s = new Stack<number>();expect(s.peek()).to.be.undefined;});
});

  为了确保TypeScript在编译时通过类型检查,我们还需要在项目的根目录下添加tsconfig.json文件,并将mocha添加到types配置节点中:

{"compilerOptions": {"types": ["mocha"]}
}

  否则,直接运行测试,你可能会遇到下面这样的错误:

TSError: ⨯ Unable to compile TypeScript:
test/stack.ts:4:1 - error TS2593: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha` and then add 'jest' or 'mocha' to the types field in your tsconfig.

  所有工作准备就绪后,我们通过下面的命令直接运行测试:

npm run tests

  你也可以在Visual Studio Code的集成终端窗口中运行上面的命令(View > Terminal)。如果一切正常,你应该会得到如下图所示的结果(所有9个测试用例都检测成功):

   注意这里所有的代码,包括测试用例,都是用TypeScript编写的。此外,借助于Visual Studio Code编辑器,你还可以在编译时进行类型检查,泛型类型审查以及获得对JavaScript所进行的一系列其它增强。

在Visual Studio Code中使用调试器在线调试代码

  我们不仅仅只能运行测试,我们还可以做得更好。如果我们的测试用例在运行中遇到问题怎么办?例如,让我们在src/Stack.ts文件中加入一行代码,使isEmpty()方法始终报错:

isEmpty(): boolean {throw new Error("Something went wrong");return this._items.length === 0;
}

  重新运行测试,首先失败的就是第三个测试用例——"can be pushed upon"。我很想知道它为什么会失败!在Visual Studio Code中打开Run and Debug

   然后左侧的窗口变成下面这样:

   在进行调试之前,我需要告诉Visual Studio Code如何在调试器中运行测试,点击Run and Debug按钮下方的create a launch.json file链接,然后在弹出的下拉列表中选择Node.js环境。这将在.vscode目录中创建一个launch.json配置文件,其中包含了一个默认的启动配置项,我们将该配置项删除,然后点击界面右下角的Add Configuration按钮,在弹出的列表中选择{} Node.js: Mocha Tests,这是运行mocha测试的基本配置项。不过,这里我们需要给mocha添加一些命令行参数,正如我们在package.json文件的script中向mocha添加的参数一样。

{// Use IntelliSense to learn about possible attributes.// Hover to view descriptions of existing attributes.// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387"version": "0.2.0","configurations": [{"args": ["--require", "ts-node/register","-u","bdd","--timeout","999999","--colors","${workspaceFolder}/test/**/*.ts"],"internalConsoleOptions": "openOnSessionStart","name": "Mocha Tests","program": "${workspaceFolder}/node_modules/mocha/bin/_mocha","request": "launch","type": "pwa-node"}]
}

  注意这里的args配置项,它包含了一些非常重要的配置,其中之一就是我们在package.json文件的script中向mocha添加的命令行参数"--require"和"ts-node/register"。另外就是"${WorkspaceFolder}/test/**/*.ts"用来指定测试文件所在的目录。还有一个就是我们将默认生成的配置项"tdd"改成"bdd"以确保mocha在Visual Studio Code的debugger模式下能正确运行。

  现在,我们可以在测试代码中打断点:

   然后,在Visual Studio Code的Run and Debug窗口中点击绿色的运行按钮:

   一旦断点被命中,程序会暂停,然后你可以逐步跟踪代码执行:

   该控制条会显示在屏幕的顶部,从左到右依次是:

  • 继续执行,直到下一个断点。
  • 执行到下一个语句。
  • 进入下一个语句内部。
  • 跳出当前语句。
  • 重新运行。
  • 停止运行。

  同时,Visual Studio Code的左侧也有一些和调试相关的窗口,其中包含当前程序运行的变量的信息(通常会非常有用)、被监视的变量的值、调用堆栈以及断点的位置信息等等。

  我们可以试着来调试一下。前两个测试用例已经成功运行了,我们创建了stack类并且测试了它的size。在接下来的测试中我想要测试push()peek()这两个方法。我们执行下面的操作:

  • 跳过stack类的创建。
  • 进入到push()方法内部。
  • 在push()方法内部跳过stack数组的push()调用。

  光标现在出现在push()方法的末尾,现在我可以查看一下变量的值——特别是this._items变量的值,因为它表示的是stack类中items的数量。目前一切看起来都很正常,让我们继续:

  • 跳过push()方法的返回。
  • 然后我们可以直接跳过对size()方法的测试语句,因为前面的测试用例已经测试过了。
  • 进入到peek()方法内部。
  • 进入到this.isEmpty()方法内部。
  • 然后我们看到程序抛出一个异常。

   如果想要暂时隐藏断点使其在程序运行时不被命中,可以在左侧的breakpoints窗口中点击Toggle Activate Breakpoints。再次点击时可以激活所有已添加的断点。

  你可以通过Visual Studio Code提供的这种在线调试工具来一步步跟踪执行我们的代码,从而分析每个步骤中各个变量的值,看看它们是否和你预期的一致。你熟知你的算法,在编码之前可以先在纸上将整个执行过程画一遍,然后看看最终程序运行时是否偏离了你的预期?

  另外需要注意的是,在调试过程中,我们看到的是TypeScript代码,而不是编译之后的JavaScript代码。

  现在我们可以使用Visual Studio Code来编写更多丰富的功能强大的TypeScript代码。


 以下是我收集到的比较好的学习教程资源,虽然不是什么很值钱的东西,如果你刚好需要,可以评论区,留言【777】直接拿走就好了

各位想获取资料的朋友请点赞 + 评论 + 收藏,三连!

三连之后我会在评论区挨个私信发给你们~

相关文章:

如何在Visual Studio Code中用Mocha对TypeScript进行测试

目录 使用TypeScript编写测试用例 在Visual Studio Code中使用调试器在线调试代码 首先&#xff0c;本文不是一篇介绍有关TypeScript、JavaScript或其它编程语言数据结构和算法的文章。如果你正在准备一场面试&#xff0c;或者学习某一个课程&#xff0c;互联网上可以找到许多…...

GO中Json的解析

一个json字串&#xff0c;想要拿到其中的数据&#xff0c;就需要解析出来 一、适用于json数据的结构已知的情况下 使用json.Unmarshal将json数据解析到结构体中 根据json字串数据的格式定义struct&#xff0c;用来保存解码后的值。这里首先定义了一个与要解析的数据结构一样的…...

chatgpt 提示词-关于数据科学的 75个词语

这里有 75 个 chatgpt 提示&#xff0c;可以立即将其用于数据科学或数据分析等。 1. 伪装成一个SQL终端 提示&#xff1a;假设您是示例数据库前的 SQL 终端。该数据库包含名为“用户”、“项目”、“订单”、“评级”的表。我将输入查询&#xff0c;您将用终端显示的内容进行…...

(自控原理)控制系统的数学模型

目录 一、时域数学模型 1、线性元件微分方程的建立 2、微分方程的求解方法​编辑 3、非线性微分方程的线性化 二、复域数学模型 1、传递函数的定义 2、传递函数的标准形式 3、系统的典型环节的传递函数 4、传递函数的性质 5、控制系统数学模型的建立 6、由传递函数求…...

Webpack5 cacheGroups

文章目录 一、 cacheGroups是什么&#xff1f;二、怎么使用cacheGroups&#xff1f;三、cacheGroups实际应用之一&#xff1f; 一、 cacheGroups是什么&#xff1f; 在Webpack 5中&#xff0c;cacheGroups是用于配置代码拆分的规则&#xff0c;它可以帮助你更细粒度地控制生成…...

前端面试的游览器部分(5)每篇10题

41.什么是浏览器的同步和异步加载脚本的区别&#xff1f;你更倾向于使用哪种方式&#xff0c;并解释原因。 浏览器的同步和异步加载脚本是两种不同的脚本加载方式&#xff0c;它们的主要区别在于加载脚本时是否阻塞页面的解析和渲染。 同步加载脚本&#xff1a; 同步加载脚本…...

数据挖掘七种常用的方法汇总

数据挖掘(Data Mining)就是从大量的、不完全的、有噪声的、模糊的、随机的实际应用数据中&#xff0c;提取隐含在其中的、人们事先不知道的、但又是潜在有用的信息和知识的过程。这个定义包括几层含义&#xff1a;数据源必须是真实的、大量的、含噪声的&#xff1b;发现的是用户…...

自然语言处理学习笔记(二)————语料库与开源工具

目录 1.语料库 2.语料库建设 &#xff08;1&#xff09;规范制定 &#xff08;2&#xff09;人员培训 &#xff08;3&#xff09;人工标注 3.中文处理中的常见语料库 &#xff08;1&#xff09;中文分词语料库 &#xff08;2&#xff09;词性标注语料库 &#xff08;3…...

Rust dyn - 动态分发 trait 对象

dyn - 动态分发 trait 对象 dyn是关键字&#xff0c;用于指示一个类型是动态分发&#xff08;dynamic dispatch&#xff09;&#xff0c;也就是说&#xff0c;它是通过trait object实现的。这意味着这个类型在编译期间不确定&#xff0c;只有在运行时才能确定。 practice tr…...

uniapp 中过滤获得数组中某个对象里id:1的数据

// 假设studentData是包含多个学生信息的数组 const studentData [{id: 1, name: 小明, age: 18},{id: 2, name: 小红, age: 20},{id: 3, name: 小刚, age: 19},{id: 4, name: 小李, age: 22}, ]; // 过滤获取id为1的学生信息 const result studentData.filter(item > ite…...

Django系列之Channels

1. Channels 介绍 Django 中的 HTTP 请求是建立在请求和响应的简单概念之上的。浏览器发出请求&#xff0c;Django服务调用相应的视图函数&#xff0c;并返回响应内容给浏览器渲染。但是没有办法做到 服务器主动推送消息给浏览器。 因此&#xff0c;WebSocket 就应运而生了。…...

HTTP——五、与HTTP协作的Web服务器

HTTP 一、用单台虚拟主机实现多个域名二、通信数据转发程序 &#xff1a;代理、网关、隧道1、代理2、网关3、隧道 三、保存资源的缓存1、缓存的有效期限2、客户端的缓存 一台 Web 服务器可搭建多个独立域名的 Web 网站&#xff0c;也可作为通信路径上的中转服务器提升传输效率。…...

pyspark笔记 Timestamp 类型的比较

最近写pyspark遇到的一个小问题。 假设我们有一个pyspark DataFrame叫做dart 首先将dart里面timestamp这一列转化成Timestamp类型 dartdart.withColumn(timestamp,col(timestamp).cast(TimestampType()))查看timestamp的前5个元素 dart.select(timestamp).show(5,truncateFal…...

SpringBoot 集成 Redis

本地Java连接Redis常见问题&#xff1a; bind配置请注释掉保护模式设置为noLinux系统的防火墙设置redis服务器的IP地址和密码是否正确忘记写访问redis的服务端口号和auth密码 集成Jedis jedis是什么 Jedis Client是Redis官网推荐的一个面向java客户端&#xff0c;库文件实现…...

黑客学习笔记(网络安全)

一、首先&#xff0c;什么是黑客&#xff1f; 黑客泛指IT技术主攻渗透窃取攻击技术的电脑高手&#xff0c;现阶段黑客所需要掌握的远远不止这些。 以前是完全涉及黑灰产业的反派角色&#xff0c;现在大体指精通各种网络技术的程序人员 二、为什么要学习黑客技术&#xff1f;…...

[openCV]基于拟合中线的智能车巡线方案V1

import cv2 as cv import os import numpy as np# 遍历文件夹函数 def getFileList(dir, Filelist, extNone):"""获取文件夹及其子文件夹中文件列表输入 dir&#xff1a;文件夹根目录输入 ext: 扩展名返回&#xff1a; 文件路径列表"""newDir d…...

MyBatis-Plus 和达梦数据库实现高效数据持久化

一、添加依赖 首先&#xff0c;我们需要在项目的 pom.xml 文件中添加 MyBatis-Plus 和达梦数据库的依赖&#xff1a; <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifac…...

已注销【888】

元神密码 - 飞书云文档 (feishu.cn)...

Ceph错误汇总

title: “Ceph错误汇总” date: “2020-05-14” categories: - “技术” tags: - “Ceph” - “错误汇总” toc: false original: true draft: true Ceph错误汇总 1、执行ceph-deploy报错 1.1、错误信息 ➜ ceph-deploy Traceback (most recent call last):File "/us…...

DataTable过滤某些数据

要过滤DataTable中的某些数据&#xff0c;可以使用以下方法&#xff1a; 使用Select方法&#xff1a;可以使用DataTable的Select方法来筛选满足指定条件的数据行。该方法接受一个字符串参数作为过滤条件&#xff0c;返回一个符合条件的数据行数组。 DataTable filteredTable …...

JAVASE---继承和多态

继承 比如&#xff0c;狗和猫&#xff0c;它们都是一个动物&#xff0c;有共同的特征&#xff0c;我们就可以把这种特征抽取出来。 像这样把相同的可以重新放到一个类里面&#xff0c;进行调用&#xff0c;这就是继承。 概念 继承(inheritance)机制&#xff1a;是面向对象程…...

Centos7升级gcc、g++版本(转载)

Centos7默认的 gcc版本是 4.8.5 默认使用yum install gcc安装出来的gcc版本也是是4.8.5。 1.首先查看自己的 gcc 版本 gcc -v g -v如果出现&#xff1a;bash: g: 未找到命令... 则安装g&#xff1a;遇到暂停时&#xff0c;输入y继续安装 yum install gcc-c然后输入&#xf…...

第一章:继承

系列文章目录 文章目录 系列文章目录前言继承的概念及定义继承的概念继承定义定义格式继承关系和访问限定符继承基类成员访问方式的变化 基类和派生类对象赋值转换&#xff08;公有继承&#xff09;继承中的作用域派生类的默认成员函数继承与友元继承与静态成员不能被继承的类复…...

git面试题

文章目录 git经常用哪些指令git出现代码冲突怎么解决你们团队是怎么管理git分支的如何实现Git的免密操作 git经常用哪些指令 产生代码库 新建一个git代码库 git init下载远程项目和它的整个代码历史 git clone 远程仓库地址配置 显示配置 git config --list [--global]编辑配置…...

Github Copilot在JetBrains软件中登录Github失败的解决方案

背景 我在成功通过了Github Copilot的学生认证之后&#xff0c;在VS Code和PyCharm中安装了Github Copilot插件&#xff0c;但在PyCharm中插件出现了问题&#xff0c;在登录Github时会一直Retrieving Github Device Code&#xff0c;最终登录失败。 我尝试了网上修改DNS&…...

使用 github 同步谷歌浏览器书签

想必使用谷歌浏览器Chrome的用户一定非常头疼的一件事就是&#xff1a;账户不能登录&#xff0c;书签收藏夹不能同步&#xff0c;换一台电脑书签收藏夹没有了&#xff01; 下面教大家一招亲测有效适用的方法解决书签同步问题&#xff0c;在任何电脑都可以同步了 1、去下载谷歌…...

Eclipse进行debug

目录 基本步骤三种执行方式 -- 键盘快捷键variables面板移除debug过的项目通过eclipse调用具有软件界面的项目进行debug各个variable颜色具有的意义 基本步骤 点击eclipse右上角debug按钮 调出debug面板 点击小蜘蛛图标&#xff08;不是点绿色三角的Run&#xff09; 此时会进…...

13-5_Qt 5.9 C++开发指南_基于信号量的线程同步_Semaphore

文章目录 1. 信号量的原理2. 双缓冲区数据采集和读取线程类设计3. QThreadDAQ和QThreadShow 的使用4. 源码4.1 可视化UI设计框架4.2 qmythread.h4.3 qmythread.cpp4.4 dialog.h4.5 dialog.cpp 1. 信号量的原理 信号量(Semaphore)是另一种限制对共享资源进行访问的线程同步机制…...

golang使用泛型实现mapreduce操作

1.使用面向对象的方式写 package streamimport ("fmt""log""reflect""sort""strconv""strings" )type Stream[T any] struct {data []TkeyBy stringsortByNum stringsortByStr []string }func FromElem…...

2023华数杯数学建模C题思路分析 - 母亲身心健康对婴儿成长的影响

# 1 赛题 C 题 母亲身心健康对婴儿成长的影响 母亲是婴儿生命中最重要的人之一&#xff0c;她不仅为婴儿提供营养物质和身体保护&#xff0c; 还为婴儿提供情感支持和安全感。母亲心理健康状态的不良状况&#xff0c;如抑郁、焦虑、 压力等&#xff0c;可能会对婴儿的认知、情…...