Selenium Webdriver C# - 从Test Suite在VS 2017中运行多个测试用例

时间:2018-02-09 09:59:40

标签: selenium-webdriver pageobjects

我一直在研究Page Object Framework,它将根据页面对测试套件进行分类。我已经遵循了所有步骤,以建立一个体面的框架。

我的每个单元测试,包含一个遵循简单步骤的方法。到目前为止,我已经能够创建一些自动化测试用例。当我想从测试套件中运行多个测试用例时,问题就开始了。我有一个chrome web驱动程序实例,它位于一个单独的类中。以下是一个例子:

using System;
using System.Dynamic;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;

namespace SystemUiAutomationTestFramework
{
    public static class Browser
    {
        private static readonly IWebDriver _webDriver = new ChromeDriver(Properties.Settings.Default.ChromePathDriver);

        public static IWebDriver WebDriver {
            get { return _webDriver; }
        }
        public static ISearchContext Driver
        {
            get { return _webDriver; }
        }

        public static string Url
        {
            get { return _webDriver.Url; }
        }

        public static string Title
        {
            get { return _webDriver.Title; }
        }

        public static void Goto(string url)
        {
            _webDriver.Manage().Window.Maximize();
            _webDriver.Url = url;

        }

        public static void Close()
        {
            _webDriver.Quit();
        }
    }
}

运行时的每个测试用例都是独立的,正如良好实践所示,应该没有测试订单实现,因为它会生成流。我将放置两个示例来检查简单的登录操作和登录验证。 您可以在下面找到登录页面的类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.PageObjects;
using OpenQA.Selenium.Support.UI;


namespace SystemUiAutomationTestFramework
{
    public class LoginPage
    {
        static string Url = "http://..";
        private static string LoginUrl = "http://...";

        private static string PageTitle = "System title page";
        private static string LoginPlaceholder = "Login";
        private static string PswdPlaceholder = "Password";
        private static string ButtonText = "Sign in";
        private static string ErrorMessage = "Wrong login or password";

        /* LoginPage Elements */

        [FindsBy(How = How.Id, Using = "inputLogin")]
        private IWebElement inputLogin;

        [FindsBy(How = How.Id, Using = "inputPassword")]
        private IWebElement inputPassword;

        [FindsBy(How = How.TagName, Using = "button")]
        private IWebElement loginButton;

        [FindsBy(How = How.ClassName, Using = "errorMsg")]
        private IWebElement errorMessage;

        /*----------------------------------------*/


        public void Goto()
        {
            Browser.Goto(Url);
        }

        public bool IsAtLoginPage()
        {
            return Browser.Url == LoginUrl;
        }

        public bool IsAtLoginPageTitle()
        {
            return Browser.Title == PageTitle;
        }

        public bool IsAtLoginField()
        {
            return inputLogin.GetAttribute("placeholder") == LoginPlaceholder;
        }

        public bool IsAtPswdField()
        {
            return inputPassword.GetAttribute("placeholder") == PswdPlaceholder;
        }

        public bool IsAtLoginButton()
        {
            return loginButton.Text == ButtonText;
        }

        public void InputCredentials(string userName, string userPassword)
        {
            inputLogin.SendKeys(userName);
            inputPassword.SendKeys(userPassword);
            loginButton.Click();
        }

        public void WaitErrorMessage()
        {
            WebDriverWait wait = new WebDriverWait(Browser.WebDriver, TimeSpan.FromSeconds(10));
            wait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(By.ClassName("errorMsg")));
        }

        public bool IsAtErrorMessage()
        {
            return errorMessage.Text == ErrorMessage;
        }


        public void ReportPageSuccessLogin()
        {
            Console.WriteLine("Application Url checked");
            Console.WriteLine("Application Title checked");
            Console.WriteLine("Login Field present");
            Console.WriteLine("Password Field checked");
            Console.WriteLine("Sign in button checked");
            Console.WriteLine("Login ssuccess");
        }

        public void ReportPageValidationTest()
        {
           ReportPageSuccessLogin();
           Console.WriteLine("Fake Credentials entered");
           Console.WriteLine("Login Button Pressed");
           Console.WriteLine("Login or Password validation message displayed: " + errorMessage.Displayed);
        }
    }
}

我还有一个用于Pagefactoring的API类。举个例子:

 public static class Pages
    {
        public static LoginPage LoginPage
        {
            get
            {
                var loginPage = new LoginPage();
                PageFactory.InitElements(Browser.Driver, loginPage);
                return loginPage;
            }
        }

现在,对于测试用例,在用户在登录页面上的示例下面,所有元素都被替换,登录系统,系统检查用户是否已登录并关闭实例。

using System;
using System.Runtime.Remoting.Channels;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SystemUiAutomationTestFramework;

namespace TestSuite.LoginPage
{
    [TestClass]
    public class LoginPageTest
    {
        [TestMethod]
        public void Can_Go_LoginPage()
        {
            Pages.LoginPage.Goto();
            Assert.IsTrue(Pages.LoginPage.IsAtLoginPage());
            Assert.IsTrue(Pages.LoginPage.IsAtLoginPageTitle());
            Assert.IsTrue(Pages.LoginPage.IsAtLoginField());
            Assert.IsTrue(Pages.LoginPage.IsAtPswdField());
            Assert.IsTrue(Pages.LoginPage.IsAtLoginButton());
            Pages.LoginPage.InputCredentials(SettingsService.Username, SettingsService.Userpassword);
            Pages.HomePage.IsAtHomePage();

            Pages.LoginPage.ReportPageSuccessLogin();
        }

        [TestCleanup]
        public void CleanUp()
        {
            Browser.Close();
        }
    }
}

另一个只是通过提供虚假的登录名和密码来验证登录页面,如果错误消息被正确显示,则测试用例也会通过关闭实例来完成。

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SystemUiAutomationTestFramework;

namespace TestSuite.LoginPage
{
    [TestClass]
    public class LoginPageValidationTest
    {
        [TestMethod]
        public void Can_Validate_LoginPage()
        {
            Pages.LoginPage.Goto();
            Assert.IsTrue(Pages.LoginPage.IsAtLoginPage());
            Assert.IsTrue(Pages.LoginPage.IsAtLoginPageTitle());
            Assert.IsTrue(Pages.LoginPage.IsAtLoginField());
            Assert.IsTrue(Pages.LoginPage.IsAtPswdField());
            Assert.IsTrue(Pages.LoginPage.IsAtLoginButton());
            Pages.LoginPage.InputCredentials("abcd.efgh", "test123");
            Pages.LoginPage.WaitErrorMessage();
            Assert.IsTrue(Pages.LoginPage.IsAtErrorMessage());

            Pages.LoginPage.ReportPageValidationTest();

        }

        [TestCleanup]
        public void CleanUp()
        {
            Browser.Close();
        }
    }
}

现在问题发生在我从登录页面测试套件中尝试这两个测试用例时,一个完成,因为另一个测试用例失败了。从错误消息中,我理解这是因为另一个测试用例正在尝试使用已经运行的Webdriver实例。

我想知道您的意见/指南/解决方案我该如何解决这个问题。我为长篇文章道歉,但我认为如果我放置代码,您就很容易理解我的问题。

致以最诚挚的问候,感谢您的回答或将我与我的问题重复或已有解决方案的主题联系起来。

1 个答案:

答案 0 :(得分:0)

我能够自己解决这个问题。我创造了一个 我的驱动程序类的属性和每次调用测试类时调用的Initialize方法。还重构了我的代码以使其更灵活。