Проблема заключается вот в чем.
Есть много тестов, которые ранятся уже приблизительно около 6 часов. Хочется паралелить их запуск.
Как реализовано сейчас . Доккер контейнер разворачивает на виртуальной машине селеноид и в нем ранятся тесты. Генерится аллюр отчеты.
Тесты: dotnetcore, nunit3, seleniumc#
Разбить на несколько контейнеров, но как лучше это сделать? В одном контенере, но запускать в нескольких chrome браузерах, возможно ли?
Мощная машинка с большим количеством памяти, с виндой на борту.
Тут запускается nunit консолька, когда прилетает билд в стейдж тестов, и выполняются все тяжеловесные операции (хранение в памяти листов и прочее, в общем по сути все операции кроме обращения к браузеру)
В коде соответственно все запросы на создание браузеров улетают на GGR.
GGR раскидывает на N хостов сессии.
Ну а дальше браузеры поднимаются селенойдом…
В итоге линуксовые машинки, на которых крутится селеноид не особо мощные, но их много.
А отчет аллюра генерится на виндовой машине, оттуда прилетает обратно на дженкинс.
возможно придется отказаться от NgDriver ради паралельности и заменить на собственные ожидания как в этой статье https://www.swtestacademy.com/selenium-wait-javascript-angular-ajax/
но там много лишнего
там есть
waitUntilAngularReady();
waitUntilAngular5Ready();
работает для 5 и выше только скрипт waitUntilAngular5Ready();
Если просто параллелить - то в Properties -> AssemblyInfo.cs установить нужный уровень параллелизации, например, [assembly: LevelOfParallelism(6)] (через CI также можно задать).
А дальше фикчи помечать нужным типом параллелизации (например, [Parallelizable(ParallelScope.Fixtures)])
Спасибо за советы. Попробовала NUnit Parallelizable - не получается, так как при одновременном запуске 2 тестов в хроме, теряется session id. И тест фактически не стартует.
Вариант с отказом от ngwebdriver пока не принимаю, как говорится, работает - не трогай.
Вариант docker , solenoid , потом допустим 2 инстанса ggr и chrome browser последней версии. Каким образом тесты поделятся на 2 пачки для запуска? Что-то нужно делать в коде тестов ?
Объявила и куда ее дальше? Драйверу?
Второй вопрос. В случае с ggr деление по сессия не нужно?
И третий по docker solenoid, не находит файл. Локально работает.
Может сталкивались с таким
OpenQA.Selenium.WebDriverException : invalid argument: File not found : /src/bin/Debug/netcoreapp2.2/Files/Pic.png
(Session info: chrome=76.0.3809.87)
at Allure.Commons.AllureLifecycle.StepRunner[TResult](String stepName, Delegate del, Boolean throwEx, Status stepStatusIfFailed, Object[] stepParams)
at Allure.Commons.AllureLifecycle.RunStep(String stepName, Action stepBody, Object
Session Id теряться может только в том случае, если это поле/свойство или переменная не является уникальным для конкретного потока.
Для простой логики достаточно сделать статичное поле с атрибутом [ThreadStatic]:
[ThreadStatic] private static string SessionId;
А обращаться к нему можно уже через обычное свойство, например.
Если же нужна какая-то доп. логика (например если нам надо достучаться до определенной сессии из других потоков), то лучше использовать класс ThreadLocal<T>:
protected ThreadLocal<IScreenshotStrategy> ScreenshotStrategyThreadLocal =
new ThreadLocal<IScreenshotStrategy>(true);
Используя GGR/Selenoid, если вы параллелите тесты, вам всё равно надо делать код потокобезопасным.
А по вопросу того, что Selenoid не находит файл, так это логично - в контейнер надо прокидывать нужные volumes.
Но появилась ошибка и пришлось добавить encoding (выделила звездочками код выше), с которым тоже не работает аплоад
Error Message:
cdmtestoriginal_1 | System.TypeInitializationException : The type initializer for 'System.IO.Compression.ZipStorer' threw an exception.
cdmtestoriginal_1 | ----> System.NotSupportedException : No data is available for encoding 437. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.
cdmtestoriginal_1 | Stack Trace:
cdmtestoriginal_1 | at System.IO.Compression.ZipStorer.WriteEndRecord(UInt32 size, UInt32 offset)
cdmtestoriginal_1 | at System.IO.Compression.ZipStorer.Close()
cdmtestoriginal_1 | at OpenQA.Selenium.Remote.RemoteWebElement.UploadFile(String localFile)
Перепроверила. Не там поставила слеш и проект не сбилдился.
В volumes добавила. Eсли указівать не правильный путь к файлу - пишет file not found
Если путь правильный - тогда такая ошибка
cdmtestoriginal_1 | at System.IO.Compression.ZipStorer.WriteEndRecord(UInt32 size, UInt32 offset)
cdmtestoriginal_1 | at System.IO.Compression.ZipStorer.Close()
Загрузка файла довольно простая:
public string purchfilepath = @"Files/Pic.png";
manufactPart.ModelFile.SendKeys(Utils.GetFileFullPath(manuffilepath));
internal class Utils
{ public static string GetFileFullPath(string relativePath)
{
return @"/src/"+relativePath;
}
Попытаюсь как можно подробнее рассказать.
Тесты без загрузки файлов проходят без проблем.
Тест в котором есть загрузка файла, падает в месте загрузки файла.
Фактически передается ссылка где лежит картинка. Причем если меняю имя картинки на не существующее в папке с файлами - при прогоне теста пишет что файл не найден. Поэтмоу я могу сказать что файл точно есть, но видимо так как не Linux , а win, не получается передать его как урл для загрузки файла.
Но возможно другая причина. Возможно нужно использовать не SendKeys, а что-то другое. Я в печали.
2019-09-05_1755 ( если нужен весь прогон - могу приаттачить)
У меня скачка файлов не работала в headlessмоде, пришлось для этих тестов делать обычный режим, может таже самая проблема. Потестируйте из под студии в обычном моде и headless
Там решение есть, и оно касается именно прокидывания файлов в сам селенойд контейнер, что вы уже сделали, указав volumes.
У вас тест, я так понимаю, должен взять локальный файл (который вы прокинули в контейнер) и загрузить его на сайт, так?
И этот файл точно лежит в контейнере?
Headless мод может зависить еще от и CI, например в Azure DevOps или Teamcity если агент запущен как сервис, а не как консольное приложение тесты ранаются в Headless mode