Sự khác biệt giữa `before ()` và `beforeEach ()` là gì?


90

Sự khác biệt cụ thể giữa Mocha 's before()beforeEach() ? (Câu hỏi tương tự cho after()afterEach().)

Tôi giả sử before()chạy một lần mỗidescribe() khối và beforeEach()chạy một lần cho mỗi lần kiểm tra ( it()khối). Có đúng như vậy không?

Và khi nào thì tôi chọn sử dụng cái này thay cho cái kia?

Câu trả lời:


188

before()được chạy một lần trước khi tất cả các thử nghiệm trong a describe
after()   được chạy một lần sau khi tất cả các thử nghiệm trong a describe
beforeEach()được chạy trước khi mỗi thử nghiệm trong a describe
afterEach()   được chạy sau mỗi thử nghiệm trongdescribe

Cái nào bạn muốn sử dụng tùy thuộc vào thử nghiệm thực tế của bạn.

Bây giờ, cho lời giải thích dài. Nếu bạn chạy mocha -R mintrên cái này:

describe("top", function () {
    before(function () {
        console.log("top before");
    });
    after(function () {
        console.log("top after");
    });
    beforeEach(function () {
        console.log("top beforeEach");
    });
    afterEach(function () {
        console.log("top afterEach");
    });
    it("test1", function () {
        console.log("top test1");
    });
    describe("sublevel", function() {
        before(function () {
            console.log("sublevel before");
        });
        after(function () {
            console.log("sublevel after");
        });
        beforeEach(function () {
            console.log("sublevel beforeEach");
        });
        afterEach(function () {
            console.log("sublevel afterEach");
        });
        it("test1", function () {
            console.log("sublevel test1");
        });
        it("test2", function () {
            console.log("sublevel test2");
        });
    });
    it("test2", function () {
        console.log("top test2");
    });
});

Bạn sẽ thấy một cái gì đó như (Tôi đã bỏ qua đầu ra không liên quan):

top before
top beforeEach
top test1
top afterEach
top beforeEach
top test2
top afterEach
sublevel before
top beforeEach
sublevel beforeEach
sublevel test1
sublevel afterEach
top afterEach
top beforeEach
sublevel beforeEach
sublevel test2
sublevel afterEach
top afterEach
sublevel after
top after

Điều có thể ngạc nhiên nếu bạn nhìn vào những gì thực thi trước và sau mỗi bài kiểm tra ở cấp độ bán lại là cả hai lệnh beforeEachgọi lại ở cấp cao nhất và ở cấp độ bán lại đều được gọi. Điều tương tự đối với afterEach.

Một số người cũng đang ngạc nhiên bởi trình tự sublevel before, top beforeEach, sublevel beforeEach. Họ nghĩ rằng tất cả các móc trong một phạm vi bên ngoài nên thực hiện trước khi tất cả các móc trong một phạm vi bên trong, vì vậy họ mong đợi các trình tự: top beforeEach, sublevel before, sublevel beforeEach. Tuy nhiên, thứ tự mà Mocha thực hiện các hook hoàn toàn có ý nghĩa: một beforehook có nghĩa là tạo tiền đề cho một nhóm các bài kiểm tra, trong khi một beforeEachbài kiểm tra dành cho từng bài kiểm tra riêng lẻ. Khi Mocha thực hiện một bài kiểm tra, tất cả các hook beforebeforeEachhook được đặt trong phần describechứa nó và tất cả các phần tử tổ tiên của nó sẽ describeáp dụng cho bài kiểm tra. Mocha sẽ thực hiện từng beforehook từ phạm vi ngoài cùng đến trong cùng, và tất cả beforeEachhook từ phạm vi ngoài cùng đến trong cùng. Tuy nhiên, tất cả các beforehook áp dụng đều được thực thi trước bất kỳ beforeEachhook nào . Điều này giải thích cho lệnh ở trên: sublevel beforethực thi trước top beforeEachvì nó là một beforehook. Và với afterafterEach, cùng một logic được áp dụng nhưng thứ tự bị đảo ngược: tất cả các afterEachhook áp dụng đều được thực thi trước bất kỳ afterhook nào .

Cũng lưu ý rằng Mocha không quan tâm đến việc tôi đã sắp xếp itcuộc gọi của mình như thế nào so với describecuộc gọi ở cấp cao nhất describe. Nó thực thi top test1, top test2sau đó là các bài kiểm tra cấp độ lại, mặc dù thứ tự tôi đã đưa ra top test1, sau đó là các bài kiểm tra cấp độ lại top test2.

Những gì bạn muốn sử dụng trong before, beforeEachvv thực sự phụ thuộc vào đặc điểm của các bài kiểm tra của bạn. Nếu bạn cần thiết lập một đối tượng hoặc cấu trúc dữ liệu giả và đối tượng hoặc cấu trúc này có thể được sử dụng lại bởi tất cả các bài kiểm tra trong một lần duy nhất describe, bạn có thể sử dụng befoređể thiết lập và afterchia nhỏ nó. Đây có thể là trường hợp nếu bạn đang thực hiện các bài kiểm tra chỉ đọc trên cấu trúc. Nếu tất cả các bài kiểm tra của bạn chỉ đọc nó, thì không cần phải tạo nó nhiều lần. Nếu mỗi bài kiểm tra của bạn describecần một bản sao mới của cấu trúc bởi vì mỗi bài kiểm tra là sửa đổi cấu trúc thì bạn nên sử dụng beforeEachđể tạo lại cấu trúc cho mỗi bài kiểm tra và sau đóafterEachnếu bạn cần xé nó ra một cách sạch sẽ. Làm điều này đảm bảo sự cô lập của thử nghiệm: mỗi thử nghiệm bắt đầu từ một trạng thái đã biết và không phụ thuộc vào sự hiện diện hay vắng mặt của thử nghiệm trước đó để thành công.


1
Tuyệt vời cảm ơn bạn. Câu hỏi của tôi là một phần là gì và một phần tại sao, cả hai điều này đều quan trọng, đặc biệt là sự phân biệt giữa đọc / ghi.
ericsoco
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.