Sau khi thay đổi hoặc thêm mã, bạn nên chạy các bài kiểm thử đơn vị hiện có và cân nhắc việc viết thêm. Tất cả các bài kiểm thử đều được thực thi trên các phiên bản mã không nén.
Có hai bộ kiểm thử đơn vị: kiểm thử JS và kiểm thử trình tạo khối.
Kiểm thử JS
Các bài kiểm thử JS xác nhận hoạt động của các hàm JavaScript nội bộ trong lõi của Blockly. Chúng ta sử dụng Mocha để chạy kiểm thử đơn vị, Sinon để tạo phần phụ thuộc mô phỏng và Chai để đưa ra các câu nhận định về mã.
Đang chạy kiểm thử
Trong cả blockly và blockly-samples, npm run test
sẽ chạy các kiểm thử đơn vị. Nói chung, thao tác này cũng sẽ chạy các kiểm thử khác như tìm lỗi mã nguồn và biên dịch. Bạn cũng có thể mở tests/mocha/index.html
trong trình duyệt để chạy tất cả các chương trình kiểm thử mocha một cách tương tác.
Kiểm thử việc viết
Chúng ta sử dụng giao diện Mocha TDD để chạy kiểm thử. Các chương trình kiểm thử được sắp xếp thành các bộ kiểm thử,
có thể chứa cả các bộ kiểm thử phụ và/hoặc các chương trình kiểm thử bổ sung. Nhìn chung, mỗi thành phần của Blockly (chẳng hạn như toolbox
hoặc workspace
) đều có tệp kiểm thử riêng chứa một hoặc nhiều bộ kiểm thử. Mỗi bộ có thể có một phương thức setup
và teardown
. Phương thức này sẽ được gọi trước và sau tương ứng cho mỗi bài kiểm thử trong bộ đó.
Trình trợ giúp kiểm thử
Chúng tôi có một số hàm trợ giúp dành riêng cho Blockly có thể hữu ích khi viết mã kiểm thử. Bạn có thể tìm thấy các lớp này trong core và trong blockly-samples.
Các hàm trợ giúp bao gồm sharedTestSetup
và sharedTestTeardown
là các hàm bắt buộc phải được gọi trước và sau khi kiểm thử (xem phần Yêu cầu).
sharedTestSetup
:
- Thiết lập bộ hẹn giờ giả của sinon (trong một số kiểm thử, bạn sẽ cần sử dụng
this.clock.runAll
). - Stubs Blockly.Events.fire kích hoạt ngay lập tức (có thể định cấu hình).
- Thiết lập tính năng tự động dọn dẹp các blockType được xác định thông qua
defineBlocksWithJsonArray
. - Khai báo một số thuộc tính có thể truy cập trong ngữ cảnh
this
:this.clock
(nhưng không được khôi phục nếu không sẽ gây ra sự cố trongsharedTestTeardown
)this.eventsFireStub
this.sharedCleanup
(dùng vớiaddMessageToCleanup
vàaddBlockTypeToCleanup
) (LƯU Ý: bạn không cần dùngaddBlockTypeToCleanup
nếu đã xác định khối bằngdefineBlocksWithJsonArray
)
Hàm này có một tham số options
không bắt buộc để định cấu hình chế độ thiết lập. Hiện tại, thuộc tính này chỉ được dùng để xác định xem có tạo mã giả lập Blockly.Events.fire
để kích hoạt ngay lập tức hay không (sẽ tạo mã giả lập theo mặc định).
sharedTestTeardown
:
- Xoá không gian làm việc
this.workspace
(tuỳ thuộc vào vị trí được xác định, hãy xem phần Yêu cầu kiểm thử để biết thêm thông tin). - Khôi phục tất cả các mã giả lập.
- Dọn dẹp mọi loại khối được thêm vào thông qua
defineBlocksWithJsonArray
vàaddBlockTypeToCleanup
. - Dọn sạch tất cả thư được thêm thông qua
addMessageToCleanup
.
Yêu cầu kiểm thử
- Mỗi lần kiểm thử phải gọi
sharedTestSetup.call(this);
làm dòng đầu tiên trong quá trình thiết lập của bộ kiểm thử ngoài cùng vàsharedTestTeardown.call(this);
làm dòng cuối cùng trong quá trình huỷ thiết lập của bộ kiểm thử ngoài cùng cho một tệp. - Nếu cần một không gian làm việc có hộp công cụ chung, bạn có thể sử dụng một trong các hộp công cụ đặt trước trên
index.html
kiểm thử. Hãy xem ví dụ bên dưới. - Bạn phải xử lý
this.workspace
đúng cách. Trong hầu hết các chương trình kiểm thử, bạn sẽ xác địnhthis.workspace
trong bộ kiểm thử ngoài cùng và sử dụng bộ kiểm thử này cho tất cả các chương trình kiểm thử tiếp theo, nhưng trong một số trường hợp, bạn có thể xác định hoặc xác định lại bộ kiểm thử này trong một bộ kiểm thử bên trong (ví dụ: một trong các chương trình kiểm thử của bạn yêu cầu không gian làm việc có các tuỳ chọn khác với tuỳ chọn mà bạn đã thiết lập ban đầu). Bạn phải xử lý thiết bị này khi kết thúc thử nghiệm.- Nếu bạn xác định
this.workspace
trong bộ chứa ngoài cùng và không bao giờ xác định lại, thì bạn không cần làm gì thêm.sharedTestTeardown
sẽ tự động xử lý. - Nếu xác định
this.workspace
lần đầu tiên trong một bộ bên trong (tức là bạn không xác định bộ đó trong bộ bên ngoài cùng), bạn phải loại bỏ bộ đó theo cách thủ công bằng cách gọiworkspaceTeardown.call(this, this.workspace)
trong quá trình gỡ bỏ bộ đó. - Nếu xác định
this.workpace
trong bộ kiểm thử ngoài cùng, nhưng sau đó xác định lại trong một bộ kiểm thử bên trong, trước tiên, bạn phải gọiworkspaceTeardown.call(this, this.workspace)
trước khi xác định lại để phá bỏ không gian làm việc ban đầu được xác định trong bộ kiểm thử cấp cao nhất. Bạn cũng phải huỷ giá trị mới theo cách thủ công bằng cách gọi lạiworkspaceTeardown.call(this, this.workspace)
trong quá trình gỡ bỏ bộ này.
- Nếu bạn xác định
Cấu trúc kiểm thử
Kiểm thử đơn vị thường tuân theo một cấu trúc nhất định, có thể tóm tắt là sắp xếp, hành động, xác nhận.
- Sắp xếp: Thiết lập trạng thái của thế giới và mọi điều kiện cần thiết cho hành vi đang được kiểm thử.
- Hành động: Gọi mã đang được kiểm thử để kích hoạt hành vi đang được kiểm thử.
- Assert: Xác nhận về giá trị trả về hoặc các hoạt động tương tác với đối tượng mô phỏng để xác minh tính chính xác.
Trong một kiểm thử đơn giản, có thể không có hành vi nào cần sắp xếp và bạn có thể kết hợp các giai đoạn hành động và xác nhận bằng cách nội tuyến lệnh gọi đến mã đang được kiểm thử trong câu nhận định. Đối với các trường hợp phức tạp hơn, kiểm thử sẽ dễ đọc hơn nếu bạn tập trung vào 3 giai đoạn này.
Dưới đây là một tệp thử nghiệm mẫu (được đơn giản hoá từ thực tế).
suite('Flyout', function() {
setup(function() {
sharedTestSetup.call(this);
this.toolboxXml = document.getElementById('toolbox-simple');
this.workspace = Blockly.inject('blocklyDiv',
{
toolbox: this.toolboxXml
});
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('simple flyout', function() {
setup(function() {
this.flyout = this.workspace.getFlyout();
});
test('y is always 0', function() {
// Act and assert stages combined for simple test case
chai.assert.equal(this.flyout.getY(), 0, 'y coordinate in vertical flyout is 0');
});
test('x is right of workspace if flyout at right', function() {
// Arrange
sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
viewWidth: 100,
});
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_RIGHT;
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_RIGHT;
// Act
var x = this.flyout.getX();
// Assert
chai.assert.equal(x, 100, 'x is right of workspace');
});
});
});
Những điều cần lưu ý từ ví dụ này:
- Một bộ có thể chứa các bộ khác có các phương thức
setup
vàteardown
bổ sung. - Mỗi bộ và kiểm thử đều có tên mô tả.
- Câu nhận định Chai được dùng để đưa ra câu nhận định về mã.
- Bạn có thể cung cấp một đối số chuỗi không bắt buộc sẽ xuất hiện nếu kiểm thử không thành công. Điều này giúp bạn dễ dàng gỡ lỗi các kiểm thử bị lỗi.
- Thứ tự của các tham số là
chai.assert.equal(actualValue, expectedValue, optionalMessage)
. Nếu bạn hoán đổiactual
vàexpected
, thông báo lỗi sẽ không có ý nghĩa.
- Sinon được dùng để tạo phương thức giả lập khi bạn không muốn gọi mã thực. Trong ví dụ này, chúng ta không muốn gọi hàm chỉ số thực vì hàm này không liên quan đến kiểm thử này. Chúng ta chỉ quan tâm đến cách phương thức đang kiểm thử sử dụng kết quả. Sinon sẽ tạo mô phỏng hàm
getMetrics
để trả về một phản hồi được tạo sẵn mà chúng ta có thể dễ dàng kiểm tra trong các câu nhận định kiểm thử. - Các phương thức
setup
cho mỗi bộ chỉ được chứa chế độ thiết lập chung áp dụng cho tất cả các bài kiểm thử. Nếu một kiểm thử cho một hành vi cụ thể dựa trên một điều kiện nhất định, thì điều kiện đó phải được nêu rõ trong kiểm thử liên quan.
Gỡ lỗi kiểm thử
- Bạn có thể mở các chương trình kiểm thử trong trình duyệt và sử dụng các công cụ dành cho nhà phát triển để đặt điểm ngắt và điều tra xem các chương trình kiểm thử của bạn có bị lỗi ngoài dự kiến (hoặc vượt qua ngoài dự kiến) hay không.
Đặt
.only()
hoặc.skip()
trên một chương trình kiểm thử hoặc bộ kiểm thử để chỉ chạy bộ kiểm thử đó hoặc bỏ qua một chương trình kiểm thử. Ví dụ:suite.only('Workspace', function () { suite('updateToolbox', function () { test('test name', function () { // ... }); test.skip('test I don’t care about', function () { // ... }); }); });
Hãy nhớ xoá các mã này trước khi chuyển giao (commit) mã.
Kiểm thử trình tạo khối
Mỗi khối có các kiểm thử đơn vị riêng. Các kiểm thử này xác minh rằng các khối tạo mã hơn là các hàm như dự kiến.
- Tải
tests/generators/index.html
trong Firefox hoặc Safari. Xin lưu ý rằng Chrome và Opera có các quy định hạn chế về bảo mật ngăn việc tải các chương trình kiểm thử từ hệ thống "file://" cục bộ (Vấn đề 41024 và 47416). - Chọn phần có liên quan của hệ thống để kiểm thử trong trình đơn thả xuống rồi nhấp vào "Tải". Các khối sẽ xuất hiện trong không gian làm việc.
- Nhấp vào "JavaScript".
Sao chép và chạy mã đã tạo trong bảng điều khiển JavaScript. Nếu kết quả kết thúc bằng "OK", thì kiểm thử đã thành công. - Nhấp vào "Python".
Sao chép và chạy mã đã tạo trong trình thông dịch Python. Nếu kết quả kết thúc bằng "OK", thì kiểm thử đã đạt. - Nhấp vào "PHP".
Sao chép và chạy mã đã tạo trong trình thông dịch PHP. Nếu kết quả kết thúc bằng "OK", thì kiểm thử đã đạt. - Nhấp vào "Lua".
Sao chép và chạy mã đã tạo trong Trình phiên dịch Lua. Nếu kết quả kết thúc bằng "OK", thì kiểm thử đã đạt. - Nhấp vào "Dart".
Sao chép và chạy mã đã tạo trong trình thông dịch Dart. Nếu kết quả kết thúc bằng "OK", thì kiểm thử đã đạt.
Chỉnh sửa kiểm tra trình tạo khối
- Tải
tests/generators/index.html
trong trình duyệt. - Chọn phần liên quan của hệ thống trong trình đơn thả xuống rồi nhấp vào "Tải". Các khối sẽ xuất hiện trong không gian làm việc.
- Thực hiện bất kỳ thay đổi hoặc bổ sung nào đối với các khối.
- Nhấp vào "XML".
- Sao chép tệp XML đã tạo vào tệp thích hợp trong
tests/generators/
.