可使用Microsoft.VisualStudio.TestTools.UnitTesting自带的attribute管理,即:
[TestMethod()]
[Owner("applewu"), Priority(1), TestCategory("Functional"), TestCategory("Negative")]
[Description("Add User No Cache No Encryption Test")]
public void AddUserNoCacheNoEncryptionTest()
{
Trace.TraceInformation("UserServiceTest:AddUserNoCacheNoEncryptionTest - BEGIN");
…… ……
Trace.TraceInformation("UserServiceTest: AddUserNoCacheNoEncryptionTest - END");
}
对于Owner项,可以规定填写个人在公司的Alias;而TestCategory是最容易出问题的,有人会写成Functional,有人可能笔误写成Functionl。
我们之所以使用Test attribute,不仅仅是可以在[测试视图]和[测试列表编辑器]中根据Owner,Priority,Category参数对测试用例进行过滤,简单明了;更重要的是,我们经常要使用mstest命令行的方式执行用例,如果某个同事把一些case的category误写成Functionl,那就会在mstest批量执行测试的时候,造成遗漏。这便引出了第二则:
第二则:推荐用枚举定义Test Category
using Test.Common;
public enum TestTypes
{
/// <summary>
/// Acceptance Tests
/// </summary>
Acceptance = 1,
/// <summary>
/// Sunny day scenarios
/// </summary>
Scenario = 2,
/// <summary>
/// Full Functional / Complete(Non-Sunny day scenarios)
/// </summary>
Functional = 3,
/// <summary>
/// Stress test
/// </summary>
Stress = 4,
}
这样,在定义测试类型的时候,就不是“Functional”这个字符串,而是TestTypes.Functional. 这正是利用编程工具自动补全的功能,来避免Test Method因为手误而被Miss掉。
第三则:使用Trace -System.Diagnostics.Trace
一旦自动化测试建立起来,就要经常性地跑Case。我们只关注最后的Test Result,即trx文件。
导致自动化测试代码Fail的原因有很多,对于Failed的Test Method,我们要逐一排查,所以测试代码中有很多Log操作。之前的做法是,我写一个Log类供大家调用,可以写到txt文件,也可以截屏。但是过多地对硬盘进行IO操作毕竟影响效率。我觉得更好的选择是用System.Diagnostics.Trace类,在查看Test Result Details时就可以看到Stack Trace的内容。
第四则:定义测试用例的运行环境
对于自动化的Cases,我认为,进行数据驱动倒是其次,可是一定要有配置文件,用来设置当前的测试环境地址。
所谓的Daily Build Dev环境和Test环境一定要分开。
可以采用EnvironmentConfiguration.xml+TestConfig.txt的方式。把所有环境的信息都在EnvironmentConfiguration.xml中定义好,一般有访问地址,证书信息,数据连接字符串等;而TestConfig.txt只有环境的名称。
EnvironmentConfiguration.xml-
TestConfig.txt- 我们要在程序中实现,取第一个envname的值作为当前的测试环境
第五则:清理测试数据
有人习惯在Test Method方法中清除测试数据,但我建议在ClassCleanUp和TestCleanUp中进行测试数据的删除动作。
原因在于,如果Remove动作发生了异常,CleanUp是不会影响Test最终的Pass/Fail结果;但是在Test Method中删除数据时,如果出错了,即便我们所测的Feature是OK的,但Test Result仍会显示Fail,而这,并不是我们期望的。
我一般的做法是,把数据存到一个类静态List变量中,待Class结束后,统一删除。
[ClassCleanup]
public static void CleanUp()
{
try
{
foreach (var user in TestUsers)
{
if(UserHelper.GetUser(user)!= null)
UserHelper.RemoveUser(user);
}
}
catch (Exception)
{
throw;
}
}