Перейти к содержимому

Публикации Noksa

117 публикаций создано Noksa (учитываются публикации только с 05 июня 2023)



#166301 Использовать созданный ранее объект WebDriver

Отправлено автор: Noksa 23 мая 2018 - 05:31 в Selenium - Functional Testing

 

Можно ли использовать уже существующий объект Selenium WebDriver? Я имею в виду следующее: в первом тесте я создаю этот объект, а по его окончанию не закрываю и не уничтожаю. После окончания теста процесс продолжает оставаться в памяти. Через какое-то время у меня возникает потребность запустить другой тест, в котором используется тот же URL. Могу ли я каким-то образом в этом новом тесте использовать старый объект драйвера, активировать существующее окно браузера и выполнить в нем новый тест?

не закрывайте например :) или статический вебдрайвер используйте но если статик будет тогда не будет и паралельных тестов

 

 

Достаточно положить статик драйвер в ThreadLocal<>, чтобы были параллельные тесты по потокам.




#166400 Извлечь текст из определённого места на странице С# + webdriver

Отправлено автор: Noksa 30 мая 2018 - 20:13 в Selenium - Functional Testing

Не получалось составить корректный xpath/css селектор!

Пока ждал ответа не сидел сложа руки и внутри цикла написал такое:

t = driver.FindElement(By.XPath("//tr[" + N + "]/td/table/tbody/tr/td")).Text;
N++;

Работает, но я не уверен насколько надёжна такая конструкция и может быть есть вариант проще или корректнее?

Из вашего локатора надо убрать лишнее до //table. Да и в целом переписать его.
К тому же, если в вашей таблице в ячейке будет какой-то элемент с текстом, а не просто текст - локатор не сработает.
Например ссылка с текстом.
Здесь нужно использовать ИЛИ.
Завтра как доберусь к компьютеру могу подробнее написать правильный универсальный локатор.



#166402 Извлечь текст из определённого места на странице С# + webdriver

Отправлено автор: Noksa 31 мая 2018 - 04:42 в Selenium - Functional Testing

Доброго времени суток.

 

Лично я в своей работе использую собственные классы элементов со всеми вытекающими плюсами из этого.

Для этого нужно написать свой декоратор.

 

В классе вертикальной таблицы у меня определяются элементы следующим образом:

 

1) Все строки: 

public virtual IList<IWebElement> Rows => FindElements(By.CssSelector("tbody tr"));
 
2) Все столбцы:
public virtual IList<IWebElement> Columns => FindElements(By.CssSelector("tr:first-child th"));
 
3) Все ячейки:
public virtual IList<IWebElement> Cells => FindElements(By.CssSelector("tbody tr td"));
 
Здесь надо учитывать то, что поиск элементов происходит от родительского.
Так же использую свой фреймворк, где у меня работают следующие атрибуты:
 
[BlockTitle("Модальное окно с заказом")]
[FindBy(XPath = "//div[@class = \'modal-content\']")]
[TimeToSearch("block_waiting_timing")]
    public class OrderModalBlock : ABlock
    {       
 
        [FindBy(XPath = "(.//table[preceding::*[contains(text(), \'Заказ\')]]) [1]", ParentElement = "Модальное окно с заказом")]
        [ElementTitle("Заказ")]
        private AHorizontalTable _orderTable;

      ...../

   }

 

Соответственно, таблица является дочерним элементом блока элементов.

А элементы внутри таблицы - соответственно дочерними элементами самой таблицы.

 

Сам локатор для поиска текста в ячейке такой (точка в начале Xpath означает, что поиск нужно осуществлять внутри родительского элемента - это важно, если у вас на странице не одна таблица): 

var element = FindElement(By.XPath($".//tbody//tr[{rowId}]//td[contains(text(), \'{textInRow}\')]|.//tbody//tr[{rowId}]//td[*[contains(text(), \'{textInRow}\')]]"));
 
Такой xpath либо найдет текст в самой ячейке, либо в любом элементе в этой ячейке. 
В моём примере, ячейка хранит ссылку, т.е. <td><a...></a></td> - и текст нужно было искать именно в элементе <a>.
 
Если вам нужно искать текст не смотря на регистр, и у вас XPath 1.0, то можно воспользоваться вспомогательным методом. 
Например таким:
 
public static string ContainsTextIgnoreCase(string text)
        {
            return
                $"text()[contains(translate(., \'ABCDEFGHIJKLMNOPQRSTUVWXYZЙФЯЦЫЧУВСКАМЕПИНРТГОЬШЛБЩДЮЗЖХЭЪ\', \'abcdefghijklmnopqrstuvwxyzйфяцычувскамепинртгоьшлбщдюзжхэъ\'), \'{text.ToLower()}\')]/parent::*";
        }



#166404 Извлечь текст из определённого места на странице С# + webdriver

Отправлено автор: Noksa 31 мая 2018 - 07:16 в Selenium - Functional Testing

Ещё такой вопрос:

Заранее определяю элемент: By checkboxes = By.XPath("//input[@name='CurrentObject.Show']");

Потом использую его в коде: driver.FindElement(checkboxes).Click();

 

Но в один прекрасный момент мне понадобилось сделать, как бы корректнее выразится, перебор по этим схожим элементам.

И внутри цикла получается только так: driver.FindElement(By.XPath("(//input[@name='CurrentObject.Show'])" + "[" + n1 + "]")).Click();

 

Можно как-нибудь сделать чтобы это было похоже на : driver.FindElement(checkboxes[n1]).Click(); как-то вот так???

 

Вы можете использовать метод FindElements.

 

Например так: driver.FindElements(checkboxes).

 

Он вернёт вам список всех найденных элементов по переданному локатору.

А потом уже можете в foreach пройтись по всем элементам из списка:

 

foreach (var checkBox in checkboxes)

                {
                    checkBox.Click();
                }
 
Если метод только один, то фигурные скобки можно опустить:

foreach (var checkBox in checkboxes) checkBox.Click();                

 
Либо через лямбду:
checkboxes.ToList().ForEach(_ => _.Click());



#166405 Извлечь текст из определённого места на странице С# + webdriver

Отправлено автор: Noksa 31 мая 2018 - 07:21 в Selenium - Functional Testing

Ну и да - я вам советую использовать PageObject паттерн, если вы его не используете. 




#166427 Скачивание файлов селениумом через headless режим C#

Отправлено автор: Noksa 01 июня 2018 - 06:03 в Selenium - Functional Testing

Коллеги, доброго времени суток.

 

Есть метод, который выполняет следующее:


1) Лочит блок кода, в котором происходит:
а) Запоминание количества файлов в директории
б) Клик по кнопке, в результате которого начинается скачивание файла и ожидание, пока файл скачается целиком
в) Сравнение двух коллекций - до скачивания и после - получаем разницу в 1 файл, дёргаем искомый файл.
2) Выходим из лока и работаем дальше с этим файлом.

 

Всё работает хорошо, пока не установить запуск хрома в режиме headless: chromeOptions.AddArgument("--headless");

Я нашёл в репо селениума открытый баг https://github.com/S...ium/issues/5159 в котором пока судя по всему нет решения проблемы.

 

Есть ли какие-то костыльные workaround, как скачать файл в этом режиме сейчас?

 

Версии драйвера, браузера последние.




#166432 Скачивание файлов селениумом через headless режим C#

Отправлено автор: Noksa 01 июня 2018 - 08:26 в Selenium - Functional Testing

Я не спрашивал, нужен этот тест или не нужен.

 

У меня тест - имитация действий пользователя.

Понятно, что я могу скачать файл напрямую через ссылку в коде, если мне нужен будет просто файл.

 

Но мне нужно проверить, что этот файл скачается, нажав на кнопку - выгрузка данных в эксель-файл с последующей его проверкой. 

 

Что же в этом костыльного? :) 




#166436 Скачивание файлов селениумом через headless режим C#

Отправлено автор: Noksa 01 июня 2018 - 10:24 в Selenium - Functional Testing

 

 

 

Что же в этом костыльного? :) 

если файл генерится в бэк-энде, то там его и можно проверить интеграционными тестами например

 

 

Да, но если он не генерится по нажатию кнопки при этом, что в этом случае сказать? "Сорри, я проверял только бизнес-логику"? 

 

Нужен именно вариант с интерфейсом, иначе я бы не парился :)

Сейчас я просто убрал headless режим, но без него хром явно медленнее соображает.




#166457 getText (getValue) для дефолтного значения dropbox

Отправлено автор: Noksa 04 июня 2018 - 07:51 в Selenium - Functional Testing

Надо учитывать, что если значение никакое не выбрано - у вас вылетит эксепшн. 




#166516 Наследования

Отправлено автор: Noksa 07 июня 2018 - 16:43 в Автоматизированное тестирование

Наследованию всегда надо предпочитать композицию, если есть возможность.
И вообще, PageObject в помощь.



#166519 Наследования

Отправлено автор: Noksa 08 июня 2018 - 04:38 в Автоматизированное тестирование

 

 

 а вот наследовать тесты - плохая практика.

 

Вот здесь я не понял Вас немного. Каждый методу меня это этап бизнес процесса. Вот cardFill  - это заполнение карточки заявления. В итоге я хочу на одной ветке БП создать этот метод (так как я и сделал в классе FirstBP_OrgCreating) , а дальше наследовать все классы от этого класса, и просто вызывать этот метод. Я не могу понять чем это чревато?

 

 

1) Ваши классы нарушают SRP в чистом виде.

Они не выполняют одну задачу, а выполняют две - проверяют какой-то функционал и создают драйвер.

 

Вам нужно вынести всю логику по работе с драйвером в базовый класс для всех тестов. Всё создание драйвера и его уничтожение будет описано в одном месте.

От него и надо будет наследовать классы тестов.

В идеале это должна быть фабрика по созданию нужного драйвера.

В классах тестов не должно быть никакого упоминания о драйвере!

 

Сейчас у вас создание драйвера, во-первых, имеет хардкод в жесткий диск (это вообще жесть полная), во-вторых - предусмотрено создание только хромдрайвера.

И, опять же, дублирование кода создания драйвера, при этом один класс наследует другой... выглядит странным.

 

 

Чем всё это чревато? А тем, что если у вас поменяется что-то в создании драйвера, например, вам будет нужен не хром, а лиса - вам придётся это менять во всех местах.

Эту проблему вообще надо решать другим путём, конечно, это просто как пример.

 

2) Сейчас у вас заполнение карточки является по сути не тестом, а precondition шагом. 

В той реализации, что у вас есть - у вас все тесты будут зависеть по факту от одного теста. Зависимые тесты - это очень плохо. Если ваш первый тест не будет работать - все остальные тоже не будут работать из-за того, что они не могут выполнить precondition шаг.

 

В идеале, нужно уходить от такого рода шагов. Например, путём создания другого precondition шага, который будет в БД приложения записывать нужные данные, а тест уже будет их использовать.

Таким образом, если создание precondition шага в интерфейсе не будет работать - вы сможете проверить другой функционал, минуя его.

А в отдельном одном тесте уже проверять непосредственно cardFill через интерфейс.

 

 

Действия на страницах надо выносить не в базовый класс, а следовать PageObject паттерну, и выносить это в отдельные методы на конкретном pageobject'е. А в самих PageObject применять композицию для избежания дублирования кода.

Допустим, есть общее меню для всех страниц - его нужно выносить в отдельный класс (я их называю блоками) и используя композицию вносить его во все pageobject, где он присутствует.

Таким образом, элементы описанные в этом блоке - будут описаны в одном месте, и при их изменении вам нужно будет исправить их только в одном месте, а не на всех страницах.

 

 

Общее видение PageObject:

 

У вас есть страница Cards. 

Создаёте класс Cards, в нём создаете мелкие методы, которые делают что-то на этой странице.

Потом, если вас это не устраивает - делаете там же общий метод cardFill, который содержит в себе вызовы мелких методов, а не дублирует их логику.

 

 

А в тесте уже используете этот класс и методы из него. Здесь не нужно наследование.




#166522 Наследования

Отправлено автор: Noksa 08 июня 2018 - 06:55 в Автоматизированное тестирование

Вам нужно вынести всю логику по работе с драйвером в базовый класс для всех тестов. Всё создание драйвера и его уничтожение будет описано в одном месте.

От него и надо будет наследовать классы тестов.

 

В идеале это должна быть фабрика по созданию нужного драйвера.

В классах тестов не должно быть никакого упоминания о драйвере!

 

Тут я Вас понял! Именно из за того что я создавал драйвер в каждом классе у меня и наследование не получится. 

Фабрики для создание драйверов мне не нужно - работаем только с chrome, поэтому и указал путь на ЖД. Но уже видел ссылку где это делаеться через maven, пересмотрю потом.

И да то, что в тестах не должно быть упоминание о драйвере только сейчас понял. Но так как я только начинаю работать то для меня понимание этого уже плюс)

 

 

Мыслите шире. Или даже так - мыслите интерфейсами. Это позволит вам писать легкоизменяемый код, который при этом не повлияет на работоспособность другого кода, который его использует.

 

Сейчас не нужно - а завтра будет нужно. Заказчики люди непостоянные и требования у них могут меняться каждый день :)

 

Лучше сразу предусмотреть возможность создания любого драйвера, чтобы потом не пришлось строить костыли.

 

Хороший вариант, это параметризация запуска тестов. При запуске передавать параметр - какой браузер использовать.

Таким образом, вы одновременно, например на разных машинах, сможете запустить все тесты на разных браузерах.

 

 

Дело в том что как бы я не хотел сделать тесты независимыми - этого у меня не получиться. Возьмем для примера заполнения этой карточки. От этого теста зависит выполнение всех последующих. В конце теста есть клик на кнопку, после которого отправляеться на емейл ссылка для дальнейшей работы. Поэтому если даный тест не отработает (ссылка не прийдет) то и последуюющие шаги мне выполнять не нужно. Я не смогу начать выполнять тест с 3 или 4 этапа бизнес процесса. Только в такой последовательности. Поэтому даже при запуске, для того что бы проверить например 8 сетод (завершения БП) мне нужно тест запустить с самого начала. 

 

Можно использовать API, или БД, необязательно создавать тестовые данные через интерфейс. Это быстрее и надежнее.
 
Но, если вы прям уж очень хотите завязываться на интерфейс - в таком случае нужно скипать все тесты, которые не будут выполняться без этого шага, чтобы сэкономить время. Ибо запускать их смысла нет. Ну и указывать причину, почему скипнуты.
 

 

 

На сколько я понял вы предлагаете уже в тестах создать метод напримет cardFill() в нем создать обьект OrgCard  и на нем вызвать метод orgcard.setFieldsOnTheOrgCard(); 

 

Не-не, ни в коем разе.
Да, у вас вполне себе pageobject.
Тесты не должны создавать методы, они должны только использовать их. Иначе будет каша.
 
 

 

 

Для первого класса у меня такая же реализация. А для других классов  я почему то решил что нужно делать наследования. То есть Вы говорите что нужно и для других классов создавать обьект класса OrgCard  и на нем вызвать метод orgcard.setFieldsOnTheOrgCard(), а не делать наследование

 

Вы путаете тестовые классы и PageObject классы.

Тестовые классы должны использовать экземпляры pageobject классов.

Сам тестовый класс не должен знать ничего о другом тестовом классе, он должен только наследовать базовый тестовый класс для всех тестовых классов, в котором реализована общая логика для всех тестовых классов (методы создания драйвера, уничтожения драйвера, что-то ещё)

 

Так же как и PageObject классы - могут наследовать какой-то базовый для них всех класс, в котором например:

1) Будет конструктор с PageFactory с кастомным декоратором, чтобы не писать его каждый раз в каждом наследнике.

2) Какие-то общие для всех страниц методы и так далее...

 

 

PS: 

Вынесите в OrgCard всю логику, ведь она относится непосредственно к этой странице:

public string fillCard()
{    
    this.setFieldsOnTheOrgCard();
    PopUpMessage popUpMessage = this.createButtonClick();
    return popUpMessage.getLinkFromPopUp();
} 

 

А в тестах используйте в первой строке:

new OrgCard(driver).fillCard()

и никакого наследования тестами других тестов.




#166523 Наследования

Отправлено автор: Noksa 08 июня 2018 - 07:12 в Автоматизированное тестирование

Так же, я бы вам советовал сразу писать такую архитектуру, в которой не требуется в конструктор страницы передавать драйвер.

Т.е, в конструктор страницы вообще ничего не следует передавать.

 

Как вариант, использовать статичный драйвер в контейнере ThreadLocal<>.

 

Это моё субъективное мнение.

 

 

Пример с C#, на страницах не требуется объявлять конструктор, он вызывается из базового класса.

При этом все прекрасно бегает в параллельных потоках.

public class NewsPage : BasePage
    {
      ....
    }


public abstract class BasePage
    {
     ...

     protected BasePage()
        {
            Elements.Clear();
            ElementsInBlocks.Clear();
            PageFactory.InitElements(DriverManager.Driver, this, new AFieldDecorator());
        }



#166541 Selenium-web-driver ----- ошибка Returned node (null) was not a DOM el

Отправлено автор: Noksa 08 июня 2018 - 17:06 в Selenium - Functional Testing

Пример кода, где ошибка валится?



#166550 Как ускорить автотесты, давайте соберем все возможные варианты

Отправлено автор: Noksa 10 июня 2018 - 20:05 в Selenium - Functional Testing

Самое банальное и очевидное - улучшить железо, а как следствие количество потоков.



#166570 Page Object ver.2

Отправлено автор: Noksa 11 июня 2018 - 18:28 в Автоматизированное тестирование

Скажу от себя.

 

 

 

создаем маленькие методы (например заполнить поле, выбрать с селекта)

 

Предположим, что у вас будет на странице 20 полей, которые нужно заполнить и 5 селектов, которые нужно выбрать.

 

Если вы будете для каждого поля делать отдельный метод, то количество методов на данной странице, помимо каких-то вспомогательных и унаследованных, будет большое количество и это не очень удобно. Количество методов не должно быть слишком большим, это очень неудобно.

 

Здесь можно пойти другим путём. Сделать один универсальный метод, например "fillField", который будет принимать в себя два аргумента: enum и string.

Где enum - это перечисление всех полей\селектов, которые есть на странице, а string - соответственно чем нужно заполнить\что нужно выбрать.

 

Ну а в теле метода уже через switch реализовать заполнение\селект конкретных полей\селектов.

 

В итоге у вас будет всего один метод, который работает с полями\селектами на странице.

 

Далее.

 

 

 

Жду конструктивной критики

 

Я сторонник PageFactory с кастомным локатором\декоратором, поэтому для меня поиск элементов через findElement и поля с типом By - это некрасиво и глаза разбегаются.

 

Могу привести пример, почему PageFactory лучше, на мой взгляд.

Вы можете придумать свои собственные атрибуты (аннотации), которые можете использовать у каких-то элементов.

Есть, допустим, элемент, который появляется динамически, но точно должен появиться спустя 3 секунды.

 

При поиске через чистый findElement, у вас тут же будет выброшено исключение, если элемент не существует или исчез из DOM страницы.

Конечно же, вы всегда можете обернуть вызов findElement для достижения нужного результата - но это тоже на мой взгляд не оптимально.

 

А при использовании PageFactory и своей собственной аннотации, вы можете указать, что конкретный элемент нужно ждать 3 секунды. И если спустя эти 3 секунды он не появился - тогда будет выброшено исключение.

Либо вы можете добавить аннотацию, чтобы не выбрасывалось исключение, а просто писался варн в лог и тест шёл дальше - словом, всё что захотите.

 

Пример с C#:

[FindBy(Id = "date_from")]
[ElementTitle("Операции с")]
[TimeToSearch(3)]
private ADatePicker _dateFromPicker;

При обращении к этому элементу, будут предприняты попытки его поиска в течении 3 секунд. 

Или можно использовать не хардкодное значение, а ссылаться на какое-то проперти, и при его изменении оно соответственно изменится у всех затронутых элементов:

[FindBy(Id = "date_from")]
[ElementTitle("Операции с")]
[TimeToSearch(App.Properties.Timeouts.Small)]
private ADatePicker _dateFromPicker;

А так же задавать нужный polling time, да в общем-то что угодно. 

Я, например, реализовал атрибут (аннотацию) для указания родительского элемента:

[FindBy(Id = "date_from", ParentElement = dateBlockName)]
[ElementTitle("Операции с")]
private ADatePicker _dateFromPicker;

Чтобы избежать дублирования XPath.

 

 

Далее.

 

 

 

Создал класс BaseTest, в котором у меня реализована инициализация драйвера, также убрал SetProperty с явным указанием в нем пути к драйверу заменив его dependency WebDriverManager в pom файле. В итоге получился такой код:

 

Хардкод хромдрайвера и до сих пор есть необходимость всюду пропихивать экземпляр драйвера.

 

 

 

Мне кажется что в тестовых классах я не должен иметь возможности делать driver.findElement, driver.click и т.д. Тоесть на прямую обращаться к драйверу. Или я ошибаюсь?

 

И да и нет.

У вас, как ни крути, будет доступен драйвер в тестовом классе. У вас же тестовый класс наследуется от базового, в котором драйвер protected.

Просто не используйте драйвер в тестовых классах в таких целях.

 

 

 В архитектуре классов у меня есть также класс SummaryAPI. В лекции что я смотрел, от этого класса неследовались классы BasePage и BaseTest - тоесть в них была реализация чего то общего для этих двух классов, например того же метода find:

 

Могу сказать по себе. 

Мне пришлось форкнуть Allure под C# и реализовать в нём возможность создания\добавления шагов и аттачей в [setup] и [teardown] методах.

 

И чтобы не указывать в каждом тестовом классе, что этот класс должен генерить отчет, я наследую базовый тестовый класс от класса, в котором у меня реализован старт\стоп отчета и прочее.

В итоге для всех тестовых классов у меня будет создаваться отчет.

public abstract class ABaseTestConfig : AllureReport
    {
      ...
    }

Но это что касается базового тестового класса.

 

Для чего нужно иметь общий базовый класс и для базового тестового класса и для BasePage - честно говоря никогда не думал об этом.

 

Могу лишь предположить, что какие-то общие данные текущего запуска тестов \ теста, но вроде все (?) тестовые фреймворки и так это хранят в доступных через статичные классы контекстах. 




#166574 Как ускорить автотесты, давайте соберем все возможные варианты

Отправлено автор: Noksa 12 июня 2018 - 09:57 в Selenium - Functional Testing

У ТС нет цели уменьшить количество авто-тестов.

У него совсем другая цель.

 

 

 

Истинное искусство тестировщика - уменьшение числа тестов.

Предлагаете уменьшать покрытие? 

 

При релизах всё равно надо гонять все тесты. И чем их больше (т.е. больше покрытие) - тем лучше.

 

 

 

Это прошлый век. Сейчас выгоднее на время прогона тестов арендовать вычислительные мощности в облаке.

 

Кому как. Я за стабильную мощную физическую машину.

 

И ещё учитывайте, что не все компании, а если быть точнее - их политика безопасности, разрешает использовать какое-либо облако.




#166579 Как ускорить автотесты, давайте соберем все возможные варианты

Отправлено автор: Noksa 12 июня 2018 - 18:47 в Selenium - Functional Testing

И чем же это плохо, если это занимает при хорошей параллельности 10 минут?
Нет, конечно можно забить и прогнать только явно «задетые» фичи за пару минут, а потом наблюдать за дефектами на проде и за метрикой бездефектности - выбор каждого.



#166588 Как ускорить автотесты, давайте соберем все возможные варианты

Отправлено автор: Noksa 13 июня 2018 - 09:18 в Selenium - Functional Testing

Проблема в том, что из "прогнать все автоматизированные UI-тесты" совершенно не следует "ноль дефектов на проде".

 

Безусловно. Я об этом и не писал :)

Но чем больше полезных тестов вы прогоните, тем меньше потенциальных дефектов там окажется.

 

Да и вообще, все клиенты разные. Кому-то не нравится что в тексте допущены ошибки, кому-то ещё что-то. 

 

И все таки какие люди счастливые... Всего жалких "500 UI-тестов". Вот было бы немного, ну хотя бы тысяч 5-10. Хотя бы. Я уж не говорю про нормальное количество.

 

Нет, конечно можно забить и прогнать только явно «задетые» фичи за пару минут, а потом наблюдать за дефектами на проде и за метрикой бездефектности - выбор каждого. 

 

 

Если это так, то у вас "сильно связанный код". Что в свою очередь означает, что вам уже Слово из 6 букв, вторая "И". Не надо смотреть на разработку с точки зрения тестирования. Смотрите с точки зрения разработки в целом. Если вы просели по группе атрибутов качества "модифицируемость" (ГОСТ 25010), то... У вас все очень, очень плохо.

 

Да хоть 50000. Если ресурсы компании позволяют это так же прогонять за 10 минут (или смотря сколько у вас time2market), не вижу никакой проблемы.

А если вы ограничены в ресурсах, то конечно - выкидывайте тесты и пишите, что так надо делать и это вообще best practice.

 

 

PS: Даже если у вас не "сильно связанный код", никто никогда не даст гарантию, что его изменение обязательно не заденет что-то другое.

 

Большинство дефектов, в общем-то, обычно отсюда и вытекает, что "ой, а тут не должно было ничего измениться".

 

 

За сим откланиваюсь, дальнейшая дискуссия не имеет смысла.




#166688 Можно ли в автотестах установить количество запуска?

Отправлено автор: Noksa 19 июня 2018 - 16:28 в Автоматизированное тестирование

Вам нужно CI/CD.



#166690 Как найти отчеты о прохождении теста в Visual Studio

Отправлено автор: Noksa 19 июня 2018 - 18:52 в Автоматизированное тестирование

Без дополнительных тулов у вас никогда не будет нормальных отчетов\истории и прочего.

 

Но, отчет в самой VS можно получить через Test Explorer.

 

Test => Windows => Test Explorer.




#166745 Как записать переменную внутри локатора

Отправлено автор: Noksa 21 июня 2018 - 18:31 в Selenium - Functional Testing

Java:

WebElement parentElement = driver.findElement(By.xpath("//div[text()='" + st1 + "']/../.."));

C#:

var parentElement = driver.FindElement(By.XPath($"//div[text()='{st1}']/../.."));



#166749 Загрузка документа

Отправлено автор: Noksa 21 июня 2018 - 20:05 в Автоматизированное тестирование

Что мешает запомнить количество файлов до какого-то действия, а после него ждать пока количество файлов изменится на +1 и проверять ещё что файл скачан до конца?



#166751 Загрузка документа

Отправлено автор: Noksa 22 июня 2018 - 05:12 в Автоматизированное тестирование

Ничего не мешает, кроме того что файл может быть не скачен

 

В каком смысле он может быть не скачан?

 

Я использую такой вариант:

 

После нажатия кнопки/ссылки начинается скачивание файла (в течении 2-3 сек).

Сам файл может качаться при этом любое время.

 

Ждём условные 2-3 секунды изменения количества файлов в директории загрузки.

Если по истечении 2-3 секунд количество файлов не изменилось - значит что-то пошло не так и скачивание не началось.

Если же началось, то количество файлов уже изменилось, даже если файл ещё не скачался.

 

Вычитаем из одной коллекции другую, получаем одно вхождение - это наш новый файл.

 

Далее ждём, пока он скачается целиком.

Здесь вариантов может быть много:

1)  Ждём пока у файла расширение изменится с .download/.temp/ещё какого-то на любое другое кроме этих

2) Ждём пока у файла будет конкретное расширение, если вы знаете, каким оно должно быть после скачивания.

3) Ждём пока у файла будет ожидаемый размер.

4) Итд.




#166755 Загрузка документа

Отправлено автор: Noksa 22 июня 2018 - 06:31 в Автоматизированное тестирование

Александр спасибо за ответ.

В том то и дело что файл может быть не скачан. Кликаем на download а в ответ тишина. 

 

Насчет подождать условные 2-3 секунды - вот тут то и основная загвоздка, что по моим наблюдениям файл начинает скачиваться как мгновенно после нажатия кнопки, так и через 10 секунд :)),  да да через 10(редко, но бывает и дольше), почему так это не ко мне, имеем что имеем, по этому ставить в "лоб" ожидание 10 секунд для каждого моего документа (а их около 200) не совсем камильфо, собственно я и думал что есть уже какое-то "умное" решение этого ожидания. 

 

В любом случае, спасибо что отозвались.

 

Ну здесь по-другому не получится.

Да и это не совсем в лоб.

Вы же не будете ждать каждый раз 10 секунд. Если файл начал качаться за 1 секунду - то ожидание прервется и начнется другое - ожидание завершения скачивания файла.

 

Если у вас файлы начинают качаться спустя 10 секунд после клика по кнопке - это проблема разработки, надо идти к ним/к начальству и просить оптимизировать. 

 

Предполагаю, что после нажатия кнопки "Скачать" начинается формирование файла, и после того как он сформируется - начинается скачивание, отсюда и различие в ожидании.