zoukankan      html  css  js  c++  java
  • Poang,基于Node.js的自动化测试范例

    Poang是一个基于express framework部署在Heroku/MongoLab上的Node.js应用,该应用的作者Stephen Bronstein详细描述了如何写单元测试、功能测试、集成测试并在云端使用Strider做持续集成开发。

    Poang主要业务逻辑是使用Everyauth做本地身份认证,并将用户身份信息通过Mongoose-Auth持久化到MongoDB中去(Mongoose做对象建模),利用Connect-Mongo做会话保存。Poang中的认证代码auth.js大部分取自Mongoose-Auth docs

    测试代码使用了多种技术框架,Mocha做单元测试,should做断言,Sinon.JS监测以及制造mock数据,Zombie.js做基于浏览器的轻量级集成测试。

    单元测试

    写一个基于web/数据库的单元测试比较麻烦,有很多配置项需要添加,这里举一个简单例子来阐述如何使用Mocha框架做单元测试

    describe('index', function() {
      describe('#timesTwo()', function() {
       it('should multiply by two', function() {
        var x = 5;
        var xTimesTwo = index.timesTwo(x);
        xTimesTwo.should.equal(10);
       });
      });
    });

    注:前三行表述了单元测试的目标类和目标函数(一个乘二函数),单元测试的代码体输入参数为5,利用should断言来校验返回值是否为10

    功能测试

    1) Case1

    创建mock请求对象mock_req,来验证服务端的身份认证功能。使用Sinon.JS的spy功能监测mock响应对象mock_res是否有做重定向,如果没有做重定向,则将mock响应对象的http状态码设置为200

    var mock_req = {session: {}};
    var mock_res = {redirect: function() {}, end: function() {}};
    sinon.spy(mock_res,"redirect");
    middleware.require_auth_browser(mock_req, mock_res, function() {
      mock_res.statusCode = 200;
    });

    服务端会验证mock请求对象是否包含用户信息,因为我们mock请求不包含用户对象,所以服务端会返回http 401状态码(未授权),并跳转到login页面

    mock_res.statusCode.should.eql(401);
    mock_res.redirect.getCall(0).args[0].should.equal('/login');

    2) Case2

    重新创建一个mock对象,包含用户信息,此时我们断定,mock响应对象的状态码被设置为200

    mock_req = {user: {}};
    middleware.require_auth_browser(mock_req, mock_res, function() {
      mock_res.statusCode = 200;
    });
    mock_res.statusCode.should.eql(200);

    集成测试

    接下来使用Zombie.js做轻量级基于浏览器的集成测试,步骤如下:

    首先启动Poang应用实例,随机选择一个服务端口号(当然也可以自己指定一个端口号,但要保证该端口号没有被占用)

    var TEST_PORT = Math.floor(Math.random()*61439 + 4096);
    before(function() {
      var server = app.init(config);
      // should check to see if something is listening on the port first
      server.listen(TEST_PORT);
      console.log('Server is listening on port %s', TEST_PORT);
    });

    确认下这个服务是可用的,并且页面的标题是”Poang”

    var browser = new zombie();
    browser.visit(base_url, function () {
      browser.success.should.be.ok;
      if (browser.error) {
       console.dir('errors reported:', browser.errors);
      }
      done();
    });
    browser.text("title").should.eql("Poang");

    注册一个用户,校验注册流程是否成功

    var browser = new zombie();
    browser.visit(base_url + "register", function () {
      browser.query("#register").should.be.ok;
      // Fill email, password and submit form
      browser.fill("email", test_email).fill("password", "secret").
      pressButton("register", function() {
       // Form submitted, new page loaded.
       browser.success.should.be.ok;
       browser.location.pathname.should.eql("/");
       done();
      });
    });

    因为每次集成测试,都会注册同样的帐号,为了避免困扰,我们在跑完集成测试的时候可以将帐号从数据库中删掉(这个取决于测试的具体策略,可以灵活调整)

    after(function(done) {
      var db_uri = process.env.MONGOLAB_URI || process.env.MONGODB_URI || config.default_db_uri;
     mongoose.connect(db_uri);
      // drop database
     mongoose.connection.db.executeDbCommand( {dropDatabase:1}, function() {
      console.log("Dropped test database");
      done();
    });
    })

    Strider持续集成

    Strider是一个基于Node.jsPython的持续集成平台,Strider本身可以集成任意的测试框架,唯一的要求是应用必须支持”NPM Test”命令,而Strider对测试用具TAP有很好的集成性,所以Poang应用的描述文件Package.json会添加如下命令:

    "test": "mocha -R tap --globals o,section,data,m,k,i"

    “--globals o,section,data,m,k,I”指定全局变量,不然会报全局变量遗漏错误

    Strider还在内测阶段,读者可以申请邀请码试用

    以下是开发部署应用过程中,总结的最佳实践

    MongoDB的配置

    启动MongDB的时候,需要关闭数据库文件大小的预分配,不然会间或出现单元测试连接数据库超时

    mongod --noprealloc --nojournal

    Heroku/MongoLab上部署Poang应用

    • 创建进程文件Procfile,并指定如何启动该进程,详细可以参照Heroku指南
      • web: node app.js
    • MongoLab数据库连接的环境变量
      • Poang首先会使用Heroku提供的环境变量process.env.MONGOLAB_URI,如果找不到则会使用Strider提供的process.env.MONGODB_URI,如果还是找不到会使用本地系统默认配置config.default_db_uri
    • Heroku上添加MongoLab模块插件,使用Heroku Toolbelt创建MongoLab模块,命令如下(如果在本地目录,无需指定应用名称)

    heroku addons:add mongolab:starter --app [your_app_name]

  • 相关阅读:
    转载:[Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)
    转载:《理解OAuth 2.0》 阮一峰
    转载:《RESTful API 设计指南》 阮一峰
    转载:《理解RESTful架构》 阮一峰
    转载:2.2.5 在配置中使用变量《深入理解Nginx》(陶辉)
    转载:2.2.4 配置项的单位《深入理解Nginx》(陶辉)
    转载:2.2.3 配置项的注释《深入理解Nginx》(陶辉)
    SQL & PL/SQL 模块总结
    一些比较好的shellscript脚本
    11 高级优化技术
  • 原文地址:https://www.cnblogs.com/shihao/p/2536188.html
Copyright © 2011-2022 走看看