我正在编写将执行一系列测试步骤的代码,这些测试步骤将与测试用例中手动捕获的测试步骤一致,这是一个示例:
上面的屏幕截图显示了示例测试用例的3个步骤(使用Microsoft Test Manager查看)。
请记住,这是一个原始的例子,简化了这个问题,实际上有50个测试步骤和更复杂的场景并不罕见,我也省略了清理以及下面函数中的输入代码。
现在运行它的代码看起来像这样:(注意try / catch机制,允许测试在特定步骤失败):
[TestMethod]
public void LinksPageOpensFromClick()
{
int step = 0;
try
{
step++;
// Code to Open the page
}
catch (Exception ex )
{
Assert.Fail(AppManager.RaiseError(step, "Open the page", ex));
}
try
{
step++;
// Code to Click links button
}
catch (Exception ex)
{
Assert.Fail(AppManager.RaiseError(step, "Click links button", ex));
}
try
{
step++;
// Code to Assert links page opened
}
catch (Exception ex)
{
Assert.Fail(AppManager.RaiseError(step, "Assert links page opened ", ex));
}
}
首先观察的是,我过去只是硬编码这样的步骤值:
Assert.Fail(AppManager.RaiseError(3, "Assert links page opened ", ex));
但这意味着如果测试稍后更改,并且添加或重新排序测试步骤,则意味着手动更改大量步骤。
将步骤作为递增变量也不是理想的,首先它不是很优雅,如果你忘记增加步数,它就太容易出错了。此外,您无法对代码进行模式扫描,看看您在不添加其他评论的情况下执行了哪些步骤。
我真正想要的是这样的解决方案:
[StepDesc="Assert links page opened"]
Step
{
// Code to exec
}
Error (Exception ex)
{
Assert.Fail(AppManager.RaiseError(Step.Count, Step.Desc, ex));
}
如果失败了,可以更简洁地增加步数或使其更加动态而无需手动递增。
提前致谢。
编辑:如果C#无法解决这个问题,也许我可以将所有面向前面的测试用例放在另一个可能不是C#但符合MSIL的项目中?答案 0 :(得分:4)
这显然需要循环,例如:
class Step
{
public string Name { get; set; }
public Action Action { get; set; }
}
var steps = new []
{
new Step() { Name = "Open the page", Action = OpenThePageStep },
new Step() { Name = "Click links button", Action = ClickLinksBtnStep },
...
};
...
var id = 0; // or the Step class itself should have an id?
foreach (var step in steps)
{
try
{
id++;
step.Action();
}
catch (Exception ex)
{
Assert.Fail(AppManager.RaiseError(id, step.Name, ex));
}
}
答案 1 :(得分:2)
如果步骤是手动实现的(并且不是例如从正式描述中自动生成,在这种情况下定义Step
类的Groo's solution确实更好),这可能是我如何做到的,因为它似乎是最简单的方法,至少如果每一步的代码都很简单,我也发现它更具可读性:
public class Stepper
{
private int StepNumber { get; set; }
public void Step(string description, Action code)
{
StepNumber++;
try
{
code();
}
catch (Exception ex)
{
Assert.Fail(AppManager.RaiseError(StepNumber, description, ex));
}
}
}
然后您的测试代码如下所示:
var stepper = new Stepper();
stepper.Step("Open the page", () => { /* code to open the page */ });
stepper.Step("Click links button", () => { /* code to click links button */ });
// etc.
对您而言可能或可能不感兴趣的一件事是,您可以相当轻松地实现创建嵌套步骤的方法,例如:
之类的东西var stepper = new Stepper();
stepper.Step("Foo the bar", () => { /* ... */ });
using (var substep = stepper.SubStep("baz all the quuxs"))
{
substep.Step("baz the first quux", () => { /* ... */ });
substep.Step("baz the second quux", () => { /* ... */ });
}
stepper.Step("cleanup", () => { /* ... */ });