使用cordova、angularjs、ionic开发hybrid App有一段时间了。为了做单元测试,之前一直是把要测的某一部分产品代码复制到另一个单独的工程中来写测试代码,测好了以后再复制回去。弊端显而易见。于是就想,能不能在同一份产品代码上做单元测试呢?

  搜百度,结果千篇一律,而且语焉不详,一点实践意义都没有。还是谷歌好,给出了三篇非常具体的指导文章,请看附录。

 

一、我的工程概况

  因为是cordova工程,所以除了www之外还有别的很多目录,这里不一一列出。以下只看www目录:

+ www/

  + lib/      库根目录

    + angular/     放angular库

    + ionic/       放ionic库(一般已包含了angular库)

  + app/      app控制器、视图模板,按大功能块再分子目录

  + app.services/   app相关的service

  + app.directives/  app相关的directive

  + test/      测试代码根目录

    + lib/       测试用到的库

      + jasmine-2.4.1/    放jasmine库

      + angular/          放angular-mock等依赖项

    + spec/      测试用例

    SpecRunner.html  测试运行器页面

 

【注1】Jasmine库具体是哪些文件呢?请后参考资料:2. Jasmine独立包下载页面: https://github.com/jasmine/jasmine/releases

【注2】测试运行器页面 SpecRunner.html 也可以仿照 Jasmine库的示例来写,例如:

    <!-- jasmine -->
    <link rel="shortcut icon" type="image/png" href="lib/jasmine-2.4.1/jasmine_favicon.png">
    <link rel="stylesheet" href="lib/jasmine-2.4.1/jasmine.css">
    <script src="lib/jasmine-2.4.1/jasmine.js"></script>
    <script src="lib/jasmine-2.4.1/jasmine-html.js"></script>
    <script src="lib/jasmine-2.4.1/boot.js"></script>

    <!-- angular -->
    <script src="../lib/ionic/js/ionic.bundle.js"></script>
    <script src="lib/angular/angular-mocks.js"></script>

    <title>测试运行器</title>

    <!-- 被测源码 -->
    <script src="../app.services/constService.js"></script>

    <!-- 测试用例 -->
    <script src="spec/app.services/constServiceSpec.js"></script>

【注3】test目录不需要出现在最终打包后的Android apk中,所以要排除掉,方法如下:

  找到cordova工程中platforms\android\ant.properties文件,添加一句:

aapt.ignore.assets=&lt;dir&gt;test:

相当于:

aapt.ignore.assets=<dir>test:

 

 

二、测试Service

假如www/app.services/目录下有个constService.js文件:

angular.module("app.services").service("constService", function(){

  this.one = 1;

});

 

现在编写测试Spec,文件名为constServiceSpec.js,位于www/test/spec/app.services/目录,内容如下:

describe("constService", function () {
    var out;                                     // 被测对象
    beforeEach(function () {
        module('app.services');                 // 导入模块
     inject(function (constService) {        // 注入依赖
          out = constService;                   // 关联被测对象实例
    }));

    it("one == 1", function () {
        expect(out.one).toEqual(1);
    });
});        

 

然后在 SpecRunner.html中添加该Spec文件的引用:

    <!-- 测试用例 -->
    <script src="spec/app.services/constServiceSpec.js"></script>

 

最后运行SpecRunner.html即可,输出如下:

 

三、测试Controller

待续...

 

参考资料:

  1. Jasmine官网: http://jasmine.github.io/
  2. Jasmine独立包下载页面: https://github.com/jasmine/jasmine/releases
  3. Unit Testing in AngularJS: Services, Controllers & Providers
  4. Mocking Dependencies in AngularJS Tests
  5. Unit Testing Services in AngularJS for Fun and for Profit