Để tăng tỉ lệ chạy thành công của test case thuộc end-to-end testing do các điều kiện bất lợi như: mạng không ổn định, tốc độ hiển thị phần tử trên trang chậm hay độ phản hồi webserver chậm… Lúc này bạn có thể chỉ định cho test case chạy lại một số lần nhất định bằng cách sử dụng tính năng retry của mocha.
Qua bài viết Mocha run cycle? Những điều cần biết cho người mới bắt đầu, bạn đã có cái nhìn tổng thể về cách mà Mocha thực thi các test spec. Tuy nhiên khi sử dụng tính năng retry, mocha run cycle sẽ có những thay đổi, cụ thể là sự thay đổi hoạt động của các hooks. Chúng ta hãy cùng tìm hiểu về hoạt động của mocha hooks khi sử dụng tính năng retry thông qua những trường hợp cụ thể như sau:
- Retry được sử dụng ở test case
- Retry được sử dụng trong describe
- Retry được sử dụng ở cả hai nơi describe và test case
- Retry được sử dụng trong trường hợp describe lồng describe
Các code snippet trong bài viết được thực hiện trên Mocha version 8.3.0. Để xem chi tiết toàn bộ source code vui lòng truy cập vào đây.
Retry được sử dụng ở test case
Trường hợp bạn muốn chỉ định một test case cụ thể chạy lại nếu thực thi thất bại, bạn hãy sử dụng tính năng retry ngay bên trong test case. Bên dưới là mã nguồn ví dụ cụ thể:
Mã nguồn: retry/sample1.js
var assert = require('assert');
describe('hooks', function() {
before(function() {
console.log('run BEFORE');
});
beforeEach(function() {
console.log('run BEFORE EACH');
});
it('retry test case', function() {
this.retries(1);
console.log('run TEST CASE');
assert.equal(0, -1);
});
afterEach(function() {
console.log('run AFTER EACH');
});
after(function() {
console.log('run AFTER');
});
});
Kết quả chạy:
Retry test
run BEFORE
run BEFORE EACH
run TEST CASE
run AFTER EACH
run BEFORE EACH
run TEST CASE
1) retry test case
run AFTER EACH
run AFTER
Mã nguồn bên trên tại dòng 13: this.retries(1);
đang sử dụng tính năng retry với số lần retry là 1 cho test case it('retry test case'
. Khi test case này thất bại ở lần đầu tiên, nó sẽ được khởi chạy lại 1 lần nữa. Từ kết quả chạy chúng ta dễ dàng nhận thấy:
- Các hook
before
vàafter
: chạy 1 lần duy nhất - Các hook
beforeEach
vàafterEach
: số lần chạy lại bằng với số lần chạy lại của test case (nói cách khác mỗi lần chạyit
sẽ khởi chạy hai hook này). Thứ tự chạy lại vẫn tuân theo mocha run cycle.beforeEach
được chạy lại trước khi test case chạy lại.afterEach
được chạy lại sau khi chạy lại test case.
Retry được sử dụng trong describe
Mocha cho phép sử dụng tính năng retry ngay trong describe để thực hiện retry cho tất cả các test case nằm trong test spec đó. Ở ví dụ bên dưới, test spec: sample2.js gồm 2 test case it('retry test case 1'
và it('retry test case 2'.
Chúng ta chỉ định số lần retry là 1: this.retries(1)
. Khi test case thất bại, nó sẽ được chạy lại một lần. Cụ thể trong ví dụ này cả hai test case này đều thất bại và đều thực hiện chạy lại một lần.
Mã nguồn: retry/sample2.js
var assert = require('assert');
describe('Retry test', function() {
this.retries(1);
before(function() {
console.log('run BEFORE');
});
beforeEach(function() {
console.log('run BEFORE EACH');
});
it('retry test case 1', function() {
console.log('run TEST CASE 1');
assert.equal(0, -1);
});
it('retry test case 2', function() {
console.log('run TEST CASE 2');
assert.equal(0, -1);
});
afterEach(function() {
console.log('run AFTER EACH');
});
after(function() {
console.log('run AFTER');
});
});
Kết quả chạy:
Retry test
run BEFORE
run BEFORE EACH
run TEST CASE 1
run AFTER EACH
run BEFORE EACH
run TEST CASE 1
1) retry test case 1
run AFTER EACH
run BEFORE EACH
run TEST CASE 2
run AFTER EACH
run BEFORE EACH
run TEST CASE 2
2) retry test case 2
run AFTER EACH
run AFTER
Khi tính năng retry đươc sử dụng trong describe thì tất cả các test case thất bại đều sẽ được chạy lại. Hoạt động của các hook tương tự như trường hợp retry đặt trong test case.
Retry được sử dụng ở cả hai nơi describe và test case
Có một số trường hợp bạn sẽ thấy retry được chỉ định ở cả describe và nội tại bên trong test case. Mã nguồn dưới đây là ví dụ cho trường hợp này. Tập tin test spec: sample3.js gồm có 2 test case. Chỉ định số lần retry chung cho test spec (đặt trong describe) là 2 lần.
Riêng test case it('retry test case 1'
được chỉ định riêng số lần retry là 1. Hai test case trong ví dụ này đều thất bại và được chạy lại. Hãy cùng xem kết quả chạy để xem retry trên hai test case này khác nhau như thế nào nhé!
Mã nguồn: retry/sample3.js
var assert = require('assert');
describe('Retry test', function() {
this.retries(2);
before(function() {
console.log('run BEFORE');
});
beforeEach(function() {
console.log('run BEFORE EACH');
});
it('retry test case 1', function() {
this.retries(1);
console.log('run TEST CASE 1');
assert.equal(0, -1);
});
it('retry test case 2', function() {
console.log('run TEST CASE 2');
assert.equal(0, -1);
});
afterEach(function() {
console.log('run AFTER EACH');
});
after(function() {
console.log('run AFTER');
});
});
Kết quả chạy:
Retry test
run BEFORE
run BEFORE EACH
run TEST CASE 1
run AFTER EACH
run BEFORE EACH
run TEST CASE 1
1) retry test case 1
run AFTER EACH
run BEFORE EACH
run TEST CASE 2
run AFTER EACH
run BEFORE EACH
run TEST CASE 2
run AFTER EACH
run BEFORE EACH
run TEST CASE 2
2) retry test case 2
run AFTER EACH
run AFTER
Kết quả chạy cho thấy:
- test case
it('retry test case 1'
chạy lại 1 lần. Các hookbeforeEach
vàafterEach
của test case này đều được chạy lại 1 lần. Như vậy tại đây đang áp dụng số lần retry được chỉ định nội tại bên trong test case - test case
it('retry test case 2
' chạy lại 2 lần. Các hookbeforeEach
vàafterEach
của test case này đều được chạy lại 2 lần. Như vậy tại đây đang áp dụng số lần retry được chỉ định tại describe
Retry được sử dụng trong trường hợp describe lồng describe
Trong một file test spec sẽ có những trường hợp chúng ta thiết kế nhiều describe nằm trong describe khác. Khi đó số lần retry được áp dụng cho các test case sẽ lấy theo chỉ định của describe nào đây? Hãy cùng làm rõ điều này thông qua ví dụ bên dưới.
Mã nguồn: retry/sample4.js
var assert = require('assert');
describe('parent describe', function() {
this.retries(1);
it('retry test case out site', function() {
console.log('run TEST CASE outside');
assert.equal(0, -1);
});
describe('child describe', function() {
this.retries(2);
before(function() {
console.log('run BEFORE');
});
beforeEach(function() {
console.log('run BEFORE EACH');
});
it('retry test case inside', function() {
console.log('run TEST CASE');
assert.equal(0, -1);
});
afterEach(function() {
console.log('run AFTER EACH');
});
after(function() {
console.log('run AFTER');
});
});
});
Kết quả chạy:
Retry test
run TEST CASE outside
run TEST CASE outside
1) retry test case out site
child describe
run BEFORE
run BEFORE EACH
run TEST CASE
run AFTER EACH
run BEFORE EACH
run TEST CASE
run AFTER EACH
run BEFORE EACH
run TEST CASE
2) retry test case inside
run AFTER EACH
run AFTER
Chúng ta có 2 describe: describe('parent describe'
và describe('child describe'
. Trong đó:
describe('parent describe'
chứa test caseit('retry test case out site'
vàdescribe('child describe'
. Số lần retry chỉ định trong describe này là 1.describe('child describe'
chứa test caseit('retry test case inside'
. Số lần retry chỉ định trong describe này là 2.
Kết quả chạy như sau:
it('retry test case out site
' được chạy lại 1 lần. Như vậy tại đây đang áp dụng số lần retry được chỉ định trongdescribe
mà nó thuộc về.it('retry test case inside'
được chạy lại 2 lần. Các hookbeforeEach
vàafterEach
của test case này đều được chạy lại 2 lần. Như vậy tại đây đang áp dụng số lần retry được chỉ định trong describe mà nó thuộc về.
Lời kết
Trong bài viết với khá nhiều thông tin do đó rất khó để hiểu ngay sau một lần đọc. Tóm tắt lại sau một số trường hợp đã trình bày bên trên, chúng ta có thể đúc kết ngắn gọn một số điểm như sau:
-
Các hook
before
vàafter
hook không ảnh hưởng bởi retry, chúng vẫn chạy duy nhất một lần. -
Các hook
beforeEach
vàafterEach
thì đi theo test case, do đó test case retry bao nhiều lần chúng cũng chạy lại bấy nhiêu lần -
Trường hợp trong file test spec có nhiều chỉ số retry được chỉ định thì test case sẽ chạy lại với số lần retry lấy theo thứ tự ưu tiên như sau:
- Số lần retry chỉ định nội tại bên trong test case
- Số lần retry chỉ định trong describe mà test case trực tiếp thuộc về
- Số lần retry chỉ định trong describe ngoài cùng.
Tài liệu tham khảo
https://mochajs.org/#retry-tests
Thuật ngữ sử dụng
test spec: là file test script, thể hiện kịch bản của một hay nhiều test case.