C# 每个属性都应该执行 TestMethod
C# each attribute should execute the TestMethod
我创建了一个名为 RoleAttribute
:
的自定义 xUnit 理论测试 DataAttribute
public class RoleAttribute : DataAttribute
{
public Role Role { get; set; }
public RoleAttribute(Role role, Action<Role> method)
{
Role = role;
AuthRepository.Login(role);
method(role);
}
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{
return new[] { new object[] { Role } };
}
}
我有测试方法OpenProfilePageTest
:
public class ProfileTest : AuthTest
{
[Theory, Priority(0)]
[Role(Enums.Role.SuperUser, OpenProfilePageTest)]
[Role(Enums.Role.Editor, OpenProfilePageTest)]
public void OpenProfilePageTest(Enums.Role role)
{
var profile = GetPage<ProfilePage>();
profile.GoTo();
profile.IsAt();
}
}
我想要的是它首先执行的每个角色(属性):
AuthRepository.Login(role);
(RoleAttribute
的构造函数)
然后继续 OpenProfilePageTest()
方法中的代码。在它重复相同但第二个属性之前。
我怎样才能做到这一点,现在我正试图通过在属性内部传递 OpenProfilePageTest()
方法并在其构造函数中执行它来实现这一点。一定有比绕过我相信的方法更好的方法来完成这个?
不通过方法也可以实现,需要稍微修改一下属性。我更改了属性以获取您要测试的所有角色,并在数据中 return 它们。这是一个例子
public class RolesAttribute : DataAttribute
{
private Role[] _roles;
public RolesAttribute(params Role[] roles)
{
_roles = roles;
}
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{
var data = new List<object[]>();
//We need to add each role param to the list of object[] params
//This will call the method for each role
foreach(var role in _roles)
data.Add(new object[]{role});
return data;
}
}
然后在你的测试中,你只需像这样在一个属性中传递所有你想测试的角色
public class ProfileTest : AuthTest
{
[Theory, Priority(0)]
[Roles(Enums.Role.SuperUser, Enums.Role.Editor)]
public void OpenProfilePageTest(Enums.Role role)
{
AuthRepository.Login(role);
var profile = GetPage<ProfilePage>();
profile.GoTo();
profile.IsAt();
}
}
让 Attribute
执行除了提供有关其装饰成员的元数据之外的功能是混合问题,会导致不必要的并发症,而不是它的设计目的。
可以取消整个自定义属性,而是使用内置数据属性
例如
public class ProfileTest : AuthTest {
[Theory, Priority(0)]
[InlineData(Enums.Role.SuperUser)]
[InlineData(Enums.Role.Editor)]
public void OpenProfilePageTest(Enums.Role role) {
//Arrange
AuthRepository.Login(role);
var profile = GetPage<ProfilePage>();
//Act
profile.GoTo();
//Assert
profile.IsAt();
}
}
AuthRepository.Login
在这种情况下是 setup/arrangement 的一部分,用于执行所需的用例。
我创建了一个名为 RoleAttribute
:
public class RoleAttribute : DataAttribute
{
public Role Role { get; set; }
public RoleAttribute(Role role, Action<Role> method)
{
Role = role;
AuthRepository.Login(role);
method(role);
}
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{
return new[] { new object[] { Role } };
}
}
我有测试方法OpenProfilePageTest
:
public class ProfileTest : AuthTest
{
[Theory, Priority(0)]
[Role(Enums.Role.SuperUser, OpenProfilePageTest)]
[Role(Enums.Role.Editor, OpenProfilePageTest)]
public void OpenProfilePageTest(Enums.Role role)
{
var profile = GetPage<ProfilePage>();
profile.GoTo();
profile.IsAt();
}
}
我想要的是它首先执行的每个角色(属性):
AuthRepository.Login(role);
(RoleAttribute
的构造函数)
然后继续 OpenProfilePageTest()
方法中的代码。在它重复相同但第二个属性之前。
我怎样才能做到这一点,现在我正试图通过在属性内部传递 OpenProfilePageTest()
方法并在其构造函数中执行它来实现这一点。一定有比绕过我相信的方法更好的方法来完成这个?
不通过方法也可以实现,需要稍微修改一下属性。我更改了属性以获取您要测试的所有角色,并在数据中 return 它们。这是一个例子
public class RolesAttribute : DataAttribute
{
private Role[] _roles;
public RolesAttribute(params Role[] roles)
{
_roles = roles;
}
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{
var data = new List<object[]>();
//We need to add each role param to the list of object[] params
//This will call the method for each role
foreach(var role in _roles)
data.Add(new object[]{role});
return data;
}
}
然后在你的测试中,你只需像这样在一个属性中传递所有你想测试的角色
public class ProfileTest : AuthTest
{
[Theory, Priority(0)]
[Roles(Enums.Role.SuperUser, Enums.Role.Editor)]
public void OpenProfilePageTest(Enums.Role role)
{
AuthRepository.Login(role);
var profile = GetPage<ProfilePage>();
profile.GoTo();
profile.IsAt();
}
}
让 Attribute
执行除了提供有关其装饰成员的元数据之外的功能是混合问题,会导致不必要的并发症,而不是它的设计目的。
可以取消整个自定义属性,而是使用内置数据属性
例如
public class ProfileTest : AuthTest {
[Theory, Priority(0)]
[InlineData(Enums.Role.SuperUser)]
[InlineData(Enums.Role.Editor)]
public void OpenProfilePageTest(Enums.Role role) {
//Arrange
AuthRepository.Login(role);
var profile = GetPage<ProfilePage>();
//Act
profile.GoTo();
//Assert
profile.IsAt();
}
}
AuthRepository.Login
在这种情况下是 setup/arrangement 的一部分,用于执行所需的用例。