模拟枚举继承:最佳选择&做法

时间:2012-02-10 17:58:48

标签: c# nunit webdriver selenium-webdriver

我正在设计一个测试应用程序(使用NUnit),它必须通过网页导航(通过Selenium Webdriver API)。我想使用枚举来模拟站点结构,以便能够通过此枚举告诉方法导航的位置(尤其是NUnit方法)。

this.NavigateTo(Page.HomePage);

这是一个强烈的要求(在某处有一个枚举类型),主要是因为NUnit不能传递非基本类型。例如,NUnit不可能使用这种语法,因为Page 必须是原语或枚举:

static class Page{
  public static Page HomePage;
  public static Page UserAccountPage;
}

/* ... later ... */
[TestCase(Page.HomePage)]
void TestMethod(Page p) { ...

我也想使用相同的enum-or-like来进行基本继承,比如

interface IPage{}
interface IPageNavigatable : Page {}
interface IPageUserRelated : Page {}
interface IWildcardPage : Page {}

enum Page{
  HomePage : IPageNavigatable,
  UserAccountPage : IPageNavigatable IPageUserRelated,
  ErrorPage : /* none */,
  AnyPage : IWildcardPage 
}

然后,我将能够制作非常有趣的方法,如

bool IsCurrentPage(IWildcardPage p);
void LoginThenNavigate(String user, String pw, IPageUserRelated p);
Page WhereAmI(); /* and use this value with IsAssignableFrom */

我知道C#禁止枚举继承(我仍然不明白这个选择,但现在这不是我的问题)而且我已经阅读了一些解决方法,包括从头开始重新编码的类枚举机制;没有一个看起来令人满意。

我所拥有的最好的想法是使用一个带有内部枚举和一些公共布尔值的复杂类。不太满意......

public class Page{
  enum Pages { /* you know them */}
  public Page.Pages InnerPage;
  public bool isWildcard, isUserRelated, ...;

  public Page(Page.Pages p){
    this.InnerPage = p;
    switch (p){
      case ...:
      case ...:
        this.isWildcard = true;
        break;
      /* ... */
    }
  }
}

/* NUnit calls */
[TestCase(Page.Pages.HomePage)]
void TestMethod(Page.Pages p) { ...

此外,在一个完美的世界中,我喜欢用字符串或URI“链接”我的枚举或类型值,以便我可以编写如下内容:

enum Page{
  HomePage : IPageNavigatable = "/index.php",
  UserAccountPage : IPageNavigatable IPageUserRelated = "/user.php",
  ErrorPage : /* none */ = (String) null,
  AnyPage : IWildcardPage = (String) null
}

/* ... */
Page p;
Selenium.Webdriver drv;
drv.Navigate().GoToUrl(new Url(p.ToString()));

这对我来说是一个棘手的问题。有人可以帮忙吗?

编辑:克里斯在下面指出的一个线索是,NUnit(通过属性)可以采用Object类型的参数。使用它,可能有一种方法用我的继承结构实现几乎没有代码的对象,并重新编码枚举机制的一部分(并链接到URL字符串)。

不是我梦寐以求的解决方案,但可能有用......

2 个答案:

答案 0 :(得分:2)

您是否尝试过自定义类而不是枚举?

,例如

public class Page
{
    public IPageNavigatable HomePage = "/index.php";
    public IPageNavigatable UserAccountPage  = "/user.php";
    public Type ErrorPage = null;
    public IWildcardPage AnyPage  = null;
}

答案 1 :(得分:2)

你确定它们必须是原始的(顺便说一句,我们称之为.net世界中的那些值类型或结构)? This page似乎暗示您受限制的原因是因为.NET属性的固有限制,而后者又被描述为here

  

属性参数限制为常量值   以下类型:

     

简单类型(bool,byte,char,short,int,long,float和double)

     

的字符串

     

的System.Type

     

枚举

     

object(对象类型的属性参数的参数必须是上述类型之一的常量值。)

     

任何上述类型的一维数组

这告诉我以下内容可行:

static class Pages {
  public const String HomePage = "Home Page";
  public const String UserAccountPage = "User Account Page";
}

[TestCase(Pages.HomePage)]
void TestMethod(Page p) { ...