NetCase - 使用 .NET 中的元数据编程实现自动化测试用例 API






3.53/5 (6投票s)
2005年5月29日
3分钟阅读

31086

233
NetCase 是一个用于 .NET 中测试用例自动化的 API。
引言
本文通过一个名为 NetCase
的自动化测试 API 向新手介绍 Microsoft .NET 中的元数据编程。 尽管有很多类似的测试自动化资源(可能更高级),但这仍然是一个非常简单的测试 API,是我为了尝试 .NET 中的元数据编程而开发的。
元数据编程
元数据是指关于数据的数据,因此它是实际数据的两层间接。在现代编程语言(如 .NET 语言)中,元数据可用于获取有关编程语言实体(如类、方法等)的信息,然后检索此信息并对代码执行一些有用的操作。 Microsoft .NET framework SDK 包含 System.Reflection
命名空间,其中包含用于处理元数据的有用类。
NetCase 简介
NetCase 是我为在 .NET 中制作的测试自动化 API 起的名字,用于测试我编写的代码。 它类似于 Java 中的 JUnit 和 .NET 中的 NUnit。 我创建它纯粹是为了测试我在 .NET 中的元数据编程能力。 因此,可以为软件编写测试用例,并使用 NetCase 执行这些测试用例并查看结果。
编写 NetCase 测试用例
为了在 NetCase 中编写测试用例,必须从 NetCase.TestCase
类派生一个类。 TestCase
类具有以下方法
初始化
此方法在执行每个测试用例之前调用。
最终化
此方法在执行每个测试用例之后调用。
断言(Assert)
断言一个布尔条件。
可以看出,可以重写 Initialize
以在运行每个测试用例之前提供初始化代码,并且可以重写 Finalize
以提供清理代码。 可以在每个测试用例结束时测试断言条件以确定测试结果。 如果断言失败,则会抛出 TestFailedException
类型的异常。 以下是一个简单的测试用例方法示例,用于测试两个数字的二进制运算加法
[TestCase]
public void Addition()
{
A = 2;
B = 3;
Assert((A+B) == 5, true);
}
可以看出,测试用例方法用属性 [TestCase]
标记。 这有助于 NetCase 区分普通方法和测试用例方法。 这是一个简单的元数据示例。 测试用例也可以是负面的,例如
[TestCase(false)]
public void Division()
{
A = 10;
B = 1;
Assert(float.IsInfinity(A/B), true);
}
负面测试用例将 false
值传递给 [TestCase]
属性(默认情况下,测试用例是正面的)。 一旦从 NetCase.TestCase
类派生了一个类,就可以将其传递给 NetCase.TestCaseSuite
类的 RunTestCase
方法以执行。 RunTestCase
是一个静态方法,它执行包含在 TestCase
派生类中的测试用例,并返回 ClassTestResult
类型的对象。 以下是 ClassTestResult
结构的定义
public struct ClassTestResult
{
public TestResult [] SuccessfulTests;
public TestResult [] UnSuccessfulTests;
}
因此,调用者可以获取有关测试结果的信息。 请注意,负面测试用例的失败被认为是成功。 目前,我正在添加一个 Microsoft Visual Studio .NET 插件来显示测试结果,我将在完成后立即更新项目文件。
那么元数据编程在哪里呢?
NetCase.TestCaseSuite
类的 RunTestCase
方法的源代码包含用于处理测试方法的元数据代码。 该代码检查测试方法的正确格式并执行它们。
public static ClassTestResult RunTestCase(TestCase Case)
{
// Perform Sanity
if (Case == null)
{
throw new NullReferenceException();
}
// Initialize The Case
Case.Initialize();
Type CaseType = Case.GetType();
ClassTestResult Result = new ClassTestResult();
ArrayList SuccessfulTests = new ArrayList();
ArrayList UnSuccessfulTests = new ArrayList();
// Execute All Methods Marked As Test Cases
foreach (MethodInfo Info in CaseType.GetMethods())
{
// Check If The Method Has TestCaseAttribute
// If So Execute It
foreach (Attribute Attr in Attribute.GetCustomAttributes(Info))
{
if (Attr.GetType() == typeof(TestCaseAttribute))
{
try
{
if ((Info.GetParameters().Length != 0)||
(Info.ReturnType != typeof(void))||
(!Info.IsPublic))
{
break;
}
// Positive Test Case
if (!((TestCaseAttribute)Attr).IsNegativeCase)
{
Info.Invoke(Case, null);
SuccessfulTests.Add(new TestResult(Info,true,false,null));
}
else
{
// Negative Test Case
try
{
Info.Invoke(Case, null);
}
catch (TargetInvocationException e)
{
// Test Case Threw Any Other Exception
// Than TestFailedException
if (e.InnerException.GetType() !=
typeof(TestFailedException))
{
UnSuccessfulTests.Add(new TestResult(Info,
false,true,e.InnerException));
}
else
{
SuccessfulTests.Add(new TestResult(Info,
true,true,e.InnerException));
}
// Test Failed As Expected
continue;
}
// Negative Test Case Passed !
UnSuccessfulTests.Add(new TestResult(Info, false,
true, new TestFailedException()));
}
}
catch (System.Reflection.TargetInvocationException e)
{
if (e.InnerException != null)
{
UnSuccessfulTests.Add(new TestResult(Info,false,
false,e.InnerException));
}
else
{
UnSuccessfulTests.Add(new TestResult(Info,false,false,e));
}
}
}
}
if (SuccessfulTests.Count > 0)
{
Result.SuccessfulTests = (TestResult[])
SuccessfulTests.ToArray(SuccessfulTests[0].GetType());
}
if (UnSuccessfulTests.Count > 0)
{
Result.UnSuccessfulTests = (TestResult[])
UnSuccessfulTests.ToArray(UnSuccessfulTests[0].GetType());
}
}
return Result;
}
暂时就这样! 在接下来的项目中,我将添加一个 Visual Studio .NET 加载项,它将显示一个带有测试进度和结果的工具栏。