Học React/Redux qua ví dụ thực tế: Testing

Chào mừng các bạn trở lại với series Học React/Redux qua ví dụ thực tế, trong bài trước chúng ta đã setup xong project và đã viết được những React component đầu tiên. Trong bài học lần này tôi sẽ hướng dẫn các bạn các setup để test các React component. Tôi sẽ hướng dẫn testing một cách cơ bản mà không đi quá sâu vào chủ để testing đâu nhé!

Để test, chúng ta sẽ sử dụng mocha, một test framework, chai môt thư viện dùng để so sánh, và jsdom một thư viện cung cấp cho chúng ta những tính năng truy xuất vào DOM trên node.

Cài đặt

Từ thư mục gốc của project các bạn cài đặt như sau.

npm install --save-dev mocha chai jsdom

Tiếp đến chúng ta cần một file setup để chứa các config. Từ thư mục gốc các bạn tạo file test setup như sau.

mkdir test
cd test
touch setup.js

Mở file setup.js và bắt đầu cài đặt môi trường test thôi.

import React from 'react';
import {expect} from 'chai';
import jsdom from 'jsdom';

const document = jsdom.jsdom('<!doctype html><html><body></body></html>');
const window = document.defaultView;

global.document = document;
global.window = window;

Object.keys(window).forEach((key) => {
  if (!(key in global)) {
    global[key] = window[key];
  }
});

global.React = React;
global.expect = expect;

Về cơ bản, chúng ta expose một jsdom document đã được generate và một window object ra global scope, những thứ này sẽ được sử dụng bởi React trong quá trình test. Ngoài ra chúng ta cũng cần phải expose tất cả các thuộc tính của window object để chúng có thể được sử dụng sau. Cuối cùng nhưng cũng không kém phần quan trọng đó là cho phép những object React cũng như expect được truy xuất ở global scope. Điều này giúp chúng ta không phải tốn công import chúng vào mỗi khi muốn test.

Trong file package.json chúng ta sẽ thêm một script mới để chạy test, script này sẽ dùng mocha như là test framework, sửu dụng file test/setup.js để cài đặt môi trường và duyệt qua tất cả các file có phần đuôi dạng *.spec.js trong thư mục src như là những test files.

...
  "scripts": {
    ...
    "test": "mocha --compilers js:babel-core/register --require ./test/setup.js 'src/**/*spec.js'"
  },
...

Ngoài ra còn chúng ta còn cần một số thư viên gọn gàng hơn để giúp chúng ta test các React component. Enzyme là một thư viện hỗ trợ chúng ta giả lập trạng thái tại thời điểm test React component. Nào cùng cài đặt nó!

npm install --save-dev react-addons-test-utils enzyme

Bây giờ thì còn chờ gì nữa, bắt tay vào viết test file đầu tiên cho React component của chúng ta nào.

Đặt tay lên bàn phím viết test case thôi!

Trong thư mục src/components tạo file TrackList.spec.js để test component TrackList. Cùng viết các test case cho component trong file này.

import TrackList from './TrackList';
import {shallow} from 'enzyme';

describe('TrackList', () => {

  it('shows two tracks', () => {
    const props = {
      tracks: [{ id: 1, title: 'foo' }, { id: 2, title: 'bar' }]
    };
    const element = shallow(<TrackList {...props} />);

    expect(element.find('div')).to.have.length(2);
  });

});

Đây là test case tôi viết để test component TrackList. Như chúng ta đã biết thì khi component này sẽ render ra các div chứa title của các bài hát, ở đây tôi truyền vào props là danh sách hai bài hát vì thế nó sẽ render ra hai div chứa tên bài hát. Khi run test, nó sẽ phải pass.

Cùng run test bằng lệnh npm test và xem kết quả nào.

Khoan, có điều gì không đúng!

Ơ, hình như có gì đó sai sai, test chạy fail, nào cùng double check lại nhé, test case chúng ta đưa ra là truyền vào danh sách hai bài hát thì render ra hai div, sao sai nhỉ?

Ngó lại component TrackList , à thì ra là nó còn được wrap lại bởi một div ở bên ngoài. Thay vì tìm div thì ta phải tìm div con của div. Vì thế test case sẽ được sửa lại như sau.

import TrackList from './TrackList';
import {shallow} from 'enzyme';

describe('TrackList', () => {

  it('shows two tracks', () => {
    const props = {
      tracks: [{ id: 1, title: 'foo' }, { id: 2, title: 'bar' }]
    };
    const element = shallow(<TrackList {...props} />);

    expect(element.find('div > div')).to.have.length(2);
  });

});

Chạy test lại nào.

Tuyệt vời, test pass rồi. Thật ra tôi cố tình viết test fail để cho các bạn thấy mặt mũi cái test fail nó ra thế nào thôi, chứ không phải tui code lởm đâu nhé, haha.

Được đà viết thêm cái test case nữa nào, lần này chúng ta sẽ test xem component có render ra đúng tên bài hát hay không.

import TrackList from './TrackList';
import {shallow} from 'enzyme';

describe('TrackList', () => {

  ...

  it('shows track title', () => {
    const props = {
      tracks: [{ id: 1, title: 'foo' }]
    }
    const element = shallow(<TrackList {...props} />);

    expect(element.contains('foo')).to.be.true;
  })

});

Chạy test nào, lần này bao pass nhe, tôi tính toán hết rồi.

Ngoài ra, chúng ta có thể thêm script vào package.json để watch xem trong quá trình develop ở local, bất cứ chỉnh sửa nào làm test fail ta cũng có thể nhìn thấy.

...
  "scripts": {
    ...
    "test:watch": "npm run test -- --watch"
  },
...

Để chạy, đơn giản nhập vào termial lệnh npm run test:watch.

Source code trong bài các bạn có thể tìm thấy ở https://github.com/codeaholicguy/react-redux-tutorial/tree/master/testing-setup

Hôm nay đến đây là đủ rồi, tôi sẽ không viết thêm test case nào nữa đâu. Tự do thoải mái sáng tạo thêm test case, nghịch chán chê đi để đợi bài sau nhé, bài sau chúng ta sẽ đụng tới Redux đấy! Có comment gì đừng quên để lại cho tôi phía bên dưới bài viết nhé, tạm biệt!

Bài gốc: Codeaholicguy

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Hoàng Nguyễn

35 bài viết.
364 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
76 34
Nhu cầu về Javascript developer hiện nay trong thị trường IT là rất lớn. Nếu bạn có kiến thức ở mảng này thì cơ hội nghề nghiệp cũng như thu nhập c...
Hoàng Nguyễn viết hơn 1 năm trước
76 34
White
49 19
Microservices hiện đang nhận được rất nhiều sự chú ý: các bài viết, các blog, các cuộc thảo luận trên phương tiện truyền thông, trên mạng xã hội, v...
Hoàng Nguyễn viết hơn 2 năm trước
49 19
White
29 2
Chuyện tối ưu code, (Link) là công việc hàng ngày của mỗi lập trình viên, điều đó ai cũng biết. Nhưng liệu code tối ưu có phải là code đẹp, và ngượ...
Hoàng Nguyễn viết 3 tháng trước
29 2
Bài viết liên quan
White
13 4
Tôi đã từng viết một số bài giới thiệu về (Link), hay (Link) tuy nhiên chừng đó có vẻ là chưa đủ để bạn có thể lặn sâu hơn vao trong thế giới của R...
Hoàng Nguyễn viết hơn 1 năm trước
13 4
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
35 bài viết.
364 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!