客户要求对XML格式的测试结果进行统计,并发送出特定格式的邮件。
1. 测试结果有两种文件,一种是以xml为后缀的xml格式文件,一种是VS里跑测试用例产生的以trx为后缀的xml格式文件。
2. 每个文件里包含多个测试用例,每个测试用例有对应的Owner和归属类别Area。
3. 最后输出的报告格式如下:
Area |
File |
Owner |
Pass |
Fail |
Invalid |
Total |
A |
4 |
0 |
0 |
4 |
||
a.xml |
S |
1 |
0 |
0 |
1 |
|
b.xml |
S;K; |
3 |
0 |
0 |
3 |
|
B |
1 |
0 |
0 |
1 |
||
b.xml |
K; |
1 |
0 |
0 |
1 |
|
C |
1 |
2 |
0 |
3 |
||
2010-11-15 23_24_10.trx |
K; |
1 |
0 |
0 |
1 |
|
2010-11-16 19_55_45.trx |
K; |
0 |
1 |
0 |
1 |
|
2010-11-03 20_29_01.trx |
K; |
0 |
1 |
0 |
1 |
|
D |
1 |
0 |
0 |
1 |
||
2010-11-16 19_55_45.trx |
L; |
1 |
0 |
0 |
1 |
|
Overall |
- |
- |
7 |
2 |
0 |
9 |
整体思路是根据xml格式的测试结果产生xsd文件,进而使用xsd2code工具产生类文件,这样就可以使用Linq遍历对象,抽取统计结果,然后将其存储在报告对象中,通过序列化,产生测试报告的xml文件,在发送邮件时,结合xlst,输出给定格式的测试报告。
在实现过程中,对于不太熟悉这些技术的初学者,会碰到一些问题,下面就简单说一下。
1. 根据xml产生xsd文件
对于简单的xml文件,我们完全可以手写一个对应的xsd,但是有自动生成xsd的方法,大家肯定更愿意使用。
在VS中打开xml格式的文件,在菜单栏可以出现“XML”,点击“XML”,然后在弹出的快捷菜单中点击“Create Schema”,将创建好的xsd文件保存下来就可以了,很方便。
2. 使用xsd2code.exe将按xsd文件生成cs类文件
xsd2code是VS的一个插件,首先到http://xsd2code.codeplex.com/官方网站下载xsd2code安装包,然后安装到工作机上就可以了,安装成功后,在项目里,右击xsd文件,就可以看到“Run Xsd2Code generation”。
点击“Run Xsd2Code generation”,会弹出对话框,为了正常进行序列化和反序列化,我们需要对默认的值进行重新设置。
展开“PropertyParms”,将GenerateShouldSerializeProperty的值设为True;
展开“Serialization”,将Enabled的值设为True;将GenerateXmlAttribute得值设为True;
最后就可以点击“generate”了。接下来,我们就可以使用借助xsd文件,进行xml和类对象之间的序列化和反序列化喽。
3. 对于非标准的xml文件在反序列化时会失败,比如stack overflow
在实现中,发现xml文件格式并不规范,属于那种嵌套的格式(A嵌套B,B又嵌套A,且嵌套层次不确定),如下:
<A>
<B>
<A>
<B>
...
</B>
</A>
</B>
</A>
这样的xml产生的xsd需要手动调整,可以用引用的形式书写:
<xs:element name="B">
<xs:complexType>
<xs:sequence>
<xs:element ref="A" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="A">
<xs:complexType>
<xs:sequence>
<xs:element ref="B">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
由这个xsd产生的cs类文件的构造函数会相互构造导致堆栈溢出。
对于这种情况,不建议产生cs类文件,而是直接通过Linq去访问xml文件。
4. 对于trx文件的处理,可以自动产生cs类文件,但是需要获取testcase的TestArea自定义Attribute,需要从cs类文件中得到对应的testcase的dll文件,加载程序集,进而使用反射的方式得到该测试方法对应的Attribute。
加载程序集时,注意使用Assembly adaptorAssembly = Assembly.LoadFrom(fullpath); 而不是Assembly adaptorAssembly = Assembly.LoadFile(fullpath);
Type type = adaptorAssembly.GetType(className,true,true);
MethodInfo method = type.GetMethod(methodName);
foreach (object attribute in method.GetCustomAttributes(true))
{
if (attribute is TestAreaAttribute)
{
Console.WriteLine("Method=[{0}], Area=[{1}]", method.Name, ((TestAreaAttribute)attribute).AreaPath);
break;
}
}
5. 如果程序集是从远程共享路径加载的,则可能会遇到权限不足的问题
Could not load file or assembly 'XXXXX, Version=1.0.1.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Failed to grant minimum permission requests. (Exception from HRESULT: 0x80131417)
解决方法是使用UI或者命令行的形式赋予共享路径完全信任。
UI(.NET Framework Configuration Tool):限于.net framework 较低版本1.0,2.0 对于3.0,3.5,4.0之后的版本则取消了UI操作;
command line:注意区分系统是32位还是64位,这样可以确定是在C:\Windows\Microsoft.NET\Framework64\...还是C:\Windows\Microsoft.NET\Framework\...里去运行caspol.exe工具。
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\caspol.exe -m -ag 1 -url "file:////\\fs\share\*" FullTrust -exclusive on
C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\caspol.exe -m -ag 1 -url "file:////\\fs\share\*" FullTrust -exclusive on
6. 按既定格式设计要输出的xml和xlst
注意,xslt仅仅是更好的将数据显示出来,核心的东西还是取决于xml的内容,对于一个给定的xml,不要试图用xslt显示一个复杂的格式,这个一般不容易做到,最好的方法是调整xml的结构,比如对于这个测试报告的格式,我们产生的xml应该是下面的样子,才方便用xslt输出符合要求的格式。
<Report xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Item>
<AreaInfo>
<Area>
<Name>A</Name>
<Pass>4</Pass>
<Fail>0</Fail>
<Invalid>0</Invalid>
<Total>4</Total>
</Area>
<FileInfos>
<FileInfo>
<File>a.xml</File>
<Owner>S;</Owner>
<Pass>1</Pass>
<Fail>0</Fail>
<Invalid>0</Invalid>
<Total>1</Total>
</FileInfo>
<FileInfo>
...
</FileInfo>
</FileInfos>
</AreaInfo>
<AreaInfo>
<Area>
...
</Area>
<FileInfos>
<FileInfo>
...
</FileInfo>
</FileInfos>
</AreaInfo>
</Item>
<OverallCountsField>
<successCount>7</successCount>
<errorCount>2</errorCount>
<invalidcaseCount>0</invalidcaseCount>
<totalCount>9</totalCount>
</OverallCountsField>
</Report>