Viết integration test Nodejs with jasmine

Trong 1 lần tìm hiểu viết integration test cho ứng dụng nodejs, mình thấy có khá nhiều framework để test. Trong số đó được nhiều lập trinh viên sử dùng là mocha và jasmine. Jasmine là 1 behavior-driven development framework test cho Javascript. Nó không phụ thuộc vào việc bạn sử dụng framework javascript nào. Không yêu cầu DOM và dễ dàng viết test. Hôm nay mình sẽ viết bài hướng dẫn sử dụng jasmine để viết test cho NodeJs.

1.Cài đặt

Add Jasmine vào file package.json:

npm install jasmine --save-dev

Khởi tạo jasmine trong project:

jasmine init

Khi bạn muốn chạy test ta sẽ chạy:

jasmine

2. Viết test

Jasmine là 1 thư viện vì vậy trong file test bạn sẽ khai báo trên đầu file

var Jasmine = require('jasmine');
var jasmine = Jasmine();

Chúng ta sẽ setup vài ví dụ đơn giản để test hàm get server để đảm bảo rằng server sẽ trả ra HTTP status là 200 (OK) à nội dung của body là "hello world". Viết test bao gồm describe để miêu tả nội dung test giúp cho việc rõ ràng nội dung test hơn.

Bên trong ta sẽ có function it cũng chứa description về test. ngoài ra chứa các yêu cầu và mong muốn trả về . Cấu trúc đơn giản của hàm test:

describe("Hello World Server", function() {
  describe("GET /", function() {

    it("returns status code 200", function() {

    });

  });
});

Bây giờ trong function it chúng ta sẽ add URL và request. Trong function request sẽ có các mong muốn trả về gồm status và content.

var request = require("request");

var base_url = "http://localhost:3000/"

describe("Hello World Server", function() {
  describe("GET /", function() {
    it("returns status code 200", function(done) {
      request.get(base_url, function(error, response, body) {
        expect(response.statusCode).toBe(200);
        done();
      });
    });

    it("returns Hello World", function(done) {
      request.get(base_url, function(error, response, body) {
        expect(body).toBe("Hello World");
        done();
      });
    });
  });
});

Chúng ta mong muốn body trả về 'Hello World" và sau đó là hàm done() để chắc chắn expect đã chạy xong trước khi kết thúc it.

3.Run test

Trước khi chạy test local. ta mở file package.json và add command:

{
  "name": "node-tutorial",
  "version": "1.0.0",
  "main": "app.js",
  "dependencies": {
    "express": "^4.13.3",
    "request": "^2.65.0"
  },
  "devDependencies": {
    "jasmine-node": "^1.14.5"
  },
  "scripts": {
    "test": "jasmine-node spec"
  },
  "author": "",
  "license": "ISC"
}

Sau đó có thể sử dụng npm testđể chạy test.

Distellis-MBP:node-tutorial zack$ npm test

> [email protected] test /Users/zack/ws/src/node-tutorial
> jasmine-node spec

Magic is happening on port 3000
..

Finished in 0.06 seconds
2 tests, 2 assertions, 0 failures, 0 skipped

4. The app

Ngoài ra để test server gồm 2 routes, 1 get và 1 post. Có 1 cách đơn giản sử dụng the app để test và chúng ta chỉ chạy server nếu file được chạy trực tiếp.

express = require 'express'

exports.app = app = express.createServer()

app.get "/", (req, res) ->
  res.send "Hello, world!"

app.post "/", (req, res) ->
  res.send "You posted!"

if __filename == process.argv[1]
  app.listen 6789

Để gửi request lên server ngoài sử dụng thử viện request ta có thể sử dụng thử viện spec-helper

helper = require './spec-helper'

describe "App", ->
  describe "get /", ->
    it "responds successfully", ->
      helper.withServer (r, done) ->
        r.get "/", (err, res, body) ->
          expect(res.statusCode).toEqual 200
          done()

    it "has the correct body", ->
      helper.withServer (r, done) ->
        r.get "/", (err, res, body) ->
          expect(body).toEqual "Hello, world!"
          done()

  describe "post /", ->
    it "has the correct body", ->
      helper.withServer (r, done) ->
        r.post "/", "post body", (err, res, body) ->
          expect(body).toEqual "You posted!"
          done()

5. Expect trong jasmine

Jasmine framework hỗ trợ bạn rất nhiều các matcher cho test spec.Dưới đây là 1 số ví dụ:

  • toEqual: checks if two things are equal and not necessarily the same exact object.
// function will pass
expect(true).toEqual(true);
expect([1, 2, 3, 4, 5]).toEqual([1, 2, 3, 4, 5]);
  • toBe: checks if two things are the same object, not just if they are equivalent.
var spjavascriptort = { species: "football" };
var tv_progame = { species: "football" };
expect(sport).toEqual(tv_programe); // success;
expect(sport).toBe(tv_programe); // failure; not the same object
expect(sport).toBe(sport); // success; the same object
  • toBeTruthy: to test if something evaluates to true.
expect(true).toBeTruthy();
expect(1).toBeTruthy();
expect({}).toBeTruthy();
  • toBeFalsy: to test if something evaluates to false such as empty strings, zero, undefined, etc…
expect(false).toBeFalsy();
expect(null).toBeFalsy();
expect("").toBeFalsy();
  • toBeNull: checks if something is null.

expect(null).toBeNull(); // success
expect(false).toBeNull(); // failure
expect(somethingUndefined).toBeNull(); // failure
  • toContain: checks if a value is inside another.
describe("Hello world", function() {
   it("says world", function() {
    expect(helloWorld()).toContain("world");
   });
 });
  • toBeLessThan/toBeGreaterThan: check if something is greater than or less than something else.
 expect(20).toBeGreaterThan(10); // success
expect(10).toBeLessThan(20); // success
expect("a").toBeLessThan("z"); // success Notice that it works for strings too!

Tổng kết

Qua bài viết các bạn có thể biết được thêm 1 cách viết integration test cho ưng dụng nodejs bằng jasmine. Ngoài ra các bạn có thể tìm hiểu thêm về thư viện mocha để viết test.