Я разрабатываю тестовое приложение (с использованием NUnit), которое должно будет перемещаться (через Selenium Webdriver API) по веб-страницам. Я хотел бы смоделировать структуру сайта, используя перечисления, чтобы иметь возможность указывать методы, по которым следует перемещаться (особенно методы NUnit) через это перечисление.
this.NavigateTo(Page.HomePage);
Это строгое требование (иметь где-нибудь тип enum) главным образом потому, что NUnit не может быть передан не примитивным типам. Например, этот синтаксис невозможно NUnit, потому что страница должна быть примитивом или перечислением:
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()));
Это сложная проблема для меня. Кто-нибудь может помочь?
EDIT: подсказка, как указывает Крис ниже, заключается в том, что NUnit (через атрибуты) может принимать аргумент типа Object. Используя это, возможно, есть способ реализовать объекты, почти не содержащие кода, с моей структурой наследования, и перекодировать часть механизма enum (и ссылку на строки URL).
Не решение моей мечты, но может сработать ...