Этот вопрос больше для общего обсуждения совместного использования значений в SpecFlow.Пожалуйста, предоставьте любую конструктивную обратную связь, которую вы могли бы получить, основываясь на своем опыте в SpecFlow.
Я относительно новичок в этой технологии, и когда я искал решение для совместного использования значений между файлами определений шагов, я обнаружил ScenarioContext.Current.Get
и ScenarioContext.Current.Set
.Они очень удобны, но, на мой взгляд, есть пара проблем.
- В этом подходе достаточно много типизации.
- Типы значений вставляются иизвлекается с помощью строковых индексов, поэтому для обеспечения согласованности определений шагов необходимо использовать строковые константы или перечисления.
- Возможно, небезопасно предполагать, что значение, которое вы пытаетесь получить, было вставлено.
Я придумала абстракцию, которая, как мне кажется, немного облегчает жизнь, и мне интересно, что люди думают об этом.
Проблема: имеетмое значение было установлено?
Мое решение для этого заключалось в том, чтобы обернуть ScenarioContext.Current
в класс доступа синглтона.Этот класс ведет себя как ScenarioContext.Current
, за исключением того, что он выдает AssertInconclusiveException
, когда значение не может быть найдено.
private static ScenarioContextAccessor instance;
public static ScenarioContextAccessor Instance
{
get
{
if (instance == null)
{
instance = new ScenarioContextAccessor();
}
return instance;
}
}
private ScenarioContextAccessor() { }
public T Retrieve<T>(string index)
{
try
{
T val = (T)ScenarioContext.Current[index];
if (val == null)
{
throw new Exception();
}
return val;
}
catch
{
throw new AssertInconclusiveException(index + " of type " + typeof(T).Name + " was not found in the current scenario context. Did you execute your steps out of order?");
}
}
public T Retrieve<T>()
{
try
{
T val = ScenarioContext.Current.Get<T>();
if (val == null)
{
throw new Exception();
}
return val;
}
catch
{
throw new AssertInconclusiveException("No object of type " + typeof(T).Name+ " could be found in the current scenario context. Did you execute your steps out of order?");
}
}
public void Set(string index, object value)
{
ScenarioContext.Current[index.ToLower(CultureInfo.InvariantCulture)] = value;
}
public void Set<T>(T value)
{
ScenarioContext.Current.Set<T>(value);
}
}
Проблема: для этого требуется слишком много печатать!
Мое решение для этого - иметь любое определение шага, которое требует, чтобы эти значения определяли их как частные свойства, поддерживаемые ScenarioContextAccessor
.Любое свойство, которое обращается к типу значения, использует строковую константу в качестве индекса.
private string FolderName
{
get
{
return ScenarioContextAccessor.Instance.Retrieve<string>(FolderingScenarioContextKey.FolderName);
}
set
{
ScenarioContextAccessor.Instance.Set(FolderingScenarioContextKey.FolderName, value);
}
}
private UserDocumentMetadata Metadata
{
get
{
return ScenarioContextAccessor.Instance.Retrieve<UserDocumentMetadata>();
}
set
{
ScenarioContextAccessor.Instance.Set<UserDocumentMetadata>(value);
}
}
Так что теперь я могу получить доступ к своим общим значениям так же легко, как если бы они были простыми свойствами.
Пожалуйста, предлагайте любые конструктивная обратная связь, которую вы можете получить.Спасибо!