2012-03-16 28 views
42

Câu hỏi này liên quan đến khung kiểm tra Mocha cho NodeJS.Làm cách nào để thực thi các kiểm tra Mocha không đồng bộ (NodeJS) theo thứ tự?

hành vi

Giá trị mặc định có vẻ là để bắt đầu tất cả các bài kiểm tra, sau đó xử lý callbacks async khi họ đi vào.

Khi chạy thử nghiệm async, tôi muốn chạy mỗi bài kiểm tra sau phần async của một cái trước đó đã được gọi.

Làm thế nào tôi có thể làm điều này?

Trả lời

30

Điểm không quá nhiều khi "mã có cấu trúc chạy theo thứ tự bạn đã cấu trúc" (ngạc nhiên!) - nhưng thay vì @chrisdew gợi ý, các đơn hàng trả lại cho các kiểm tra không đồng bộ không thể được đảm bảo. Để giải quyết vấn đề này - các thử nghiệm tiếp tục xuống dưới (chuỗi thực thi đồng bộ) không thể đảm bảo rằng các điều kiện bắt buộc, được thiết lập bởi các kiểm tra không đồng bộ, sẽ sẵn sàng vào thời điểm chúng chạy. Vì vậy, nếu bạn yêu cầu một số điều kiện nhất định được đặt trong các thử nghiệm đầu tiên (như mã thông báo đăng nhập hoặc tương tự), bạn phải sử dụng các móc như before() để kiểm tra các điều kiện đó trước khi tiếp tục.

Bó kiểm tra phụ thuộc trong một khối và chạy một asyncbefore móc trên chúng (chú ý 'làm' ở trước khối):

var someCondition = false 

// ... your Async tests setting conditions go up here... 

describe('is dependent on someCondition', function(){ 

    // Polls `someCondition` every 1s 
    var check = function(done) { 
    if (someCondition) done(); 
    else setTimeout(function(){ check(done) }, 1000); 
    } 

    before(function(done){ 
    check(done); 
    }); 

    it('should get here ONLY once someCondition is true', function(){ 
    // Only gets here once `someCondition` is satisfied 
    }); 

}) 
+0

'someCondition' sẽ thay đổi như thế nào nếu cuộc gọi trước bị khóa trong một vòng lặp while ?! Đây không phải là cách JavaScript hoạt động. – natevw

+0

Câu trả lời cho câu hỏi của bạn nằm trong dòng chú thích 3: ".. điều kiện thiết lập kiểm tra Async của bạn sẽ xuất hiện tại đây". Cụ thể: Async, thiết lập các điều kiện, được đặt bên ngoài 'describe()' mà khởi tạo trước 'before()'. Xác nhận sau của bạn về Javascript không hoạt động theo cách này là sai. – papercowboy

+0

Trong khi mã của bạn bị kẹt liên tục kiểm tra! SomeCondition lặp đi lặp lại, không có mã nào khác của bạn có thể chạy. (Tất cả các callback khác kết hợp với các sự kiện/bộ đếm thời gian sẽ bị ngăn cản thực hiện.) Cách duy nhất này sẽ hoạt động là nếu someCondition được đặt đúng trước khi vòng lặp bắt đầu - nếu không nó sẽ bị treo. Thử nó. – natevw

7

Tôi ngạc nhiên bởi những gì bạn đã viết khi tôi sử dụng. Tôi sử dụng mocha với các bài kiểm tra kiểu bdd (mô tả/nó), và chỉ cần thêm một số console.logs để kiểm tra của tôi để xem nếu yêu cầu của bạn giữ với trường hợp của tôi, nhưng dường như họ không.

Đây là đoạn mã mà tôi đã sử dụng để xem thứ tự của "end1" và "start1". Chúng được đặt hàng đúng cách.

describe('Characters start a work', function(){ 
    before(function(){ 
     sinon.stub(statusapp, 'create_message'); 
    }); 
    after(function(){ 
     statusapp.create_message.restore(); 
    }); 
    it('creates the events and sends out a message', function(done){ 
     draftwork.start_job(function(err, work){ 
     statusapp.create_message.callCount.should.equal(1); 
     draftwork.get('events').length.should.equal(
      statusapp.module('jobs').Jobs.get(draftwork.get('job_id')).get('nbr_events') 
     ); 
     console.log('end1'); 
     done(); 
     }); 
    }); 
    it('triggers work:start event', function(done){ 
     console.log('start2'); 
     statusapp.app.bind('work:start', function(work){ 
     work.id.should.equal(draftwork.id); 
     statusapp.app.off('work:start'); 
     done(); 
     }); 

Tất nhiên, điều này có thể xảy ra do tai nạn, nhưng tôi có nhiều thử nghiệm và nếu chạy song song, tôi chắc chắn sẽ có điều kiện chủng tộc mà tôi không có.

Vui lòng tham khảo this issue quá từ trình theo dõi vấn đề mocha. Theo đó, các thử nghiệm được chạy đồng bộ.

+0

Điều này chỉ cho thấy mã đặt hàng được chạy theo thứ tự. Điều đó không xảy ra một cách tình cờ. Đó là cách nó hoạt động". – papercowboy

+0

Điều này cho thấy các kiểm tra async được sắp xếp chạy theo thứ tự: 'end1' sẽ luôn xảy ra trước' start2'. Để đơn giản hóa ví dụ, bạn có thể thay thế nội dung của bài kiểm tra đầu tiên bằng 'setTimeout (done, 1000)'.Và nếu bạn thay thế móc 'trước' bằng một cái không đồng bộ, nó sẽ luôn chạy trước lần kiểm tra đầu tiên. Theo tôi hiểu, đây chính xác là hành vi mà người khởi xướng chủ đề quan tâm và hành vi này là hành vi mặc định và hành vi duy nhất, ít nhất là bây giờ. – skozin

5

tôi muốn giải quyết vấn đề này cùng với ứng dụng của chúng tôi , nhưng accepted answer không hoạt động tốt cho chúng tôi. Đặc biệt là trong someCondition sẽ không bao giờ đúng.

Chúng tôi sử dụng các lời hứa trong ứng dụng của chúng tôi và những điều này giúp bạn dễ dàng cấu trúc các bài kiểm tra tương ứng. Tuy nhiên chìa khóa vẫn là để trì hoãn thực hiện thông qua việc móc before:

var assert = require("assert"); 

describe("Application", function() { 
    var application = require(__dirname + "/../app.js"); 
    var bootPromise = application.boot(); 

    describe("#boot()", function() { 
    it("should start without errors", function() { 
     return bootPromise; 
    }); 
    }); 

    describe("#shutdown()", function() { 
    before(function() { 
     return bootPromise; 
    }); 

    it("should be able to shut down cleanly", function() { 
     return application.shutdown(); 
    }); 
    }); 
}); 
+3

Tôi nên đặt các dòng mã thứ hai và thứ ba ('application = ...' và 'bootPromise = ...') vào trong khối 'before' không đồng bộ trong bộ cấp cao nhất ("Application"). Nếu không, bất kỳ ngoại lệ nào được ném từ mã này sẽ không bị phát hiện và báo cáo đúng cách và thậm chí tệ hơn sẽ ngăn không cho thực hiện tất cả các thử nghiệm còn lại. – skozin

4

sử dụng mocha-steps

nó giữ kiểm tra tuần tự không phân biệt nếu họ là async hay không (ví dụ: done chức năng của bạn vẫn hoạt động chính xác như họ đã làm). Đó là thay thế trực tiếp cho it và thay vào đó bạn sử dụng step

+0

tại sao điều này lại bị bỏ phiếu? –

+1

@JackMurphy câu hỏi hay. – WiR3D

+0

Tương tự. Tôi đã có cùng một vấn đề và điều này đã giúp tôi. – hrishioa

Các vấn đề liên quan