2010-10-14 23 views
0

我有一個測試腳本,它對一個對象執行某些操作,然後對第二個對象執行相同的操作。這持續了很長時間。有了這麼多的可預測的重複,自動化似乎已經成熟,但我不知道如何。我不會在乎這麼多,除非有這麼多的重複,使用錯誤的變量很容易忽略(例如:prodXyz意圖時的stagingXyz)。在2個對象上運行相同的代碼

下面的細節是不相關的。重要的是這種模式。

var stagingDbs = cleanupDbs(stagingServer.Databases); 
var prodDbs = cleanupDbs(prodServer.Databases); 

printDiff(stagingDbs, prodDbs, "Databases mis-matched"); 

foreach (var db in stagingDbs.Intersect(prodDbs)) { 
    var stagingDb = stagingServer.Databases[db]; 
    var prodDb = prodServer.Databases[db]; 

    var stagingTables = cleanupTables(stagingDb.Tables); 
    var prodTables = cleanupTables(prodDb.Tables); 

    printDiff(stagingTables, prodTables, "Tables mis-matched on " + db); 

    foreach (var table in stagingTables.Intersect(prodTables)) { 
     var stagingTable = stagingDb.Tables[table]; 
     var prodTable = prodDb.Tables[table]; 

     var matchedColumns = stagingColumns.Intersect(prodColumns); 

     var stagingTableColumns = stagingTable.Columns 
      .Cast<Column>() 
      .Where(c => matchedColumns.Contains(c.Name)) 
      .Select(c => formatColumn(c)); 
     var prodTableColumns = prodTable.Columns 
      .Cast<Column>() 
      .Where(c => matchedColumns.Contains(c.Name)) 
      .Select(c => formatColumn(c)); 
     printDiff(stagingTableColumns, prodTableColumns, 
      "Columns mis-matched"); 
    } 
} 

我不想去通過,例如,用這種

 var stagingTableColumns = doStuff(stagingTable, matchedColumns); 
     var prodTableColumns = doStuff(prodTable, matchedColumns); 

更換此

 var stagingTableColumns = stagingTable.Columns 
      .Cast<Column>() 
      .Where(c => matchedColumns.Contains(c.Name)) 
      .Select(c => formatColumn(c)); 
     var prodTableColumns = prodTable.Columns 
      .Cast<Column>() 
      .Where(c => matchedColumns.Contains(c.Name)) 
      .Select(c => formatColumn(c)); 

因爲我必須確保一切都在第一線stagingXyz,第二行是prodXyz。對於1行來說並不是那麼糟糕,但是測試腳本非常龐大,並且只有這兩件事中的一個:

  • foo(stagingXyz); FOO(prodXyz);
  • bar(stagingXyz,prodXyz);

類似地,在一個陣列這些物品包裝和具有doStuff[0]; doStuff[1];是經受相同的易錯字錯誤只以0對1筆誤將更加努力一目瞭然發現。

我想過要製作2個容器對象(一個用於分級,一個用於產品),並將這兩個對象放在一個集合中,但是我擔心這會導致一個很難維護的極小的循環。

無論如何要簡化這一點,仍然有它可讀性和可維護性?

回答

0

你能生成你的測試腳本嗎?輸入可能會讀像

var %%AB%%Dbs = cleanupDbs(%%AB%%Server.Databases); 
printDiff(%%A%%Dbs, %%B%%Dbs, "Databases mis-matched"); 
foreach (var db in %%A%%Dbs.Intersect(%%B%%Dbs)) { 

    var %%AB%%Db = %%AB%%Server.Databases[db]; 
    var %%AB%%Tables = cleanupTables(%%AB%%Db.Tables); 

    printDiff(%%A%%Tables, %%B%%Tables, "Tables mis-matched on " + db); 

    ... 
} 

含%% AB %%行可能會擴大到同一行的兩個副本,一個用「A」代替,一個與「B」替代,其中%% %%或%% B %%本身可能會被替換。

0

編輯 - 閱讀您的評論後,我發現現在的問題更加清晰。我認爲問題更多的是一個大功能的清晰度,並提出了一種解決可讀性問題的時髦方法。我認爲你把它分解成更小的函數越多,它就越清晰。

如果主要功能是分解成這樣的:

public void mainMethod(DB prodDB, DB stagingDB) 
{ 
    doPart1(prodDB, stagingDB); 
    doPart2(prodDB, stagingDB); 
} 

...並且每個部分都很好命名,像這樣輸入:

public void doPart1(DB prodDB, DB stagingDB) 
{ 
    // Code...  
} 

事情就清楚自己當作你使事情的工作更加細化。任何在doPart1方法中工作的人只需要關注少量的代碼,而在主要部分工作的任何人都不應該有一百萬件事情要查看。我明白,如果這聽起來像是一個過於簡單的迴應,但它聽起來像你正試圖解決一個問題,如果代碼被正確分解不應該存在。

如果有一種方法如此龐大且難以理解,以至於其他開發人員無法弄清楚只有兩個變量會發生什麼情況,那麼就會出現不同的問題。

+0

我認爲它沒有以這種方式構建的原因已經是因爲他需要在這對對象上執行增量操作,而不是對所有對象執行所有操作。 – twon33 2010-10-14 19:30:47

+0

它聽起來像你的建議將運行obj1然後一切obj2。這不會與原始示例中的效果相同;最顯着的是在循環內部。 – Dinah 2010-10-14 19:33:39

+0

編輯爲了更好地反映問題。 – Ocelot20 2010-10-14 19:47:28

相關問題