2017-06-17 104 views
0

以及前指定我的問題,我想告訴大家,我是新來測試領域,所以這裏是我的問題:測試涉及數據庫

我開發利用快遞+ sequelize(MySQL的)一個REST API,我想爲我的api寫一些測試。我選擇使用茉莉花庫進行測試。

所以我知道我想測試createupdate其餘端點,我需要訪問數據庫,但問題是測試用例並行運行,並且只有一個數據庫,所以如果我想要要從測試用例中的表中刪除所有項目,並且另一個測試用例在該表中創建了一行,則會出現問題。

const request = require('superagent'); 

const models = require('../../src/models'); 
const Station = models.Station; 

describe("station testing", function() { 


    before(() => { 
     // delete and recreate all database table 
     // before running any test 
    }); 


    describe("crud station", function() { 
     it('should create model',() => { 

      Station.create({ 
       'name': 'test', 
       lat: 12, 
       long: 123, 
      }).then(model => { 
       expect(model).toBeTruthy(); 
      }); 

     }); 

      it('should delete evrything',() => { 


      Station.deleteAll().then(() => { 

       // problem here if after the first model is created and before create model except is executed 
       expect(Station.Count()).toEqual(0); 
      } 


     }); 

    }); 



}); 
+0

另一個可能對你更好的測試框架是pyresttest。您只需定義您期望的請求和響應,然後就可以檢查它。 – HSchmale

+0

@ HSchmale謝謝你的提議,但我想學習如何在通用測試中,所以我需要解決這個問題。 – karim

回答

1

你的問題是你沒有在這裏編寫單元測試。

您需要了解單元測試的最重要的規則 - 唯一的測試一個單位在同一時間。一個單位可以被認爲是你的代碼的一個區域。在傳統的桌面項目(Java,C#等)中,一個單元將是一個類。在Javascript的情況下,一個單元很難定義,但它肯定會只有包含Javacript。如果您在測試中包含任何服務器代碼(例如數據庫),那麼您不是單元測試,而是在進行集成測試(這也非常重要,但要困難得多)。

您的Javascript將具有依賴關係(即它調用的其他代碼,通過Ajax調用),在您的情況下將包含被調用的服務器代碼。爲了進行單元測試,您需要確保您只是測試Javascript,這意味着在運行測試時,您不希望服務器代碼被調用。這樣,您可以隔離代碼單元中的任何錯誤,並且可以確信發現的任何問題確實在該單元中。如果你包括其他單位,那麼它可能是其他單位有問題。

在強類型語言(如Java,C#等)中,有框架允許您爲每個依賴項設置模擬。雖然我沒有嘗試過自己(這是本週的工作),但有mocking frameworks for Javascript,你可能需要使用其中一個來做真正的單元測試。你嘲笑了服務器代碼,所以當你運行測試時,它實際上並沒有打到數據庫。除了解決您的問題外,它還可以避免一些其他問題,您可能會在目前的方法中遇到一些問題。

如果您不想使用模擬框架,另一種方法是更改​​您的Javascript,以便您正在測試的函數帶有一個額外的參數,這是一個實際服務器調用的函數。所以,與其...

deleteCustomer(42); 

deleteCustomer(id) { 
    validate(id); 
    $.ajax(...); 
} 

...您的代碼應該是這樣的......

deleteCustomer(42, callServer); 

deleteCustomer(id, serverCall) { 
    validate(id); 
    serverCall(id); 
} 

...其中serverCall()包含Ajax調用。

然後,進行單元測試,你將測試這樣的事情...

deleteCustomer(42, function(){}); 

...,這樣,而不是調用服務器,沒有什麼實際完成的。

這顯然需要重寫一下你的代碼,這可以通過嘲笑來避免,但是會起作用。我的建議是花一些時間學習如何使用模擬框架。它將長期得到回報。

對不起,這已經有點長了。不幸的是,你正在進入一個複雜的單元測試領域,瞭解你在做什麼很重要。我強烈建議你在進一步學習之前閱讀單元測試,因爲對基礎知識的深入理解將在以後爲您節省很多麻煩。 Robert Martin(即Bob叔叔)關於此主題的任何內容都會很好,但網絡上有大量資源。

希望這會有所幫助。如果您需要更多信息或澄清,請離開。

+0

謝謝你對這個細節的解釋:),我只是想知道是否有一個很好的測試教科書。 – karim

+0

@karim周圍有很多好書。我不能推薦任何具體的東西,因爲我通過閱讀Bob博士的文章瞭解了我的大部分知識,並在其他文章中尋找。關於YouTube上的這個主題有很多視頻,所以可能值得關注一些視頻。 –

+0

@ karim忘記提及,如果您對任何強類型的面嚮對象語言感到滿意,那麼首先應該對其中一個進行TDD研究。您會發現比嘗試使用Javascript更容易。 –

1

Jasmine支持beforeEach函數,它在describe塊中的每個spec之前運行。 你可以使用它。

describe("A spec using beforeEach and afterEach", function() { 
    var foo = 0; 
    beforeEach(function() { foo += 1; }); 
    afterEach(function() { foo = 0; }); 
    it("is just a function, so it can contain any code", function() { 
    expect(foo).toEqual(1); 
    }); 
    it("can have more than one expectation", function() { 
    expect(foo).toEqual(1) 
    expect(true).toEqual(true); 
    }); 
}); 

因此,你可以讓beforeEach照顧刪除操作。