Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Реализация многопоточности C# +WebDriver


(dmarapov) #1

Появилась необходимость запустить 1 тест в 30 потоков.

Тест написан на C# +WebDriver.

Пытался следующим образом:

 

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
 
namespace Mlg
{
    public class MultithreadRunner
    {
        public int MaxThreads { get; private set; }
 
        public MultithreadRunner(int maxThreads)
        {
            MaxThreads = maxThreads;
            ThreadPool.SetMaxThreads(maxThreads, maxThreads);
        }
 
        private List<Task> tasks = new List<Task>();
 
        public void ActionRun(Action runMethod, int iterations)
        {
            while (iterations > 0)
            {
                iterations--;
                Task t = new Task(runMethod,TaskCreationOptions.AttachedToParent);
                tasks.Add(t);
                t.Start();
                //ThreadPool.QueueUserWorkItem(new WaitCallback(runMethod));
            }
 
            Task.WaitAll(tasks.ToArray());
 
            foreach (var task in tasks)
            {
                task.Dispose();
            }
 
            tasks = null;
        }
    }
}
 
 
 
        [TestMethod]
        public void TestEx()
        {
            MultithreadRunner runner = new MultithreadRunner(4);
 
            runner.ActionRun(Do, 4);
        }
 
        private void Do()
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "     " + DateTime.Now);
            BoDriverImpl driver = new BoDriverImpl();
            driver.SetupTest();
            for (int i = 0; i < 3; i++)
            {
                driver.Login(); 
            }
        }
 
   driver.Login();  - метод со степами.
 
Проблема в том, что запускается 4 браузера но степы выполняются тлько в 2х.
 
В чем может быть проблема? Какой еще способ многопоточного запуска можете предложить?
Задача единоразовая, уместны кривые способы.
 
Спасибо. 

 


(Дмитрий Жарий) #2

 

А как вы работаете с вебдрайвером внутри BoDriverImpl? 
 
Вы используете статические переменные? 
Если да, то советую воспользоваться атрибутом [ThreadStatic]
 
Попробуйте переписать код более примитивно, выкинув лишние классы, в стиле аля Recor and Play и инициализировать вебдрайвер внутри Таска. 

(qaleader) #3

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

Есть ли выход из этой проблемы? Возможно необходимо сделать несколько профилей браузера? Что делать с фокусировкой на окне браузера?


(Дмитрий Жарий) #4

 

Тут скорее дело не в вебдрайвере, а в настройках многопоточности и потребляемых ресурсах.

Код ниже, отлично работает в 5-ти FireFox'ах одновременно, с учетом того, что все очень жестко тормозит, потому что FF то не мало ресурсов отжирает.

А использование ThreadPool, например, говорит системе, чтобы она сама позаботилась о создании потоков. Т.е. если вы говорите создать 5 потоков через ThreadPool, то они будут созданы, но не одновременно, а с учетом текущей загрузки ресурсов системы. 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
class Program
{
private static List<Task> tasks = new List<Task>();

    <span style="color:#508050; font-weight:bold; ">private</span> <span style="color:#508050; font-weight:bold; ">static</span> <span style="color:#508050; font-weight:bold; ">void</span> Worker<span style="color:#808030; ">(</span>IWebDriver driver<span style="color:#808030; ">,</span> <span style="color:#508050; font-weight:bold; ">string</span> s<span style="color:#808030; ">)</span>
    <span style="color:#800080; ">{</span>
        Console<span style="color:#808030; ">.</span>WriteLine<span style="color:#808030; ">(</span><span style="color:#800000; ">"</span><span style="color:#cc5555; ">Started:</span><span style="color:#800000; ">"</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        driver<span style="color:#808030; ">.</span>Navigate<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span><span style="color:#808030; ">.</span>GoToUrl<span style="color:#808030; ">(</span><span style="color:#800000; ">"</span><span style="color:#cc5555; ">http://yandex.ru</span><span style="color:#800000; ">"</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        var txtSearchBox <span style="color:#808030; ">=</span> driver<span style="color:#808030; ">.</span>FindElement<span style="color:#808030; ">(</span>By<span style="color:#808030; ">.</span>CssSelector<span style="color:#808030; ">(</span><span style="color:#800000; ">"</span><span style="color:#cc5555; ">input[tabindex='1']</span><span style="color:#800000; ">"</span><span style="color:#808030; ">)</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        txtSearchBox<span style="color:#808030; ">.</span>SendKeys<span style="color:#808030; ">(</span><span style="color:#800000; ">"</span><span style="color:#cc5555; ">Webdriver in Yandex</span><span style="color:#800000; ">"</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        Thread<span style="color:#808030; ">.</span>Sleep<span style="color:#808030; ">(</span><span style="color:#778c77; ">2000</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        txtSearchBox<span style="color:#808030; ">.</span>Clear<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        txtSearchBox<span style="color:#808030; ">.</span>SendKeys<span style="color:#808030; ">(</span><span style="color:#800000; ">"</span><span style="color:#cc5555; ">It works, it works it works!</span><span style="color:#800000; ">"</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        Thread<span style="color:#808030; ">.</span>Sleep<span style="color:#808030; ">(</span><span style="color:#778c77; ">2000</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        txtSearchBox<span style="color:#808030; ">.</span>Clear<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        txtSearchBox<span style="color:#808030; ">.</span>SendKeys<span style="color:#808030; ">(</span><span style="color:#800000; ">"</span><span style="color:#cc5555; ">2 It works, it works it works!</span><span style="color:#800000; ">"</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        Thread<span style="color:#808030; ">.</span>Sleep<span style="color:#808030; ">(</span><span style="color:#778c77; ">1000</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        txtSearchBox<span style="color:#808030; ">.</span>Clear<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        txtSearchBox<span style="color:#808030; ">.</span>SendKeys<span style="color:#808030; ">(</span><span style="color:#800000; ">"</span><span style="color:#cc5555; ">3 It works, it works it works!</span><span style="color:#800000; ">"</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        Thread<span style="color:#808030; ">.</span>Sleep<span style="color:#808030; ">(</span><span style="color:#778c77; ">2000</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        txtSearchBox<span style="color:#808030; ">.</span>Clear<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        txtSearchBox<span style="color:#808030; ">.</span>SendKeys<span style="color:#808030; ">(</span><span style="color:#800000; ">"</span><span style="color:#cc5555; ">4 It works, it works it works!</span><span style="color:#800000; ">"</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        Thread<span style="color:#808030; ">.</span>Sleep<span style="color:#808030; ">(</span><span style="color:#778c77; ">2000</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        txtSearchBox<span style="color:#808030; ">.</span>Clear<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        txtSearchBox<span style="color:#808030; ">.</span>SendKeys<span style="color:#808030; ">(</span><span style="color:#800000; ">"</span><span style="color:#cc5555; ">5 It works, it works it works!</span><span style="color:#800000; ">"</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        Thread<span style="color:#808030; ">.</span>Sleep<span style="color:#808030; ">(</span><span style="color:#778c77; ">1000</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        txtSearchBox<span style="color:#808030; ">.</span>SendKeys<span style="color:#808030; ">(</span>Keys<span style="color:#808030; ">.</span>Enter<span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
    <span style="color:#800080; ">}</span>

    <span style="color:#508050; font-weight:bold; ">static</span> <span style="color:#508050; font-weight:bold; ">void</span> Main<span style="color:#808030; ">(</span><span style="color:#508050; font-weight:bold; ">string</span><span style="color:#808030; ">[</span><span style="color:#808030; ">]</span> args<span style="color:#808030; ">)</span>
    <span style="color:#800080; ">{</span>
        <span style="color:#508050; font-weight:bold; ">for</span> <span style="color:#808030; ">(</span><span style="color:#508050; font-weight:bold; ">int</span> i <span style="color:#808030; ">=</span> <span style="color:#778c77; ">0</span><span style="color:#800080; ">;</span> i <span style="color:#808030; ">&lt;</span> <span style="color:#778c77; ">5</span><span style="color:#800080; ">;</span> i<span style="color:#808030; ">+</span><span style="color:#808030; ">+</span><span style="color:#808030; ">)</span>
        <span style="color:#800080; ">{</span>

            var drv <span style="color:#808030; ">=</span> <span style="color:#508050; font-weight:bold; ">new</span> FirefoxDriver<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
            drv<span style="color:#808030; ">.</span>Navigate<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span><span style="color:#808030; ">.</span>GoToUrl<span style="color:#808030; ">(</span><span style="color:#800000; ">"</span><span style="color:#cc5555; ">http://google.com</span><span style="color:#800000; ">"</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
            Task task <span style="color:#808030; ">=</span> <span style="color:#508050; font-weight:bold; ">new</span> Task<span style="color:#808030; ">(</span><span style="color:#808030; ">(</span><span style="color:#808030; ">)</span> <span style="color:#808030; ">=</span><span style="color:#808030; ">&gt;</span> 
            <span style="color:#800080; ">{</span>
                Worker<span style="color:#808030; ">(</span>drv<span style="color:#808030; ">,</span> i<span style="color:#808030; ">.</span>ToString<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span> 
            <span style="color:#800080; ">}</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>

            tasks<span style="color:#808030; ">.</span>Add<span style="color:#808030; ">(</span>task<span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        <span style="color:#800080; ">}</span>

        <span style="color:#508050; font-weight:bold; ">foreach</span> <span style="color:#808030; ">(</span>var task <span style="color:#508050; font-weight:bold; ">in</span> tasks<span style="color:#808030; ">)</span>
        <span style="color:#800080; ">{</span>
            task<span style="color:#808030; ">.</span>Start<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        <span style="color:#800080; ">}</span>

        Console<span style="color:#808030; ">.</span>WriteLine<span style="color:#808030; ">(</span><span style="color:#800000; ">"</span><span style="color:#cc5555; ">Waiting </span><span style="color:#800000; ">"</span> <span style="color:#808030; ">+</span> DateTime<span style="color:#808030; ">.</span>Now<span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        Task<span style="color:#808030; ">.</span>WaitAll<span style="color:#808030; ">(</span>tasks<span style="color:#808030; ">.</span>ToArray<span style="color:#808030; ">(</span><span style="color:#808030; ">)</span><span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
        Console<span style="color:#808030; ">.</span>WriteLine<span style="color:#808030; ">(</span><span style="color:#800000; ">"</span><span style="color:#cc5555; ">Done </span><span style="color:#800000; ">"</span> <span style="color:#808030; ">+</span> DateTime<span style="color:#808030; ">.</span>Now<span style="color:#808030; ">)</span><span style="color:#800080; ">;</span>
    <span style="color:#800080; ">}</span>
<span style="color:#800080; ">}</span>

}


(dmarapov) #5

Спасибо, буду пробовать