Как запустить тест на нескольких браузерах одновременно?Селеновая сетка, C #, Specflow, NUnit - PullRequest
2 голосов
/ 28 июня 2019

Я прыгал между гидами и видео на YouTube, пытаясь внедрить Selenium Grid 2 в существующий проект в течение нескольких дней, и я застрял, пожалуйста, помогите!

Наша структура - Specflow 3.0.220, Selenium WebDriver 3.141.0, C #, NUnit 3.12.0, Selenium Grid, селен-сервер-автономный-3.141.59.

Мои первоначальные цели по внедрению Selenium Grid 2 заключаются в следующем:

  1. Установите концентратор и узлы на моем локальном компьютере = готово.
  2. Запустить тест через один из узлов = готово.
  3. Запуск теста на всех узлах одновременно = головная боль.

Что касается пункта 2, я настроил два узла, один - узел Chrome, а другой - узел Firefox. Я могу выполнить тест через них обоих, но не одновременно.

Я чувствую, что мне здесь не хватает части головоломки.

Вот установка:

Scenario Outline: Log in
    Given I launch the site for <profile> and <environment> and <parallelEnvironment>
    When I log in to the Normal account
    Then I see that I am logged in

        Examples:
        | profile  | environment | parallelEnvironment |
        | parallel | Chrome75    | grid                |

Если профиль параллельный, а параллельная среда является сеткой, среда игнорируется. Причина параллельной среды состоит в том, что мы все еще можем использовать Browserstack во время настройки Selenium Grid.

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

Настройка драйвера выглядит следующим образом:

namespace OurAutomation
{
    [Binding]
    public sealed class BrowserStack
    {
        private BrowserStackDriver bsDriver;
        public static BrowserStackDriver bdriver;

        [BeforeScenario]
        public void BeforeScenario()
        {
            bsDriver = new BrowserStackDriver();
            bdriver = bsDriver;
        }

        [AfterScenario]
        public void AfterScenario()
        {
            bsDriver.Cleanup();
        }
    }

    public class CustomRemoteWebDriver : RemoteWebDriver
    {
        public CustomRemoteWebDriver(Uri remoteAddress, ChromeOptions options) : base(remoteAddress, options)
        {
        }

        public string getSessionID()
        {
            return base.SessionId.ToString();
        }
    }

    public class BrowserStackDriver
    {
        private IWebDriver driver;
        public static bool isBrowserStack = false;
        public static string Platform;
        public static string theEnvironment;
        public static string sessionId;

        public BrowserStackDriver()
        {

        }

        public string GetString(string property)
        {
            if (TestContext.Parameters[property] == null)
            {
                throw new ArgumentException("Property does not exist, does not have a value, or a test setting is not selected. You may need to add the .runsettings file in Visual Studio (Test > Test Settings > Select Test Settings File).");
            }
            else
            {
                return TestContext.Parameters[property].ToString();
            }
        }

        public IWebDriver Init(string profile, string environment, string parallelEnvironment)
        {
            String testString = GetString("BuildNumber");

            theEnvironment = environment;

            NameValueCollection caps = ConfigurationManager.GetSection("capabilities/" + profile) as NameValueCollection;
            NameValueCollection settings = ConfigurationManager.GetSection("environments/" + environment) as NameValueCollection;

            ChromeOptions chromeOptions = new ChromeOptions();

            if (profile == "single")
            {
// logic to invoke relevant browser locally based on Specflow parameter 'profile'
                Thread.Sleep(3000);
            }
            else if (profile == "parallel")
            {    
                if (parallelEnvironment == "browserstack")
                {
                    foreach (string key in caps.AllKeys)
                    {
                        chromeOptions.AddAdditionalCapability(key, caps[key]);
                    }

                    foreach (string key in settings.AllKeys)
                    {
                        chromeOptions.AddAdditionalCapability(key, settings[key]);
                    }

                    string username = Environment.GetEnvironmentVariable("BROWSERSTACK_USERNAME");

                    if (username == null)
                    {
                        username = ConfigurationManager.AppSettings.Get("user");
                    }

                    string accesskey = Environment.GetEnvironmentVariable("BROWSERSTACK_ACCESS_KEY");

                    if (accesskey == null)
                    {
                        accesskey = ConfigurationManager.AppSettings.Get("key");
                    }

                    chromeOptions.AddAdditionalCapability("browserstack.user", username);
                    chromeOptions.AddAdditionalCapability("browserstack.key", accesskey);
                    chromeOptions.AddAdditionalCapability("browserstack.local", "true");
                    chromeOptions.AddAdditionalCapability("build", GetString("BuildNumber"));
                    chromeOptions.AddAdditionalCapability("name", TestContext.CurrentContext.Test.MethodName);
                    chromeOptions.AddAdditionalCapability("project", GetString("Project"));

                    BrowserStackDriver.isBrowserStack = true;

                    driver = new CustomRemoteWebDriver(
                    new Uri("http://" + ConfigurationManager.AppSettings.Get("server") + "/wd/hub/"), chromeOptions);

                    CustomRemoteWebDriver browserRemoteDriver = driver as CustomRemoteWebDriver;
                    sessionId = browserRemoteDriver.getSessionID();
                }
                else if (parallelEnvironment == "grid")
                {
                    driver = new RemoteWebDriver(new Uri("http://000.00.00.00:4444/wd/hub"), chromeOptions);
                }
            }

            return driver;
        }

        public void Cleanup()
        {
            Thread.Sleep(2000);
            if (isBrowserStack)
            {
                Log.Status status = (TestContext.CurrentContext.Result.Message == null) ? Log.Status.Passed : Log.Status.Failed;
                string reason = (TestContext.CurrentContext.Result.Message == null) ? "Passed" : "Error see exception";

                Log.UpdateTestStatus(status, reason, sessionId);
            }

            driver.Quit();
            driver = null;
        }
    }
}

Так что здесь ...

                else if (parallelEnvironment == "grid")
                {
                    driver = new RemoteWebDriver(new Uri("http://000.00.00.00:4444/wd/hub"), chromeOptions);
                }

... Я ввожу адрес одного из узлов, и тест проводится. Тем не менее, я просто хочу отправить тест на концентратор и затем выполнить его одновременно на всех активных узлах в связанных браузерах. Как мне этого добиться? Похоже, что руководства и видео только уводят меня.

спасибо

UPDATE:

Так что я продолжаю двигаться в правильном направлении, я думаю. Пришлось вернуться к основам, чтобы я мог видеть, как реализовать это в моем существующем проекте. Я сделал эту работу в моей сетке: https://github.com/teixeira-fernando/Parallel-Execution-with-Selenium-Grid

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

    namespace Tutorial_parallel_execution
{
    [TestFixture(BrowserType.Chrome)]
    [TestFixture(BrowserType.Firefox)]
    [TestFixture(BrowserType.Opera)]
    [TestFixture(BrowserType.IE)]
    [Parallelizable(ParallelScope.Fixtures)]
    public class GoogleTesting : Hooks
    {
        public GoogleTesting(BrowserType browser) : base(browser)
        {

        }

        [Test]
        public void GoogleTest()
        {
            Driver.Navigate().GoToUrl("http://www.google.com");
            Driver.FindElement(By.Name("q")).SendKeys("selenium");
            Driver.FindElement(By.Name("btnK")).Click();
            Assert.That(Driver.PageSource.Contains("Selenium"), Is.EqualTo(true),
                "The text selenium doenst exist");
        }
    }

}

Однако, так как мой проект начал жаловаться так же, как это Расширение SpecFlow Visual Studio попыталось использовать генератор кодового выделения SpecFlow 1.9 , я начал использовать SpecFlow.Tools.MsBuild.Generation и потерял доступ к тестам ( файлы кода) для добавления атрибутов. Единственный атрибут, который я могу добавить, это [Parallelizable (ParallelScope.Fixtures)], но я должен поместить его в AssemblyInfo.cs - другие атрибуты не могут быть добавлены туда.

Нужно ли понижать версию Specflow / Selenium и т. Д., Чтобы эта работа работала?

1 Ответ

0 голосов
/ 16 июля 2019

Мне удалось вырезать код, необходимый для реализации параллельного выполнения, используя ThreadLocal из https://github.com/minhhoangvn/AutomationFramework

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...