2009-02-02 149 views
9

我目前正在開發一個以動態方式生成SQL調用以供其他軟件使用的小型項目。 SQL調用事先不知道,因此我希望能夠對生成SQL的對象進行單元測試。如何測試代碼生成工具?

你有什麼線索可以做到這一點嗎?請記住,沒有辦法知道所有可能的SQL調用。

目前我唯一的想法是使用正則表達式從數據庫創建接受的SQL的測試用例,並確保SQL將編譯,但這並不能確保該調用返回預期的結果。

編輯:添加更多的信息:

我的項目是噓聲的擴展,將允許開發者用一組屬性標記他的財產。這些屬性用於確定開發人員如何將對象存儲在數據庫中。例如:

# This attribute tells the Boo compiler extension that you want to 
# store the object in a MySQL db. The boo compiler extension will make sure that you meet 
# the requirements 
[Storable(MySQL)] 
class MyObject(): 
    # Tells the compiler that name is the PK 
    [PrimaryKey(Size = 25)] 
    [Property(Name)] 
    private name as String 

    [TableColumn(Size = 25)] 
    [Property(Surname)] 
    private surname as String 

    [TableColumn()] 
    [Property(Age)] 
    private age as int 

好主意是生成的代碼不需要使用反射,但它會在編譯時添加到類中。是的,編譯將花費更長的時間,但根本不需要使用Reflection。我目前有代碼工作生成所需的方法,在編譯時返回SQL,它們被添加到對象,並可以調用,但我需要測試生成的SQL是否正確:P

回答

2

這看起來像雞蛋的情況。你不確定發生器會吐出什麼,你有一個移動的目標來測試(真正的數據庫)。所以你需要把鬆散的一端系下來。

創建一個小測試數據庫(例如使用HSQLDB或Derby)。這個數據庫應該使用與真實數據庫相同的功能,但不要複製!您將需要了解測試數據庫中的每件事情以及爲什麼它在那裏,所以花點時間想出一些合理的測試用例。針對這個(靜態)測試數據庫使用您的代碼生成器,將結果保存爲測試用例中的固定字符串。從一個功能開始。不要嘗試像第1步那樣構建完美的測試數據庫。你會到達那裏。

當您更改代碼生成器時,請運行測試。他們只應該在預期的地方打破。如果發現錯誤,請在測試數據庫中複製相關功能。創建一個新的測試,檢查結果。它看起來正確嗎?如果您能看到錯誤,請在測試中修復預期的輸出。之後,修復發生器,以便創建正確的結果。關閉錯誤並繼續。

這樣,您可以在沼澤中建立更多,更安全的地面。做一些你知道的事情,檢查它是否有效(忽略其他所有事情)。如果你滿意,繼續前進。不要試圖一次解決所有問題。一步一步來。測試不要忘記,所以可以忘記正在測試的所有內容,並專注於下一個功能。測試將確保您穩定的基礎不斷增長,直到您能夠在上面架設摩天大樓。

0

您沒有測試所有情況。進行示例調用的集合,確保包含儘可能多的難以處理的方面,然後查看生成的代碼是否正確。

0

我會有一套測試,把一個已知的輸入,並檢查生成的SQL是否如預期。

你永遠無法爲每個場景編寫一個測試,但如果你寫足夠覆蓋至少最常規的模式,你可以相當有信心你的發電機按預期工作。

如果您發現它在特定情況下無法正常工作,請爲該方案編寫另一個測試並進行修復。

1

正則表達式

我認爲,SQL的語法是不正規,但上下文;子表達是實現這一點的關鍵。您可能需要爲SQL編寫上下文無關語法分析器來檢查語法錯誤。

但問問自己:你想測試什麼?你的正確性標準是什麼?

3

單元測試的重點在於您知道將代碼結果與之比較的答案。您必須事先找到一種方法來了解SQL調用。

說實話,正如其他答覆者所建議的那樣,您的最佳方法是提出一些預期結果,並在單元測試中對其進行基本硬編碼。然後你可以運行你的代碼,獲得結果,並與硬編碼的期望值進行比較。

也許你可以記錄生成的實際SQL,而不是執行它並比較結果呢?

1

如果您正在生成代碼,爲什麼不生成測試?如果沒有單元測試(即讀取它,運行它和/或讓其他人檢查),就會以相同的方式測試/調試任何其他代碼,從而測試/調試生成的代碼。

+0

不幸的是,代碼不能被讀取,因爲它從來沒有被寫入,它在編譯時被添加到boo使用的解析tee中,因此它不能被讀取,因此讀取和獲取審查是不可能的:( – mandel 2009-02-02 12:10:59