聊聊Angular中的单元测试


本文摘自PHP中文网,作者青灯夜游,侵删。

本篇文章和大家聊聊Angular中的单元测试,通过示例介绍一下单元测试工具(Karma + Jasmine)的使用方法。

做了多年的Angular的前端开发,一直没有胆量对前端进行单元测试,原因一是前端是跟用户打交道,不好测试,原因二是项目的时间压力没有精力弄单元测试。这也就导致在前端开发时,业务一旦改变,就要人肉进行测试。费时又没有技术含量,直接让我怀疑人生。

最近得空,索性就把Angular的单元测试研究了一把。Angular其实自己有单元测试的工具:Karma + Jasmine:

  • Karma:Karma是为测试JavaScript代码而生的自动化测试管理工具,可监控文件的变化,自动执行测试。
  • Jasmine:用来编写Javascript测试的的框架。

【相关教程推荐:《angular教程》】

第一个测试用例

当创建Angular应用后,在package.json文件中已经添加了Karma和Jasmine的依赖性:

1

2

3

4

5

"karma": "~1.7.1"

"karma-chrome-launcher": "~2.2.0",

"karma-coverage-istanbul-reporter": "~2.0.0",

"karma-jasmine": "~1.1.1",

"karma-jasmine-html-reporter": "^0.2.2",

做过后端测试的同行,估计已经知道这些组件的分工了:

  • karma:Karma核心组件
  • karma-chrome-launcher:Chrome发射器,测试会在Chrome上执行
  • karma-coverage-istanbul-reporter:coverage报告
  • karma-jasmine:Jasmine核心组件
  • karma-jasmine-html-reporter:Html测试报告

在src目录下会看到名为:karma.conf.js、test.ts的两个文件。

karma.conf.js:Karma的配置文件,其中需要重点关注的配置有:

  • frameworks:使用的测试框架,这里使用Jasmine

  • port:测试使用的端口

  • autoWatch:是否自动监测测试代码的改变,自动执行测试

  • plugins:测试使用到的插件,与package.json文件保持一致

  • browsers:测试运行使用的浏览器,这里使用Chrome,如果你需要使用其他浏览器,需要通过npm安装浏览器发射器,并在plugins和这里设置,例如使用Safari:

    1

    2

    3

    4

    5

    6

    npm install karma-safari-launcher --save-dev

     

    plugins: [

        require('karma-safari-launcher')

    ]

    browsers: ['Safari'],

test.ts:测试入口文件,其中初始化了测试环境以及指定所有测试文件

在app目录下,还会找到一个名为app.component.spec.ts的文件,这就是一个Jasmine的测试,内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

import { TestBed, async } from '@angular/core/testing';

import { AppComponent } from './app.component';

//测试入口,参数为测试名、方法

describe('AppComponent', () => {

  //每个测试用的Setup

  beforeEach(async(() => {

    TestBed.configureTestingModule({

      declarations: [

        AppComponent 

      ],

    }).compileComponents();

  }));

 

  //测试用例

  it('should create the app', async(() => {

    const fixture = TestBed.createComponent(AppComponent);

    const app = fixture.debugElement.componentInstance;

    expect(app).toBeTruthy();

  }));

 

  it(`should have as title 'test-demo'`, async(() => {

    const fixture = TestBed.createComponent(AppComponent);

    const app = fixture.debugElement.componentInstance;

    //断言,期望值是否满足要求

    expect(app.title).toEqual('test-demo');

  }));

 

  it('should render title in a h1 tag', async(() => {

    const fixture = TestBed.createComponent(AppComponent);

    fixture.detectChanges();

    const compiled = fixture.debugElement.nativeElement;

    //通过querySelector获取页面元素

    expect(compiled.querySelector('h1').textContent).toContain('Welcome to test-demo!');

  }));

 

  //每个测试用例的TearDown

  afterEach(function() {

    //清除测试数据

  });

});

上述代码使用了Jasmine的语法,关于Jasmine的更详细介绍,参见JavaScript 单元测试框架:Jasmine 初探。这里不赘述。

执行: ng test,就会看到上述文件的测试报告:

1.png

另外在测试报告中还可单击某个测试单独执行,报告如下:

2.png

填坑

对于Pipe、Service、Router等组件的测试,可参见Angular文档,这里重点讲述下在测试中遇到的各种坑。

No provider ***

测试时,如果被测组件需要其他第三方组件、servcie或pipe,没有被引入,就会出现No provider 的错误,解决方法很简单,在beforeEach中使用imports或provider引入即可:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

beforeEach(async(() => {

    TestBed.configureTestingModule({

      declarations: [

        //这里声明

      ],

      imports: [

        //这里引入

      ],

      providers: [

        //这里引入

      ],

      schemas: [CUSTOM_ELEMENTS_SCHEMA],

    })

      .compileComponents();

  }));

请求超时

在开发时,异步请求由于网络原因常会出现TimeOut的错误,通常的解决方法是设置TimeOut时间的上限,并对TimeOut错误作出人性化的提示。在测试时也同样会发生TimeOut的错误:

3.png

解决办法是可以在某个测试用例中设置TimeOut的时间:

阅读剩余部分

相关阅读 >>

深入了解Angular中的模块和懒加载

javascript单元测试有什么用

浅谈Angular指令中的4种设计模式

浅谈Angular cli工具如何从零搭建并运行一个简单项目

浅谈Angular如何编译打包?如何使用docker发布?

浅谈Angular项目中如何引入第三方ui库(Angular material)

了解Angularjs中的“模块”

Angular开发者必须学习的19件事

如何利用管道提高Angular应用程序的性能?

Angular中 “?” 和 “!”有什么用?

更多相关阅读请进入《Angular》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...