8.6 把测试结果存储在内存中
问题
如何把测试结果存储在内存中,从而可以在运行一个新的测试用例之前方便地判断某个特定的测试用例通过与否。
设计
如果测试用例之间存在依赖关系,也就是说某个测试用例的运行情况取决于它前面测试用例的运行结果,那就可以考虑把测试结果保存到一个Hashtable对象里。对于测试结果进行一般性的处理,使用ArrayList通常是最好的选择。
方案
要把某个测试结果插入Hashtable,可以使用下面的代码:
TestResult tr = null;
if (actualResult == expectedResult)
{
tr = new TestResult(id, "Pass");
testResults.Add(id, tr);
}
else
{
tr = new TestResult(id, "FAIL");
testResults.Add(id, tr);
}
以及:
static Hashtable testResults = new Hashtable();
class TestResult
{
public string id;
public string pf; // "pass" 或 "fail"
public TestResult(string id, string pf)
{
this.id = id; this.pf = pf;
}
}
每个测试用例的运行结果都被保存到了一个Hashtable里。假如现在所有的测试用例都需要测试用例002运行通过。我们可以编写像下面这样的代码:
string mustPass = "002";
TestResult tr = testResults[mustPass] as TestResult;
if (tr.pf == "Pass")
{
Console.WriteLine("The dependency passed so I can run case " + id);
// 运行测试并保存结果
}
else
{
Console.WriteLine("The dependency failed so I will skip case " + id);
continue;
}
有时候,某些测试用例会依赖于其他的测试用例,也就是说某个测试用例是否运行取决于它前面的某个测试用例能否通过。对于这种情况,应该把测试结果保存在内存中。在每个测试用例被执行之前,必须对这些数据进行查找。即使测试用例的数量不是非常的大,也需要一个能够尽可能快地进行查找操作的数据结构。Hashtable对象正是为这种情况而设计的。
注解
处理测试用例依赖于其他测试用例结果的情况,从原理上来说是很简单的,但是实际中有可能会很棘手。Hashtable对象接受一个键值(你可以把它想象成一个ID)以及要存储的对象。对于测试用例结果,测试用例ID很自然地就可以作为一个键值。因为Hashtable存储的是对象,好一点的做法是写一个轻量级的类来保存测试结果信息,这样你就可以在调用Hashtable.Add()方法的时候传入一个TestResult对象作为要添加的值。
如果测试用例之间的依赖个数不是很多,你可以把依赖关系硬编码到自动化测试套件中。但是,如果测试用例之间的依赖个数很多,你应该首先重新审视一下整个测试套件,看看能否对其进行简化。如果这些依赖关系是不可避免的,则应该把这些依赖关系作为测试用例输入数据的一部分来保存。这进一步使得我们需要把测试用例数据保存到一个轻量级的类里面,比如:
class TestCase
{
public string id;
public string input;
public string expected;
public ArrayList dependencies;
public TestCase(string id, string input, string expected,
ArrayList dependencies)
{
// 构造函数代码
}
}
然后可以像下面这样(以伪代码的形式)组织测试套件:
loop thru test case collection
fetch a TestCase object
bool shouldRun = true;
loop thru each dependency
{
pull dependency result from Hashtable
if (dependency case failed)
shouldRun = false;
break;
}
if (shouldRun == true)
{
run test;
store test result;
}
else
{
skip test;
}
end loop
当使用Hashtable对象作为内存中的数据仓储时,有时候会需要显示测试结果或者把它们保存到外部存储。有好几种方法可以做这件事情。其中一种方法是,维护两个不同的数据结构——一个Hashtable用于判断测试用例之间的依赖关系,和一个ArrayList保存测试用例结果用于显示或外部存储。这很简单,但是不够高效。第二种方法是,把测试结果保存在Hashtable里,当用于测试处理的主循环结果之后,遍历Hashtable并且把测试结果保存到外部存储。例如:
Hashtable testResults = new Hashtable();
// 运行测试套件,把全部测试结果存储到testResults
FileStream fs = new FileStream("TestResults.txt", FileMode.Create);
StreamWriter sw = new StreamWriter(fs);
foreach (DictionaryEntry de in testResults)
{
TestResult t = de.Value as TestResult;
sw.WriteLine(t.id + " " + t.pf);
}
sw.Close();
fs.Close();
因为Hashtable对象里的每个元素都是一个DictionaryEntry对象,因此可以通过这种不那么显而易见的方式遍历这个Hashtable。







