测试是每个开发人员应具备的一项重要技能。 但是,有些人不愿意这样做。
我们每个人都遇到了一个开发人员,该开发人员声称测试是无用的,需要太多的精力,而实际上他的代码是如此出色,以至于不需要测试。 不要相信。 测试至关重要。

测试可以使您的代码更稳定,并减少错误数量。 在您看来,事实并非如此,因为您了解代码的每一点。 毕竟,您编写了它,为什么还要进行测试?
假设您正在创建一个天气应用程序。 您编写了几天或几周的代码,因此您知道了往返的代码。
现在,假设您已经完成了该应用程序的工作,并将在几个月后返回。 您将不会记住旧代码的每个细节。 您更改它……地狱……某些东西坏了。 您如何解决这个问题? 查看您创建的每个文件并将其配置为可以再次使用吗? 它可能会起作用。 但是更改此文件将破坏其他内容。
再举一个例子。 经过几个月的努力,您终于获得了您长期以来想要的职位! 您加入团队并开始创造一些东西。 您可以使用其他开发人员的代码,反之亦然。 有一天,一切都崩溃了。 如果团队尚未将测试集成到他们的应用程序中,那么我不会羡慕您。
每个团队在创建软件或应用程序时必须编写测试。 您不想成为一个不知道如何测试的人?
是的,编写测试需要时间。 是的,一开始很难。 是的,创建应用程序更有趣。 但是测试很重要,如果正确实施,可以节省时间。
我今天的目标是提高测试技能。 我们将通过使用Jest(JavaScript测试工具)进行测试来研究单元测试和开发。 当然,您还可以使用其他测试工具,例如Mocha和Chai。
让我们开始吧!单元测试
当您决定测试应用程序时,您会面临各种类型的测试:单元测试(单元),集成测试和功能测试。 让我们关注单元测试。
功能测试和集成测试同样重要,但是它们比单元测试更难以配置和实现。 简而言之,单元测试包括测试代码的一小部分:函数,类方法等。您将数据提交到输入并确认您已收到预期的结果。
单元测试的好处:- 使代码更稳定;
- 在不改变功能行为的情况下促进功能实现的更改;
- 记录您的代码。 您很快就会明白原因。
- 使您进行正确的设计。 确实,设计不良的代码通常更难测试。
测试开发(TDD)要通过测试理解和使用开发,请记住以下两个规则:
- 在编写代码之前,编写一个失败的测试。
- 然后编写可以通过测试的代码。
当使用TDD时,我们正在谈论的是“红色,绿色,重构”循环。
红色:您编写失败的测试而没有编写代码。
绿色:编写可以通过测试的最简单的代码。 即使代码对您来说似乎最愚蠢。
重构:必要时进行代码重构。 如果您更改了代码,并且如果出现问题,则单元测试会中断,请不要担心。
构建测试文件
Jest提供了用于构造测试的功能:
describe:用于对测试进行分组并描述函数/模块/类的行为。 它有两个参数。 第一行描述您的小组。 第二个是回调函数,其中包含测试用例或挂钩函数。
还是测试:您的单元测试。 参数与描述相同。 必须是描述性的。 测试的名称由您决定,但您可以从“应该”开始。
beforeAll(afterAll):钩子函数在所有测试之前(和之后)运行。 它带有一个参数,该参数是您将在所有测试之前(和之后)运行的功能。
beforeEach(afterEach):在每个测试之前(和之后)执行的挂钩函数。 它带有一个参数,该参数是您在每次测试之前(和之后)运行的功能。
在编写任何测试之前,您应该了解以下内容:
您可以在
describe及其上使用
.skip跳过测试:
it.skip(...)或
describe.skip(...) 。 使用
.skip ,您告诉Jest忽略测试或组。
您可以在
describe及其上使用
.only来选择要运行的测试:
it.only(...)或
describe.only(...) 。 如果您有很多测试,并且只想专注于一件事或想“调试”测试,则此功能很有用。
开玩笑的设置
为了向您展示我们上面检查的测试功能,我们需要配置Jest。 这很简单。
您只需要Node.js和npm或Yarn。 确保您使用的是最新版本的Node.js,因为我们将使用ES6。 创建一个新目录并对其进行初始化。
mkdir test-example && cd test-example npm init -y # OR yarn init -y
-y对所有npm或yarn问题回答“是”。 他必须创建一个非常简单的package.json文件。
然后将
Jest添加到您的开发环境中。
yarn add jest --dev
然后将以下脚本添加到
package.json中 :
"scripts": { "test": "jest" }
yarn test将在目录中运行您的测试文件。 默认情况下,Jest会识别__tests__目录内的文件或以.spec.js或.test.js结尾的文件。
仅此而已。 您准备好编写第一个测试了吗?
匹配器(样本)
当您检查某项内容时,需要输入和预期结果。 这就是为什么Jest提供样本来测试我们的价值的原因:
expect(input).matcher(output)
笑话有很多样本,这是最重要的:
toBe:比较严格相等(===)。
expect(1 + 1).toBe(2) let testsAreEssential = true expect(testAreEssential).toBe(true)
toEqual:比较两个变量,数组或对象之间的值。
let arr = [1, 2] arr.push(3) expect(arr).toEqual([1, 2, 3]) let x= 1 x++ expect(x).toEqual(2)
toBeTruthy(toBeFalsy):指示值是否为true(或false)。
expect(null).toBeFalsy() expect(undefined).toBeFalsy() expect(false).toBeFalsy() expect("Hello world").toBeTruthy() expect({foo: 'bar'}).toBeTruthy()
toContain:检查数组是否包含元素。
expect(['Apple', 'Banana', 'Strawberry']).toContain('Apple')
toThrow:检查函数是否引起错误。
function connect () { throw new ConnectionError() } expect(connect).toThrow(ConnectionError)
初试
现在,我们将编写第一个测试并使用我们的功能。 首先在目录中创建一个example.spec.js文件,然后粘贴以下内容:
describe('Example', () => { beforeAll(() => { console.log('running before all tests') }) afterAll(() => { console.log('running after all tests') }) beforeEach(() => { console.log('running before each test') }) afterEach(() => { console.log('running after each test') }) it('Should do something', () => { console.log('first test') }) it('Should do something else', () => { console.log('second test') }) })
请注意,我们不需要导入所有使用的功能。 它们已经由Jest提供。
运行
纱线测试 :

由于您在测试中没有语句,因此它们将通过。 您是否看到过不同的console.log说明? 您需要更好地了解功能和测试用例的工作方式。
现在删除所有钩子函数,并将
.skip添加到第一个测试中:
describe('Example', () => { it.skip('Should do something', () => { console.log('first test') }) it('Should do something else', () => { console.log('second test') }) })
再次运行
纱线测试 :

如果第一个测试不起作用,也可以。
添加第三项测试并使用
.only :
describe('Example', () => { it('Should do something', () => { console.log('first test') }) it('Should do something else', () => { console.log('second test') }) it.only('Should do that', () => { console.log('third test') }) })
再次运行纱线测试 :

在本文的第二部分,我们将使用TDD在JavaScript中对堆栈进行简单的实现。