Trong bài viết này mình sẽ trình bày những khái niệm cơ bản nhất khi làm quen với unit-testing và e2e-testing trên Javascript, và đi vào thực hành viết test trên JS với Jasmine framework và Karma.

I. Những khái niệm cơ bản về testing

Unit-testing

Đây là test do chính lập trình viên viết, để kiểm tra các hàm do chúng ta viết ra có sai hay không. Unit test kiểm tra từng bộ phận nhỏ (unit) trong source code và đảm bảo các hàm này chạy đúng mỗi khi chúng ta sửa, cập nhật source code.

E2E-Testing

Ở mức độ cao hơn, để đảm bảo toàn bộ hệ thống chúng ta hoạt động trơn tru như mong đợi, E2E test ra đời giúp chúng ta kiểm thử toàn bộ hệ thống, từ giao diện cho đến các business logic trong hệ thống, giống như một người dùng thực thụ. (User flow)

Trong bài viết này mình sẽ tập trung vào cách thực hành viết unit test trên Javascript, E2E testing sẽ được trình bày ở bài viết tiếp theo.

Khái niệm TDD (Test Driven Development)

Quay trở lại với cách làm việc thường thấy của một lập trình viên: Code – Test – Fix – Code – Test … Hầu như chúng ta vẫn thường đánh giá thấp quá trình test và dành ít thời gian cho nó, nhưng một khi test, phát hiện bugs và fix bugs lại chiếm rất nhiều thời gian trong quá trình phát triển phần mềm.

TDD là một quy trình phát triển phần mềm với trọng tâm là hướng về phía kiểm thử, cụ thể các bước của TDD là:

  1. Viết 1 test cho hàm mới. Đảm bảo rằng test sẽ fail.
  2. Chuyển qua viết code sơ khai nhất cho hàm đó để test có thể pass.
  3. Tối ưu hóa đoạn code của hàm vừa viết sao cho đảm bảo test vẫn pass và tối ưu nhất cho việc lập trình kế tiếp.
  4. Lặp lại cho các hàm khác từ bước 1.

Kiến trúc Unit-test trên Javascript

Để bắt đầu viết một unit-tests với javascript, chúng ta cần tìm hiểu về kiến trúc, cách thức hoạt động khi một file unit-tests được thực thi.

Hình 1.1: Kiến trúc của một Unit tests
Nguồn ảnh: https://priv.ly/pages/develop.html

Theo hình 1.1, kiến trúc của unit-tests trong Javascript được thiết kế thành 3 tầng chính:

  • Assertion library/ Test framework
    Bình thường chúng ta có thể viết unit tests bằng Javascript thuần, tuy nhiên với sự hỗ trợ từ các test framework như Jasmine, Mocha, … cú pháp sẽ trở nên dễ viết, dễ đọc hơn.
  • Test runner
    Nhiệm vụ của test runner (Karma, Wallabyjs…) là cung cấp môi trường để thực thi test, kết nối các đoạn test được viết bởi Jasmine đến các iframes được chạy trên trình duyệt và nhận kết quả test trả về (passed/ failed with error).
  • Web browser
    Web browser là nơi các đoạn test được chạy, có hai lựa chọn đó là dùng trình duyệt thật (Chrome, Firefox…) và trình duyệt giả lập (Phantomjs).
                                                 Hình 1.2: So sánh kiến trúc giữa unit-testing và e2e-testing
                                Nguồn ảnh: https://masteringmean.com/lessons/619-Testing-the-AngularJS-Application

II. Cài đặt môi trường cho unit test

1. Cài đặt Nodejs

Karma chạy trên Nodejs và được cung cấp thông qua NPM (Node package management), vì vậy trước tiên ta cài đặt Nodejs và NPM thông qua Brew (OSX)

$ brew install node

2. Tạo Project với theo cấu trúc như sau:

js  
|--tests
|  |--fixtures
|  |--specs
|--lib
index.html  

Trong đó, thư mục js/test/fixturesjs/test/specs sẽ chứa tất cả các thành phần liên quan đến unit test, thư mục lib sẽ chứa các function thực hiện các chức năng của chương trình.

3. Cài đặt Karma:

  • Khởi tạo NPM
$ cd unit-testing-javascript
$ npm init 
  • Cài đặt Karma local
$ npm install karma --save-dev
  • Cài đặt Karma client global
$ npm install karma-cli -g
  • Cài đặt Jasmine framework và connector karma-jasmine
$ npm install jasmine-core karma-jasmine --save-dev
  • Cài đặt Chrome launcher
$ npm install karma-chrome-launcher --save-dev
  • Cài đặt Karma Fixture

Fixture trong unit test là các thành phần cố định được chuẩn bị sẵn để sử dụng cho việc testing (ví dụ như data, hay các file html). Karma fixture là một plugin của Karma hỗ trợ load các file *.html hoặc *.json như một fixture để chuẩn bị cho việc testing.

$ npm install karma-fixture --save-dev
  • Cài đặt Karma Preprocessor

Preprocessor trong karma được sử dụng để xử lý file trước khi được sử dụng ở trình duyệt. Ở đây ta sẽ sử dụng preprocessor html2js để convert các file html mẫu thành Javascript strings và đặt nó thành biến global và sử dụng chúng để test DOM.

$ npm install karma-html2js-preprocessor --save-dev

Xem thêm về Karma preprocessor tại đây.

4. Config Karma:

  • Khởi tạo karma config
$ karma init

Thực hiện các bước khai báo cần thiết, ta được file karma.conf.js với các điểm đáng lưu ý như sau:

Khai báo testing framework

    frameworks: ['jasmine', 'fixture']

Đường dẫn đến các files sẽ được load bởi trình duyệt, bao gồm các file library, fixtures và các file unit test.

    files: [
      'js/lib/*.js',
      'js/tests/fixtures/*.html',
      'js/tests/specs/*.js'
    ]

Khai báo preprocessors sử dụng

    preprocessors: {
      'js/tests/fixtures/*.html' : ['html2js']
    }

Khai báo trình duyệt sử dụng

   browsers: ['Chrome']

OK, như vậy là đã xong các bước cài đặt và cấu hình, bước tiếp theo chúng ta sẽ viết Test theo TDD pattern. Let’s get started!

III. Viết unit test đầu tiên với Karma, Jasmine, Chrome

  • Thêm file index.html với nội dung như sau:
<html>  
    <head>
        <title>Magic Calculator</title>
    </head>
    <body>
        <input id="x" type="text">
        <input id="y" type="text">
        <input id="add" type="button" value="Add Numbers">
        Result: <span id="result" />
        <script type="text/javascript" src="lib/calculator.js"></script>
        <script>
            calculator.init();
        </script>
    </body>
</html>

Chương trình toán cộng đơn giản:
  • Thêm file js/fixtures/calculator.fixture.html
<input id="x" type="text">  
<input id="y" type="text">  
<input id="add" type="button" value="Add Numbers">  
Result: <span id="result" />  
  • Thêm file js/specs/calculatorSpec.js
describe('Calculator', function() {  
  beforeEach(function() {
    // Load fixture và inject vào DOM của trình duyệt trước khi test
    fixture.base = 'js/tests/fixtures';
    fixture.load('calculator.fixture.html');

    // Gọi đến hàm init từ library
    window.calculator.init();
  });

  // Viết test case đầu tiên
  it('should calculate 3 for 1 + 2', function() {
    document.getElementById('x').value = 1;
    document.getElementById('y').value = 2;
    document.getElementById('add').click();
    expect(parseInt(document.getElementById('result').innerHTML)).toEqual(3);
  });
});

Cú pháp describe() là một bộ mô tả kiểm thử (Spec suite) sẽ bao gồm nhiều hàm kiểm thử, các hàm kiểm thử trong một spec suite thường sẽ có môi trường kiểm thử giống nhau, nên chứa các hàm khởi tạohàm thu dọn dùng chung.

Hàm beforeEach cho phép khai báo mã lệnh trước khi thực hiện những Specs, do đó ta thường dùng beforeEach để giả lập dữ liệu, hay các service cần dùng trước khi kiểm thử.

Ngược lại, chúng ta có hàm afterEach, sẽ được dùng để chạy sau cùng sau khi các Specs kết thúc.

Về cú pháp của Jasmine, xem thêm tại đây.

  • Chạy test lần đầu tiên
$ karma start karma.conf.js

Kết quả:

Với kết quả chạy test lần đầu tiên, test failed với 2 lỗi, ở dòng số 8dòng số 21

TypeError: Cannot read property 'init' of undefined at Object.<anonymous> (/Users/gumi-thao/Documents/Gumi Project/unit-testing-javascript/js/tests/specs/calculatorSpec.js:8:22)

TypeError: Cannot read property 'equal' of undefined at Object.<anonymous> (/Users/gumi-thao/Documents/Gumi Project/unit-testing-javascript/js/tests/specs/calculatorSpec.js:21:55)

Song song với kết quả trả về tại console, trình duyệt sẽ tự động kết nối đến Karma server, chúng ta có thể nhấn vào chế độ Debug để xem kết quả:

Xem kết quả tại chế độ debug, lỗi được hiển thị dưới console log của trình duyệt:

Hiện tại chúng ta chưa implement chức năng calculator nên xuất hiện lỗi là điều tất nhiên. 😀
  • Fix lỗi tại lần chạy test đầu tiên, tiến hành implement calculator function, thêm file js/lib/calculator.js
'use strict';

window.calculator = (function() {  
  function calculate() {

  };

  function init() {
    document.getElementById('add').addEventListener('click', calculate);
  };

  return {
      init: init
  }
})();
  • Chạy test lần 2

TypeError: Cannot read property 'equal' of undefined at Object.<anonymous> (/Users/gumi-thao/Documents/Gumi Project/unit-testing-javascript/js/tests/specs/calculatorSpec.js:16:55)

Với việc khởi tạo hàm init, chúng ta đã giải quyết được lỗi ở dòng số 8 ở bước trước.

Cứ tiếp tục như vậy, follow theo TDD Pattern: viết test trước, sau đó viết code cho function, chạy test, fix bugs, refactor code, cho đến khi tất cả các test đều PASSED.

  • OK, như vậy chúng ta đã hoàn thành việc thực hành viết unit test với Jasmine và Karma và follow theo TDD Pattern, trong bài viết tiếp theo, chúng ta sẽ tìm hiểu về E2E testing và thực hành viết E2E testing với ProtractorMocha
  • Source code demo về unit testing với Jasmine và Karma, có thể tải về tại: https://github.com/trongthaonh/javascript-unit-testing-karma

Happy coding! 🙂

Tài liệu tham khảo có sử dụng trong bài viết:

  1. Unit Testing JavaScript Using Jasmine
  2. Karma Tutorial – Unit Testing JavaScript
  3. Unit and E2E testing in Angular

Xu hướng

Từ khi Internet ra đời việc trao đổi và cập nhật thông tin trở nên dễ dàng và thuận tiện hơn . Một trong những ứng dụng phát triển mạnh nhất của Internet cho đến ngày nay là  World Wide Web  .  Từ các trang  các nhân đơn giản đến các trang tin tức , forum , mạng xã hội, shop online  liên tục xuất hiện , gia tăng về số lượng và chất lượng. Các trang Web luôn luôn phải cải tiến về hình thức cũng như chất lượng nhằm thu hút cũng như bảo đảm số người truy cập cao nhất.

SEO một thuật ngữ phổ biến những năm gần đây có thể xem là chìa khoá thành công của doanh nghiệp trong thời đại công nghệ ngày nay. Thương mại điện tử  đang là xu hướng tất yếu của các công ty, doanh nghiệp  trong thời kỳ hội nhập ngày nay . Các trang Web phải bắt mắt , dễ tìm  kiếm   thu hút người dùng  với  các tính năng độc đáo , khác biệt để gây được chú ý.

HTML5 & CSS3 Gumi

HTML5  and CSS3

Năm 2008 , HTML5 chính thức được ra mắt đã hứa hẹn một bước tiến mới   cho cả người dùng lẫn các Developer . Thay thế các tính năng nâng cao , mà các Developer phải cần sự hỗ trở của các công cụ hay thư viện của bên thứ 3 trước đây, HTML5 tích hợp sẵn các tính năng mới giúp việc phát triển các ý tưởng của các nhà thiết kế Web trở nên sinh động và dễ dàng hơn.

Cùng với CSS3 , HTML5 tận dụng thế mạnh của ngôn ngữ lập trình phía người dùng, khai thác tối đa việc xử lý tại client , việc hiển thị và xử lý các hiệu ứng chuyển động trở nên mượt mà và sinh động hơn. Bên cạnh các thành phần mới như : video, audio , các tag input mới , HTML5 cung cấp khả năng xử lý đồ hoạ “cực đỉnh” CANVAS, thành phần không thể thiếu đối với các Web Developer ( hiện đang rất phổ biến) .

Cá nhân là một Developer  , mình  rất thú vị và bất ngờ với những tính năng  của HTML5 và CSS3  . Bạn được  thoả sức sáng tạo theo ý mình , nếu bạn là một hoạ sỹ tài ba , tác phẩm của bạn sẽ được thể hiện sinh động trên Web và có thể chia sẻ với mọi người.

Mình xin được chia sẻ chi tiết hơn về các tính năng nổi bật của HTML5 và CSS3 trong các bài viết sau .

Kính gửi: Quý khách hàng / Quý đối tác

Nhân dịp đón mừng Năm Canh Tý 2020, Công ty gumi Việt Nam kính chúc Quý khách hàng, Quý đối tác cùng gia đình một năm mới an khang thịnh vượng.

Trong năm 2019 vừa qua, sự tin tưởng và ủng hộ vô cùng quý báu của Quý khách hàng – Quý đối tác cùng tinh thần nỗ lực không mệt mỏi của toàn thể nhân viên công ty đã giúp gumi Việt Nam có những bước ngoặt chuyển mình đầy phấn khởi.

Bằng tất cả sự trân trọng, chúng tôi vô cùng cảm ơn Quý vị đã đồng hành trong suốt thời gian qua và rất mong tiếp tục nhận được sự ủng hộ trong năm 2020 và những năm tiếp theo. Chúng tôi – gumi Việt Nam sẽ luôn nỗ lực phấn đấu và không ngừng cải tiến hết mình để cung cấp cho Quý vị những sản phẩm và dịch vụ tốt nhất.

Chúng tôi xin trân trọng thông báo:
gumi Vietnam sẽ nghỉ tết Nguyên Đán từ ngày 23/01/2020 đến hết ngày 29/01/2020.
Chúng tôi sẽ bắt đầu làm việc trở lại vào ngày 30/01/2020.

Trong thời gian nghỉ lễ,chúng tôi không thể phản hồi và hỗ trợ cho quý khách,kính mong quý khách thông cảm.

Nếu cần thêm thông tin, Quý khách vui lòng liên lạc với chúng tôi theo địa chỉ sau: contact@gumiviet.com

Một lần nữa, xin kính chúc Quý khách hàng, Quý đối tác một năm mới tươi đẹp với nhiều niềm vui, hạnh phúc bên gia đình và người thân.

Kính chào Quý khách hàng và các Đối tác,

Công ty gumi Việt Nam xin chân thành cảm ơn sự tin tưởng của Quý Công ty trong suốt một năm qua.

Chúng tôi xin trân trọng thông báo đến Quý Công ty, gumi Việt Nam sẽ tạm ngưng các giao dịch trong khoảng thời gian nghỉ tết Dương lịch theo như quy định chung:

Thời gian: từ 27/12/2019 đến 01/01/2020.
Chúng tôi sẽ bắt đầu giao dịch lại từ ngày 02/01/2020.

Trong thời gian nghỉ tết Dương lịch, chúng tôi xin phép không thể hỗ trợ kịp thời các phản hồi hay yêu cầu từ Quý công ty.
Nếu có thắc mắc, xin đừng ngần ngại liên hệ với chúng tôi qua email: contact@gumiviet.com

Chúc Quý khách một kỳ nghỉ lễ vui vẻ!
Trân trọng kính báo!

Kính gửi Quý khách hàng,

Công ty gumi Việt Nam xin chân thành cảm ơn sự hỗ trợ của Quý Khách đối với Công Ty chúng tôi.

Hôm nay chúng tôi xin trân trọng thông báo đến Quý khách, công ty chúng tôi sẽ tạm ngưng làm việc trong ngày lễ theo như quy định chung:

Thời gian nghỉ: 02/09/2019 (thứ 2)

Chúng tôi sẽ làm việc lại vào 03/09/2019 (thứ 3)

Trong thời gian nghỉ lễ, chúng tôi xin phép sẽ không thể hỗ trợ hay phản hồi về những yêu cầu của Quý công ty.

Nếu có thắc mắc, xin đừng ngần ngại liên hệ với chúng tôi qua email:

contact@gumiviet.com hoặc nhipham@gumiviet.com

Chúc Quý khách một kỳ nghỉ lễ vui vẻ cùng gia đình!
Trân trọng kính báo!

Kính gửi Quý khách hàng,

 

Công ty Gumi Việt Nam xin chân thành cảm ơn sự hỗ trợ của Quý Khách hàng đối với Công Ty chúng tôi.

Hôm nay chúng tôi xin trân trọng thông báo đến quý khách hàng, công ty chúng tôi sẽ tạm ngưng làm việc trong khoảng thời gian nghỉ lễ theo như quy định chung:

 

Thời gian nghỉ:

15/4/2019 (thứ Hai) và từ 29/4/2019 (thứ Hai) đến 1/5/2019 (thứ Tư). 

Chúng tôi sẽ làm việc lại vào 2/5/2019 (thứ Năm) và làm việc bù vào 4/5/2019 (thứ Bảy).

 

Trong thời gian nghỉ lễ, chúng tôi sẽ không thể hỗ trợ hay phản hồi về những yêu cầu của quý công ty.

Nếu có thắc mắc, xin đừng ngần ngại liên hệ với chúng tôi qua email :

contact@gumiviet.com hoặc nhipham@gumiviet.com

 

Trân trọng kính báo!

ính gửi Quý khách hàng,

Công ty Gumi Việt Nam xin chân thành cảm ơn sự hỗ trợ của Quý Khách hàng đối với Công Ty chúng tôi.

Hôm nay, chúng tôi xin trân trọng thông báo đến quý khách hàng, công ty chúng tôi sẽ tạm ngưng làm việc trong khoảng thời gian nghỉ lễ Quốc Khánh 2/9 theo như quy định chung :

Thời gian nghỉ: 1/9 (Thứ 7) – 03/09/2018 (Thứ 2).

Chúng tôi sẽ bắt đầu làm việc lại từ ngày 04/09/2018 (Thứ 3) .

Trong thời gian nghỉ lễ, chúng tôi sẽ không hỗ trợ hay phản hồi về những yêu cầu của quý công ty.

Nếu có thắc mắc, xin đừng ngần ngại liên hệ với chúng tôi qua email :

contact@gumiviet.com hoặc nhipham@gumiviet.com

Trân trọng kính báo!

Kính gửi Quý khách hàng,

Công ty Gumi Việt Nam xin chân thành cảm ơn sự hỗ trợ của Quý Khách hàng đối với Công Ty chúng tôi.

Hôm nay chúng tôi xin trân trọng thông báo đến quý khách hàng, công ty chúng tôi sẽ tạm ngưng làm việc trong khoảng thời gian nghỉ lễ theo như quy định chung :

Thời gian: 25/04/2018 và  từ 30/04/2018 đến 01/05/2018

Chúng tôi sẽ bắt đầu làm việc lại từ ngày 25/04/2018.

Trong thời gian nghỉ lễ, chúng tôi sẽ không hỗ trợ hay phản hồi về những yêu cầu của quý công ty.

Nếu có thắc mắc, xin đừng ngần ngại liên hệ với chúng tôi qua email :

contact@gumiviet.com hoặc nhipham@gumiviet.com

Trân trọng kính báo!

Kính gửi Quý Khách Hàng, Đối tác!

Lời đầu tiên,
Toàn thể nhân viên gumi Vietnam
xin gửi đến quý khách hàng lời cảm ơn sâu sắc vì đã ủng hộ chúng tôi trong suốt thời gian qua.

Chúng tôi xin trân trọng thông báo:
gumi Vietnam sẽ nghỉ tết Nguyên Đán từ ngày 14/02/2018 đến hết ngày 20/02/2018.
Chúng tôi sẽ bắt đầu làm việc trở lại vào ngày 21/02/2017.
Trong thời gian nghỉ lễ,chúng tôi không thể phản hồi và hỗ trợ cho quý khách,kính mong quý khách thông cảm. Nếu cần thêm thông tin,Quý khách vui lòng liên lạc với chúng tôi theo địa chỉ sau: huyenmy@gumi.co.jp Một lần nữa chúng tôi xin chân thành cảm ơn và kính chúc Quý khách một năm mới An Khang,Thịnh Vương! Trân trọng.

Kính gửi Quý khách hàng,

Công ty Gumi Việt Nam xin chân thành cảm ơn sự hỗ trợ của Quý Khách hàng đối với Ngân Hàng chúng tôi.
Hôm nay chúng tôi xin trân trọng thông báo đến quý khách hàng, công ty chúng tôi sẽ tạm ngưng các giao dịch trong khoảng thời gian nghỉ tết Dương lịch theo như quy định chung :
Thời gian: từ 28/12/2017 đến 01/01/2018.
Chúng tôi sẽ bắt đầu giao dịch lại từ ngày 02/01/2018.

Trong thời gian nghỉ tết Dương lịch, chúng tôi sẽ không hỗ trợ hay phản hồi về những yêu cầu của quý công ty.
Nếu có thắc mắc, xin đừng ngần ngại liên hệ với chúng tôi qua email :
contact@gumiviet.com hoặc nhipham@gumiviet.com

Trân trọng kính báo!