## 9.测验和练习入门
> 原文: [http://exploringjs.com/impatient-js/ch_quizzes-exercises.html](http://exploringjs.com/impatient-js/ch_quizzes-exercises.html)
>
> 贡献者:[so-hard](https://github.com/so-hard)
在大多数章节中,都有测验和练习。它们是付费功能,但可以进行全面预览。本章介绍如何开始使用它们。
### 9.1 测验
安装:
* 下载并解压缩`impatient-js-quiz.zip`
运行测验应用程序:
* 在 Web 浏览器中打开`impatient-js-quiz/index.html`
* 你会看到所有测验的 TOC。
### 9.2 练习
#### 9.2.1 获取练习
获取练习步骤如下:
* 下载并解压缩`impatient-js-code.zip`
* 按照`README.md`中的说明进行操作
#### 9.2.2 运行练习
* 练习在本书中的路径。
* 例如:`exercises/quizzes-exercises/first_module_test.js`
* 每个文件的内容:
* 第一行包含运行练习的命令。
* 接下来的几行描述了你要做的事情。
### 9.3 JavaScript 中的单元测试
本书中的所有练习都是通过测试[ava](https://github.com/avajs/ava)框架 运行的测试。本节简要介绍。
#### 9.3.1 典型的测试
典型的测试代码分为两部分:
* 第 1 部分:被测试的代码。
* 第 2 部分:测试代码
举例来说,以下两个文件:
* `id.js`(待测代码)
* `id_test.js`(测试)
##### 9.3.1.1 第 1 部分:被测试的代码
代码本身驻留在`id.js`中:
```js
export function id(x) {
return x;
}
```
划重点:必须暴露出要要测试的代码。否则,测试代码无法访问它。
##### 9.3.1.2 第 2 部分:测试
![](https://img.kancloud.cn/83/6f/836f0345de4fda5b9b81d7038ebb276d.svg) **不要担心测试的确切细节**
您无需担心测试的确切细节:它们始终为您实施。因此,您只需要阅读它们,但不要写它们。
代码测试位于`demos/quizzes-exercises/id_test.js`:
```js
import test from 'ava'; // (A)
import {strict as assert} from 'assert'; // (B)
import {id} from './id.mjs'; // (C)
test('My test', t => { // (D)
assert.equal(id('abc'), 'abc'); // (E)
});
```
该测试文件的核心是 E 行 - [断言](ch_assertion-api.html):`assert.equal()`指定`id('abc')`的预期结果是`'abc'`。
至于其他线路:
* A 行:导入测试框架。
* B 行:导入断言库,AVA
* C 行:导入我们要测试的功能
* D 行:通过调用函数`test()`来创建一个测试:
* 第一个参数:该测试的名字。
* 第二个参数:参数为t的箭头函数,参数t给我们提供了AVA的api(assertions 等等)
运行测试,我们在命令行中执行以下命令:
```js
npm t demos/quizzes-exercises/id_test.js
```
`t`是`test`的缩写。也就是说,这个命令的长版本是:
```js
npm test demos/quizzes-exercises/id_test.js
```
![](https://img.kancloud.cn/3e/d5/3ed5755d562179ae6c199264f5e21157.svg) **练习:你的第一次练习**
测试的初体验:
* `exercises/quizzes-exercises/first_module_test.js`
#### 9.3.2 AVA中的异步测试
![](https://img.kancloud.cn/83/6f/836f0345de4fda5b9b81d7038ebb276d.svg) **阅读**
您可以推迟阅读本节,直到您进入异步编程的章节。
为异步代码编写测试需要额外的工作:当测试返回时,他会后会收到它的结果,并向 AVA 发出信号,表示它还没有完成。以下小节将分析三种异步方法。
##### 9.3.2.1 回调异步
如果我们用`test.cd()`来替代`test()`,AVA会切换到基于回调的异步。当我们的回调函数结束后,必须用调用`t.end()`
```js
test.cb('divideCallback', t => {
divideCallback(8, 4, (error, result) => {
if (error) {
t.end(error);
} else {
assert.strictEqual(result, 2);
t.end();
}
});
});
```
##### 9.3.2.2 Promise异步
如果在测试里返回一个Proise,AVA 将其切换到基于`Promise`的异步。如果Promise状态为`fulfilled`则认为测试成功,如果`Promise`的状态为`rejected`则认为测试失败。
```js
test('dividePromise 1', t => {
return dividePromise(8, 4)
.then(result => {
assert.strictEqual(result, 2);
});
});
```
##### 9.3.2.3 异步函数作为测试“主体”
异步函数总是返回`Promises`。因此,异步函数是实现异步测试的便捷方式。以下代码与前面的示例等效。
```js
test('dividePromise', async () => {
const result = await dividePromise(8, 4);
assert.strictEqual(result, 2);
// No explicit return necessary!
});
```
你不需要显式返回任何内容:隐式返回的undefined则说明异步函数返回的`Promise`的状态为fulfiled。如果测试代码抛出异常,则`Promise`状态为rejected。
- I.背景
- 1.关于本书(ES2019 版)
- 2.常见问题:本书
- 3. JavaScript 的历史和演变
- 4.常见问题:JavaScript
- II.第一步
- 5.概览
- 6.语法
- 7.在控制台上打印信息(console.*)
- 8.断言 API
- 9.测验和练习入门
- III.变量和值
- 10.变量和赋值
- 11.值
- 12.运算符
- IV.原始值
- 13.非值undefined和null
- 14.布尔值
- 15.数字
- 16. Math
- 17. Unicode - 简要介绍(高级)
- 18.字符串
- 19.使用模板字面值和标记模板
- 20.符号
- V.控制流和数据流
- 21.控制流语句
- 22.异常处理
- 23.可调用值
- VI.模块化
- 24.模块
- 25.单个对象
- 26.原型链和类
- 七.集合
- 27.同步迭代
- 28.数组(Array)
- 29.类型化数组:处理二进制数据(高级)
- 30.映射(Map)
- 31. WeakMaps(WeakMap)
- 32.集(Set)
- 33. WeakSets(WeakSet)
- 34.解构
- 35.同步生成器(高级)
- 八.异步
- 36. JavaScript 中的异步编程
- 37.异步编程的 Promise
- 38.异步函数
- IX.更多标准库
- 39.正则表达式(RegExp)
- 40.日期(Date)
- 41.创建和解析 JSON(JSON)
- 42.其余章节在哪里?