这几乎是我自动化测试的开始,所以如果我不能说清楚,我想道歉!
因此,在阅读了有关自动化的博客两周后,我决定将 NUNIT 与 Selenium Webdriver 一起用于UI自动化。
我的应用程序属于企业级别,已在开发中重建3年。它是一个项目和投资组合管理系统。
我有数百页,其中约50%执行 CRUD 操作。
我为我的申请决定了以下结构:
我使用以下格式的测试数据作为JSON,并将此数据检索到我的视图模型:
[
{
"Name": "Finance",
"Description": "division with complete test data",
"Color": "#ff0000",
"ExpectedStatus": {
"WillBeAdded": true,
"WillBeDeleted": true,
"WillBeUpdated": true
},
"PerformableActions": {
"ShouldAdd": true,
"ShouldDelete": false,
"ShouldUpdate": true
}
},
{
"Name": "IT",
"Description": "IT projects",
"Color": "pink",
"ExpectedStatus": {
"WillBeAdded": true,
"WillBeDeleted": true,
"WillBeUpdated": true
},
"PerformableActions": {
"ShouldAdd": true,
"ShouldDelete": false,
"ShouldUpdate": true
}
},
{
"Name": "Business",
"Description": "division with name and color name",
"Color": "yellow",
"ExpectedStatus": {
"WillBeAdded": true,
"WillBeDeleted": true,
"WillBeUpdated": true
},
"PerformableActions": {
"ShouldAdd": true,
"ShouldDelete": false,
"ShouldUpdate": true
}
},
{
"Name": "",
"Description": "division without name and color name, should add white color",
"Color": "",
"ExpectedStatus": {
"WillBeAdded": true,
"WillBeDeleted": true,
"WillBeUpdated": true
},
"PerformableActions": {
"ShouldAdd": true,
"ShouldDelete": true,
"ShouldUpdate": true
}
},
{
"Name": "",
"Description": "without name and color name and will not be added",
"Color": "black",
"ExpectedStatus": {
"WillBeAdded": false,
"WillBeDeleted": false,
"WillBeUpdated": false
},
"PerformableActions": {
"ShouldAdd": true,
"ShouldDelete": false,
"ShouldUpdate": false
}
}
]
我在这里使用两件事:
1。 PerformableActions ,即使用此测试用例数据可以执行哪些操作。 E.g shouldAdd表示应该执行此TestCase以添加记录,shouldDelete表示应该运行此testCase以删除记录,类似于shouldUpdate运行。
2。 ExpectedStatus ,即测试用例的预期结果, WillBeAdded意味着将这些数据添加到网格中。同样,WillBeDeleted和WillBeUpdated工作。
问题:
1)我对所有 CUD 操作使用相同的测试数据,原因是我必须在我的应用程序中维护CUD流程。因为只需要测试UI所以我只是假设创建,检索和删除将按顺序工作。
这是在CRUD操作情况下进行测试的正确方法吗?
2)认为我必须在我的项目中运行所有测试,它可能数百或数千,我如何维护订单,因为我可以看到唯一可行的方法是使用< NUNit 中的strong>订单属性。我如何使用它或者是否有任何替代方案单独测试独立模块和相关模块组?
答案 0 :(得分:1)
wait
来让后端做它有事业的东西。我知道,您使用C#
标记了您的问题,但是对于这项工作量,可能值得查看一些其他库而不是您现在的库。如果你不怕学习很少,你可以享受F#:
UPDATE :对于排序,您可以定义自己的属性,甚至可以使用NUnit中的现有属性,并按正确的顺序调用每次反射的方法。或者您为测试定义自己的DSL并遍历列表并提取所需的信息。
public struct CRUD
{
public bool C;
public bool R;
public bool U;
public bool D;
public CRUD(bool c, bool r, bool u, bool d)
{
this.C = c;
this.R = r;
this.U = u;
this.D = d;
}
}
public enum ActionKind
{
Create,
Read,
Update,
Delete
}
public struct TestResult
{
public ActionKind Action;
public bool IsPerformed;
}
public class TestCase
{
public string Name { get; set; }
public string Description { get; set; }
public string Color { get; set; }
public CRUD Action { get; set; }
public List<TestResult> Actual { get; set; }
public List<TestResult> Expected { get; set; } // or List<TestResult>
}
public class Tests
{
public void TestAListOfCases()
{
var cases = new List<TestCase>
{
new TestCase { Name = "Finance", Description = "division with complete test data", Color = "#ff0000",
Expected = new List<TestResult> {new TestResult {Action = ActionKind.Create, IsPerformed = true },
new TestResult {Action = ActionKind.Update, IsPerformed = false},
new TestResult {Action = ActionKind.Delete, IsPerformed = true }
}},
new TestCase { Name = "IT", Description = "Description"}
};
cases
.Where(x => x.Name == "IT")
.Where(x => x.Color != "pink")
.Select(RunTestCase)
.Where(x => !x.Item2)
.Select(x => OutputFailedTestCase(x.Item1)); // boah c# is verbose
}
public Tuple<TestCase, bool> RunTestCase(TestCase testCase)
{
foreach(var exp in testCase.Expected)
{
switch (exp.Action) {
case ActionKind.Delete:
// do delete if needed and create actual result
var actual = exp.IsPerformed
? new TestResult { Action = exp.Action, IsPerformed = true }
: new TestResult { Action = exp.Action, IsPerformed = false };
break;
}
}
var isFailed =
Enumerable.Zip(
testCase.Actual,
testCase.Expected,
(expected, actual) => expected.Action == actual.Action && expected.IsPerformed == actual.IsPerformed)
.All(x=>x);
// your selenium stuff
return Tuple.Create(testCase, isFailed);
}
public bool OutputFailedTestCase(TestCase testCase)
{
// write to console or do something else
Console.Write($"{testCase.Name} is failed to perform following actions: {calculateFailedActions}");
return true;
}
}