SeleniumをMSTestで単体テスト　　--メモ--

Visual Studioで新規プロジェクトを**単体テストプロジェクト(.NET Framework)**で作成。
NuGetで**WebDriver　chromedriver firefoxdriver**などを適宜インストール。

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
と追加。

#ひな形の作成

[TestClass]と[TestMethod]はMSTestで重要な属性。

[TestInitialize]はテスト実行前、
[TestCleanup]はテスト実行後に呼び出されることを示す属性。

```csharp
    [TestClass]
    public class UnitTest1
    {
        protected ChromeDriver driver;

        [TestInitialize]
        public void CreateDriver()
        {
            driver = new ChromeDriver();
        }

        [TestMethod]
        public void ClickTestExample()
        {  
            driver.Navigate().GoToUrl("http://www.selenium.academy/Examples/Interaction.html");
            IWebElement button = driver.FindElement(By.Id("button"));
            button.Click();
        }

        [TestCleanup]
        public void QuitDriver()
        {
            if (driver != null)
                driver.Quit();
        }
    }

```

#カスタム属性の作成、利用

カスタム属性を作って、ブラウザやURLを指定する。
https://selenium.academy/  のサンプルからサーバー関連などをそぎ落として若干シンプルにした。

```csharp

using System;
using System.Linq;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;

namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
        protected IWebDriver driver;
        public TestContext TestContext { get; set; }

        [TestInitialize]
        public void CreateDriver()
        {
            BrowserAttribute browser = (BrowserAttribute)GetCustomAttribute<BrowserAttribute>(TestContext.FullyQualifiedTestClassName, TestContext.TestName);

            if (browser == null)
            {
                throw new InvalidOperationException("Browser属性が指定されていません。 ");
            }

            switch (browser.Browser)
            {
                case "Chrome":
                    driver = new ChromeDriver();
                    break;
                case "Firefox":
                    driver = new FirefoxDriver();
                    break;
                default:
                    throw new InvalidOperationException("Browser " + browser.Browser + " not found!");
            }

            PageAttribute page = (PageAttribute)GetCustomAttribute<PageAttribute>(TestContext.FullyQualifiedTestClassName, TestContext.TestName);
            if (page == null)
            {
                throw new InvalidOperationException("No Page attribute is specified. ");
            }

            driver.Navigate().GoToUrl(page.Url);

        }
        [TestMethod]
        [Browser(Browser = "Firefox")]
        [Page(Url = "http://www.selenium.academy/Examples/Interaction.html")]
        public void Clickテスト()
        {
            Console.WriteLine();
            IWebElement button = driver.FindElement(By.Id("button"));
            button.Click();
        }

        [TestCleanup]
        public void QuitDriver()
        {
            if (driver != null)
                driver.Quit();
        }

        private Attribute GetCustomAttribute<T>(string className, string testName)
        {
            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                var currentType = assembly.GetTypes().FirstOrDefault(f => f.FullName == className);

                if (currentType == null)
                    continue;

                Attribute classAttribute = currentType.GetCustomAttribute(typeof(T));
                if (classAttribute != null)
                {
                    return classAttribute;
                }

                var currentMethod = currentType.GetMethod(testName);

                Attribute methodAttribute = currentMethod.GetCustomAttribute(typeof(T));
                if (methodAttribute != null)
                {
                    return methodAttribute;
                }
            }

            return null;
        }

        [AttributeUsage(validOn: AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
        public class BrowserAttribute : Attribute
        {
            public string Browser { get; set; }
            public string Version { get; set; }
            public string Url { get; set; }
        }

    }

    [AttributeUsage(validOn: AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
    public class PageAttribute : Attribute
    {
        public string Url { get; set; }

    }
}


```

[参考]
[Creating A Selenium Testing Framework In C#](https://selenium.academy/creating-a-selenium-testing-framework-in-c/)
[MsTestによるユニットテストの解説](https://qiita.com/mima_ita/items/55394bcc851eb8b6dc24)