2010-10-14 65 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

相关问题