У меня возникли проблемы с особым стилем параметризованных тестов. Все наши тесты Selenium могут выполняться локально, но они также должны быть удалены удаленно на нескольких платформах на SauceLabs. В принципе, я хотел взять большое количество уже написанных тестовых примеров и параметризовать их с минимальными изменениями кода. Кроме того, мне нужно было передать параметры в метод setUp, то, что я не видел в других решениях.
Вот что я придумал:
import inspect
import types
test_platforms = [
{'browserName': "internet explorer", 'platform': "Windows 7", 'version': "10.0"},
{'browserName': "internet explorer", 'platform': "Windows 7", 'version': "11.0"},
{'browserName': "firefox", 'platform': "Linux", 'version': "43.0"},
]
def sauce_labs():
def wrapper(cls):
return test_on_platforms(cls)
return wrapper
def test_on_platforms(base_class):
for name, function in inspect.getmembers(base_class, inspect.isfunction):
if name.startswith('test_'):
for platform in test_platforms:
new_name = '_'.join(list([name, ''.join(platform['browserName'].title().split()), platform['version']]))
new_function = types.FunctionType(function.__code__, function.__globals__, new_name,
function.__defaults__, function.__closure__)
setattr(new_function, 'platform', platform)
setattr(base_class, new_name, new_function)
delattr(base_class, name)
return base_class
При этом все, что мне нужно было сделать, это добавить простой декоратор @sauce_labs () в каждый обычный старый TestCase, а теперь, когда его запускают, они завернуты и переписаны, так что все методы тестирования параметризуются и переименованы. LoginTests.test_login (self) работает как LoginTests.test_login_internet_explorer_10.0 (self), LoginTests.test_login_internet_explorer_11.0 (self) и LoginTests.test_login_firefox_43.0 (self), и каждый из них имеет параметр self.platform, чтобы решить, какой браузер / платформу для запуска, даже в LoginTests.setUp, что имеет решающее значение для моей задачи, поскольку именно там инициализируется соединение с SauceLabs.
В любом случае, я надеюсь, что это может помочь кому-то, кто хочет сделать аналогичную «глобальная» параметризация их тестов!
Mark Outs
с атрибутом [JsonProperty]
:
private class Engine
{
public string Text { get; set; }
public int Id { get; set; }
[JsonProperty] // Causes the protected setter to be called on deserialization.
public Coords[] Outs { get; protected set; }
public Engine()
{
this.Outs = new Coords[3];
for (int i = 0; i < this.Outs.Length; i++)
{
this.Outs[i] = new Coords();
}
}
}