Đề Xuất 6/2023 # Test Javascript Code Với Jest # Top 11 Like | Hanoisoundstuff.com

Đề Xuất 6/2023 # Test Javascript Code Với Jest # Top 11 Like

Cập nhật nội dung chi tiết về Test Javascript Code Với Jest mới nhất trên website Hanoisoundstuff.com. Hy vọng thông tin trong bài viết sẽ đáp ứng được nhu cầu ngoài mong đợi của bạn, chúng tôi sẽ làm việc thường xuyên để cập nhật nội dung mới nhằm giúp bạn nhận được thông tin nhanh chóng và chính xác nhất.

Test (hay automated test) là một phần không thể thiếu của quy trình phát triển phần mềm.Với những dự án mang tính chất phát triển lâu dài và có quy trình phát triển nhanh thì automated test là điều tối quan trọng.Bài viết này mình sẽ chia sẻ một vài kinh nghiệm viết test với javascript (Nodejs) sử dụng Jest.

Tại sao lại là Jest

Trước đây khi mới bắt đầu với Javascript mà đặc biệt là Nodejs, mình cũng hơi bị hoang mang khi tìm tool để viết test.Lạc giữa mê hồn trận các thể loại tools, nổi bật và được dùng nhiều nhất thời điểm đó vẫn là combo: Mocha + Chai + Sinon.Mình đã từng có ý định viết 1 bài blog về cách Setup đủ bộ combo này để chạy test và làm starter cho cả team, một phần vì nó khá loằng ngoằng và phức tạp.Cho đến một ngày mình gặp Jest.Jest được phát triển bởi Facebook, bạn có thể tìm hiểu thêm tại trang chủ của Jest

Vậy tại sao mình chọn Jest:

Đơn giản, dễ hiểu: bạn ko cần phải đi mò giữa nhiều thư viện khác nhau, chỉ lên trang chủ Jest là đủ

Không cần cấu hình gì cả: vâng, hoàn toàn không. Chỉ cần kéo thư viện về là bạn có thể bắt đầu viết test và test code được rồi

All in one: một mình Jest là đã cân đầy đủ test runner, assert và mock. Ngoài ra còn có thêm cả Coverage reports… rất ngầu.

Nhanh: phải nói là rất nhanh, ngoài ra terminal của test rất đẹp và thân thiện, khi dùng cảm giác rất cool.

Chừng đó đã đủ để Jest đốn tim bạn chưa? Nếu <3 rồi thì tại sao ta không tiến sâu hơn?

1

2

$ yarn add --dev jest

Nếu bạn để ý kỹ thì sẽ thấy jest bỏ qua thư mục node_modules và tự động tìm kiếm file test nằm trong thư mục __tests__ hoặc file có đuôi là: .spec.js hoặc .test.jsMình thì follow theo convention là sẽ đặt tên file test là .test.js cùng thư mục với unit code.

sum.js

1

2

3

4

function

sum

(

a, b

)

{

return

a + b;

}

module

.exports = sum;

Viết test case với Jest đơn giản chỉ là vậy. Bạn bắt đầu 1 test case với test() và sử dụng bộ assert expect() + toXXX() mà jest cung cấp.Bạn có thể tham khảo section Matchers trên trang chủ Jest, đầy đủ và rất dễ hiểu

Integration tests

Integration tests, nôm na là test xem code của mình mà có dùng đến code khác chạy có đúng không.Phần code khác, được hiểu là code của 1 unit khác, hoặc 1 thư viện mà mình nhúng vào để sử dụng.Để test được case này thì ta sẽ phải mô phỏng hành vi của phần code khác (gọi là mock), và test phần code của mình.

Mock 1 module

Giả sử mình có 1 module là total(array), nó sẽ sử dụng module sum ở trên để tính tổng các phần tử của 1 array

total.js

1

2

3

4

5

6

7

const

sum =

require

(

'./sum'

);

function

total

(

values = []

)

{

return

values.reduce(sum,

0

);

}

module

.exports = total;

Unit tests total:

Mock module thì chỉ đơn giản như vậy. Bạn có thể tham khảo kỹ hơn về mock trên trang chủ của jest.

Tất nhiên với case hàm total và sum ở trên thì bạn không cần mock vì mấy hàm này gần như cô lập và đã chạy rất nhanh.Giờ ta sẽ sang 1 case thực tế hơn, ví dụ bạn có 1 function, trong function đó gọi đến việc đọc thông tin 1 file trên ổ cứng.Trường hợp này mock sẽ giúp test case chạy nhanh hơn, mock được nhiều case hơn và bạn không cần chuẩn bị file trên ổ cứng để test.

Mock nodejs core module

Ví dụ mình có 1 hàm sử dụng core module fs để đọc thông tin file.

readContent.js

1

2

3

4

5

6

7

const

fs =

require

(

'fs'

);

function

readContent

(

file

)

{

return

fs.readFileSync(file);

}

module

.exports = readContent;

Các Chuẩn Coding Style Trong Javascript

Thế nào gọi là chuẩn Coding (Coding Standard)?

Name Standards

“ Call me by your name” trong Javascript sẽ dễ dàng hơn nếu bạn áp dụng một số quy ước cho việc đặt tên trong Javascript. Chẳng hạn như:

Ngoài ra khi viết code Javascript, ta cũng có một số quy ước đặt tên phổ biến cho hàm ví dụ như:

Một vài quy ước khác mà bạn cũng nên học hỏi thêm:

Space và Tab Indentation

Mỗi indentation level sẽ có những quy định khác nhau về việc cách nhau một nhóm các spaces nhất định với mục đích chủ yếu là để bạn hoặc thành viên khác trong team có thể dễ dàng đọc code của nhau hơn. Các Indentation level thường cách nhau bởi 2 spaces, ví dụ 2 spaces với first indentation, 4 spaces với second indentation, … Chúng ta có thể setting khi sử dụng các editor để tùy ý một tab tương ứng với bao nhiêu spaces.

Tab Indentation cũng tương tự như vậy và với mỗi indentation level ta lại sử dụng 1 tab. Nói nôm na là mỗi cấp indentation sẽ cách nhau 1 tab. Ví dụ minh họa như sau:

Thật ra thì những cái này thì mình thường dùng extension Beautiful Code trên VS Code và cứ mỗi lần save là nó lại fix những lỗi về spacing của mình nên mình cũng chẳng cần động tay động chân nhiều. Nhưng nhớ những điều này cũng sẽ có lợi cho bạn. Biết đâu đấy sau này bạn lại dùng những phần mềm khác không có tính năng này thì sao?

Hạn chế Horizontal Scrolling

Thường thì một dòng code sẽ được giới hạn bởi 80 kí tự, chính vì vậy mà ta không nên phá vỡ nguyên tắc này. Nếu bạn viết code mà khiến thành viên khác phải scroll theo chiều horizontal quá nhiều thì sẽ khiến họ cảm thấy bất tiện và khó chịu, bên cạnh đó, nó cũng không tiện cho việc review với những dự án được public lên github.

Sử dụng Black Line

if (num === 1) {

Một số chuẩn Coding khác

Những chuẩn coding này mình không biết liệt kê chúng vào đâu, nói chung là nhiều lắm nên mình chỉ liệt kê một vài chuẩn thường dùng thôi.

Đối với Object: ở JS khi ta muốn tạo các method cho object thì nên sử dụng các protype để khai báo. Việc viết như vậy sẽ tách được ra một chỗ là biến sẽ được khai báo ở trong function. Còn method nó sẽ viết ở ngoài. Ngoài ra, ta cũng nên nhớ một vài quy tắc như: tên object phải nằm cùng với dấu { đầu tiên trên cùng một hàng, sử dụng dấu hai chấm giữa key và value, không thêm dấu “,” vào cặp key-value cuối cùng, v.v….

Tạm kết

Bên trên là một vài chuẩn coding phổ biến mà mình nghĩ các anh em lập trình viên Javascript nên nhớ và áp dụng. Thật ra thì còn nhiều cái nữa lắm nhưng nếu mình liệt kê ra chắc một bài viết như thế này sẽ không đủ đâu. Và theo mình thì bấy nhiêu đó đủ để khiến code bạn trông clean hơn bao giờ hết rồi đấy!

Tìm Hiểu Về Jestjs, Viết Unit Test Cho Javascript

Jestjs là một JavaScript Testing Framework khá là dễ sử dụng và cài đặt, tuy nhiên vẫn đầy đủ tính năng để bạn có thể sử dụng Bài viết này mình xin giới thiệu một số tính năng cơ bản của jest cùng với một số ví dụ.

Cài đặt

Cài đặt Jest khá đơn giản:

yarn add --dev jest

hoặc

npm install --save-dev jest

Sau đó thêm đoạn code sau vào file package.json:

Tiếp theo mình có ví dụ một file test: math.js

Để viết test cho file trên mình tạo file test/math.test.js, đuôi file là chúng tôi sẽ nói cho jest biết đây là file test của bạn.

Sau đó chạy yarn test hoặc npm run test.

Ở trong đoạn code trên:

expect(MathJS.sum(1, 1)).toBe(2);

.toBe() chính là một matcher trong jest. Nó giống như phép so sánh bằng bình thường vậy. Ví dụ:

expect(result).toBe(2); expect(result).toBe(true); expect(result).toBe({a: 1, b: 2});

Tuy nhiên khi so sánh một Object bạn nên sử dụng .toEqual() Lý do là vì.toBe thực tế sử dụng === để so sánh và đưa ra kết quả. Và chúng ta đều biết trong javascript:

Còn .toEqual() theo như Jest sẽ lần lượt kiểm tra tất các trường của Object, hoặc mảng để so sánh. Vì vậy thay vì viết:

expect(result).toBe({a: 1, b: 2});

Hãy viết:

expect(result).toEqual({a: 1, b: 2});

Ngoài ra còn các matchers khác:

Truthiness

toBeNull so sánh với giá trị null.

toBeUndefined so sánh với giá trị undefined.

toBeDefined là hàm cho kết quả ngược lại toBeUndefined.

toBeTruthy so sánh với giá trị true.

toBeFalsy so sánh với giá trị false.

Numbers

Đối với số thập phân, bạn nên sử dụng toBeCloseTo:

String

Bạn có thể kiểm tra một đoạn văn bản với regular expressions bằng toMatch:

Array

Để kiểm tra giá trị có trong một mảng, bạn có thể dùng toContain:

Exceptions

Để kiểm tra một lỗi có thể xảy ra bạn có thể sử dụng toThrow:

Test một action trong redux

Test một event trong Jquery

Bạn có thể thấy const alert = jest.fn();. Đây là một tính năng trong Jest giúp bạn mock một function. Hay mô phỏng lại hàm cần test.

Test với module axios

Trong ví dụ này mình đã mock module axios, và đặt giá trị trả về cho hàm get. Như vậy khi test bạn sẽ không cần phải gửi request thật, tránh mất thời gian. Các module khác bạn cũng có thể làm cách tương tự.

All Rights Reserved

Unit Test Cho Nodejs Với Mocha

Bài viết này mình sẽ hướng dẫn các bạn viết bằng Mocha (một Javascript testing framework). Như các bạn cũng biết, việc Unit test cho một dự án là vô cùng quan trọng. Người ta đã phải bỏ công, bỏ sức ra để thiết kế những kiến trúc, mô hình để dự án có thể dễ Unit Test hơn. Điển hình như Android có mô hình MVP, web thì có MVC, MVVM…

Để cho bài viết dễ hiểu, mình sẽ thực hiện unit test cho một ứng dụng cụ thể. Đó là RESTful APIs tạo bởi Nodejs.

#Unit Test là gì?

Unit Test là một cơ chế để kiểm tra từng hàm trong mã nguồn của bạn. Unit Test đảm bảo từng method trong mã nguồn hoạt động đúng yêu cầu, xử lý được các ngoại lệ, kiểm tra dữ liệu nhập vào và dữ liệu trả về có chính xác với yêu cầu hay không.

Nhiều bạn cứ nghĩ Unit Test thì do tester thực hiện nên hay bỏ qua kỹ năng này. Nhưng thực tế, Unit Test phải do developer thực hiện. Chỉ có dev mới hiểu và viết được chính xác các test case mà thôi.

#Ví dụ viết Unit Test cho Nodejs

$ npm install -g mocha@2.3.1

1. Cấu trúc testing cho dự án NodeJs

Để tạo unit test cho dự án, bạn tạo thêm một thư mục Test trong dự án. Sau đó tạo thêm một file test. Ví dụ là: test-server.js

Đại khái, cấu trúc dự án bạn sẽ thấy như sau:

├── package.json ├── server │ ├── app.js │ ├── models │ │ └── blob.js │ └── routes │ └── index.js └── test └── test-server.js

Còn đây là cấu trúc một test case cơ bản:

});

Nếu bạn muốn nhóm nhiều test case lại thành một group thì có thể làm như sau:

describe('Blobs', function() { it('should list ALL blobs on /blobs GET'); });

2. Thêm thư viện cần thiết

Trong ví dụ này, mình sẽ dụng thư viện Chai (v3.2.0) và chai-http (v 1.0.0) để tạo kết nối HTTP sau đó sẽ test kết quả trả về.

Cài đặt:

$ npm install chai@3.2.0 chai-http@1.0.0 --save-dev

Sau đó update lại file chúng tôi như sau:

var chai = require('chai'); var chaiHttp = require('chai-http'); var server = require('../server/app'); var should = chai.should(); chai.use(chaiHttp); describe('Blobs', function() { it('should list ALL blobs on /blobs GET'); it('should add a SINGLE blob on /blobs POST'); });

OK, về cơ bản là chúng ta đã hiểu và chuẩn bị xong, giờ bắt đầu viết test case.

3. Viết test case cho các hàm GET

Các bạn update lại test case đầu tiên như sau:

it('should list ALL blobs on /blobs GET', function(done) { chai.request(server) .get('/blobs') .end(function(err, res){ res.should.have.status(200); done(); }); });

Chúng ta truyền vào hàm ẩn danh (callback) một tham số done (thực chất nó là một hàm). Tham số này sẽ kết thúc test case khi được gọi.

Về ví dụ test case trên thì rất dễ hiểu. Nó đơn giản là chúng ta sẽ tạo một request (GET) tới API URL: “/blobs”. Sau đó kiểm tra xem mã trả về có phải có status là 200 hay không!?

Cũng dễ hiểu phải không?

Để chạy test case, chúng ta gọi chạy lệnh mocha

$ mocha Blobs Connected to Database! GET /blobs 200 19.621 ms - 2 ✓ should list ALL blobs on /blobs GET (43ms) - should add a SINGLE blob on /blobs POST 1 passing (72ms) 4 pending

Hmm. Nếu chỉ Unit test mỗi status thì cũng không có nhiều ý nghĩa lắm. Thử kiểm tra thêm vài yếu tố nữa xem sao.

it('should list ALL blobs on /blobs GET', function(done) { chai.request(server) .get('/blobs') .end(function(err, res){ res.should.have.status(200); res.should.be.json; res.body.should.be.a('array'); done(); }); });

Viết mấy test case này cũng đơn giản nhỉ. Đọc code cũng hình dung được ý định của test case, giống như viết văn vậy.

4. Viết test case cho các hàm POST

Bạn xem lại mã nguồn của ứng dụng, khi có một “blob” được thêm mới , sẽ thông báo cho client biết với nội dụng như dưới:

{ "SUCCESS": { "__v": 0, "name": "name", "lastName": "lastname", "_id": "some-unique-id" } }

OK, suy nghĩ một lúc về kết quả mong muốn và viết test case thôi.

it('should add a SINGLE blob on /blobs POST', function(done) { chai.request(server) .post('/blobs') .send({'name': 'Java', 'lastName': 'Script'}) .end(function(err, res){ res.should.have.status(200); res.should.be.json; res.body.should.be.a('object'); res.body.should.have.property('SUCCESS'); res.body.SUCCESS.should.be.a('object'); res.body.SUCCESS.should.have.property('name'); res.body.SUCCESS.should.have.property('lastName'); res.body.SUCCESS.should.have.property('_id'); res.body.SUCCESS.name.should.equal('Java'); res.body.SUCCESS.lastName.should.equal('Script'); done(); }); });

Cho đến thời điểm này, các bạn có để ý là với các test case, chúng ta đều tương tác trực tiếp với database không? Thực tế, nếu làm như vậy sẽ làm hỏng dữ liệu test của chúng ta.

Do đó, với unit test, chúng ta nên fake luôn cả dữ liệu với mỗi test case nếu cần. Để dễ hiểu, với test case cho hàm POST, thay vì gọi tới API POST và lưu một blob vào database. Chúng ta sẽ fake việc lưu vào database, và trả kết quả như bình thường.

Để làm được điều này, chúng ta có một số hàm như beforeEach() and afterEach() hooks. Đúng như tên gọi của nó, những này cho phép chúng ta thực hiện một số tác vụ chuẩn bị, kết thúc khi gọi hàm để test.

Đầu tiên, mình sẽ thêm một file _config.js vào “server” folder, để tách URI tương tác với database, phục vụ có unit test.

var config = {}; config.mongoURI = { development: 'mongodb://localhost/node-testing', test: 'mongodb://localhost/node-test' }; module.exports = config;

Sau đó, cập nhật lại chúng tôi để cấu hình môi trường ứng dụng. Ý là, với môi trường developement thì tương tác với database này, còn khi thành product thì sẽ tương tác với database khác.

var config = require('./_config'); mongoose.connect(config.mongoURI[app.settings.env], function(err, res) { if(err) { console.log('Error connecting to the database. ' + err); } else { console.log('Connected to Database: ' + config.mongoURI[app.settings.env]); } });

Cuối cùng là viết unit test:

process.env.NODE_ENV = 'test'; var chai = require('chai'); var chaiHttp = require('chai-http'); var mongoose = require("mongoose"); var server = require('../server/app'); var Blob = require("../server/models/blob"); var should = chai.should(); chai.use(chaiHttp); describe('Blobs', function() { Blob.collection.drop(); beforeEach(function(done){ var newBlob = new Blob({ name: 'Bat', lastName: 'man' }); newBlob.save(function(err) { done(); }); }); afterEach(function(done){ Blob.collection.drop(); done(); });

Bây giờ thì trước mỗi test case, database được clear, thêm một blob. Khi test case kết thúc thì lại xóa database trước khi sang test case khác.

Như vậy mình đã kết thúc phần chia sẻ những kiến thức bản để viết unit test cho Nodejs sử dụng thư viện mocha.

Mình nhắc lại là việc viết unit test không khó nhưng lại rất quan trọng và lại rất hay được các bạn cố tình quên.

Bạn đang đọc nội dung bài viết Test Javascript Code Với Jest trên website Hanoisoundstuff.com. Hy vọng một phần nào đó những thông tin mà chúng tôi đã cung cấp là rất hữu ích với bạn. Nếu nội dung bài viết hay, ý nghĩa bạn hãy chia sẻ với bạn bè của mình và luôn theo dõi, ủng hộ chúng tôi để cập nhật những thông tin mới nhất. Chúc bạn một ngày tốt lành!