【发布时间】:2018-11-01 11:09:58
【问题描述】:
我是刚入门的 Specflow 新手,希望有人能帮助我吗?这可能都是我自己对它应该如何工作的误解,但希望有人能帮助我进步。
所以!我正在处理一个测试项目,其中包含 2 个功能文件和 2 个 Step 类文件(以及使用 POM 的页面文件)。
1.) ServiceSchedules.feature 2.) ServiceSchedulesSteps.cs 3.) 登录功能 4.) LoginPageSteps.cs
两个功能文件共享一个步骤,“并且浏览器已关闭”,以在每个场景结束时关闭浏览器。这适用于 Login.feature 文件中的场景测试,但不适用于其他功能文件 ServiceSchedules.feature 中的场景测试,该文件在此步骤中使用“Driver.Dispose”失败。它返回以下错误;
System.NullReferenceException : 对象引用未设置为 对象的实例。
我希望可以跨功能文件共享该步骤? (也许不是我想要的方式?)
作为旁注,我很欣赏这可能不是最佳实践,因为我知道您可以使用挂钩,但是当我尝试使用 AfterScenario Hook 尝试在每次测试后关闭浏览器时遇到了另一个问题。当从 ServiceSchedules.feature 文件运行相同的场景测试时,它返回了另一个错误(使用与下面相同的代码);
System.ArgumentException : 定位器对象的 SearchContext 不能为空参数名称:定位器
但回到我当前的问题 - 这是我的文件; 功能文件 1:登录功能
@All @Login
Feature: LoginPage
In order to use the Program
As a User
I want to be be able to see the login Page
Background:
Given I want to login
@Content
Scenario: LoginPageContent
When I view the Login Page
Then everything I need to login is present
And the browser is closed
@ErrorMessage
Scenario: InvalidLoginError
When I enter invalid Username of "!£$%^&*^%?["
And enter an invalid Password "£$%^&*£!"
And the submit button is pressed
Then an Invalid Name or Password error will display on a popup
And the browser is closed
@ErrorMessage
Scenario: NoLoginDetailsError
And I have not entered a username
And I have not entered a password
When the submit button is pressed
Then an error message will display under the username field of "The User name field is required."
And an error message will display under the password field of "The Password field is required."
And the browser is closed
LoginPageSteps.cs
using NUnit.Framework;
using OpenQA.Selenium;
using System;
using System.Threading;
using TechTalk.SpecFlow;
namespace Selenium.Services.SpecFlow2.SpecFlow.CodedSteps
{
[Binding]
public class LoginPageSteps
{
public IWebDriver Driver { get; set; }
[Given(@"I want to login")]
public void GivenIWantToLogin()
{
Driver = UserActions.IntializeDriver();
}
[Given(@"I have not entered a username")]
public void GivenIHaveNotEnteredAUsername()
{
var signinpage = new SignInPage(Driver);
Thread.Sleep(10);
signinpage.UserNameS.Clear();
}
[Given(@"I have not entered a password")]
public void GivenIHaveNotEnteredAPassword()
{
var signinpage = new SignInPage(Driver);
Thread.Sleep(10);
signinpage.PasswordS.Clear();
}
[When(@"I view the Login Page")]
public void WhenIViewTheLoginPage()
{
Thread.Sleep(2000);
Assert.AreEqual(Driver.Url, "http://qa-URL-Ommitted");
}
[When(@"I enter invalid Username of ""(.*)""")]
public void WhenIEnterInvalidUsernameOf(string invalidUsername)
{
var signinpage = new SignInPage(Driver);
Thread.Sleep(10);
signinpage.UserNameS.Clear();
signinpage.UserNameS.SendKeys(invalidUsername);
}
[When(@"enter an invalid Password ""(.*)""")]
public void WhenEnterAnInvalidPassword(string invalidPassword)
{
var signinpage = new SignInPage(Driver);
Thread.Sleep(10);
signinpage.PasswordS.Clear();
signinpage.PasswordS.SendKeys(invalidPassword);
}
[When(@"the submit button is pressed")]
public void WhenTheSubmitButtonIsPressed()
{
var signinpage = new SignInPage(Driver);
signinpage.SubmitButtonS.Click();
}
[Then(@"everything I need to login is present")]
public void ThenEverythingINeedToLoginIsPresent()
{
var UserActions = new UserActions(Driver);
var signinpage = new SignInPage(Driver);
UserActions.WaitForElement(Driver, signinpage.TimeServicesSignInTitle);
UserActions.WaitForElement(Driver, signinpage.UserNameText);
UserActions.WaitForElement(Driver, signinpage.PasswordText);
UserActions.WaitForElement(Driver, signinpage.RememberMeText);
}
[Then(@"the browser is closed")]
public void ThenTheBrowserIsClosed()
{
Driver.Dispose();
}
[Then(@"an Invalid Name or Password error will display on a popup")]
public void ThenAnInvalidNameOrPasswordErrorWillDisplayOnAPopup()
{
var signinpage = new SignInPage(Driver);
bool InvalidPopUp = signinpage.InvalidPasswordAndOrUserNameS.Displayed;
}
[Then(@"an error message will display under the username field of ""(.*)""")]
public void ThenAnErrorMessageWillDisplayUnderTheUsernameFieldOf(string usernameError)
{
var signinpage = new SignInPage(Driver);
var UserActions = new UserActions(Driver);
UserActions.WaitForElement(Driver, signinpage.UserNameRequired);
Assert.AreEqual(usernameError, signinpage.UserNameRequiredS.Text);
}
[Then(@"an error message will display under the password field of ""(.*)""")]
public void ThenAnErrorMessageWillDisplayUnderThePasswordFieldOf(string passwordError)
{
var signinpage = new SignInPage(Driver);
var UserActions = new UserActions(Driver);
UserActions.WaitForElement(Driver, signinpage.PasswordRequired);
Assert.AreEqual(passwordError, signinpage.PasswordRequiredS.Text);
}
}
}
功能文件 2:ServiceSchedule 功能
@All @ServiceSchedules
Feature: ServiceSchedules
In order to use the Program
As a User
I want to be be able to easily Search, Create and Edit ServiceSchedules upon login, from the homepage
Background:
Given I have logged on
@Content
Scenario: ServiceScheduleLoginPageContent
When I view the Homepage Page
Then I am taken to the Dashboard ServiceSchedules homepage
And the correct breadcrumb of "Dashboard" and "Serivce Schedules" are present
And the Customer Details search options appear
And the Export and Search buttons appear
And the results pane appears
And the results pane has a quick filter
And the browser is closed
ServiceScheduleSteps.cs
using NUnit.Framework;
using OpenQA.Selenium;
using System;
using System.Threading;
using TechTalk.SpecFlow;
using Selenium.Services.SpecFlow2.Pages;
namespace Selenium.Services.SpecFlow2
{
[Binding]
public class ServiceSchedulesSteps
{
public IWebDriver Driver { get; private set; }
[When(@"I view the Homepage Page")]
public void WhenIViewTheHomepagePage()
{
Thread.Sleep(2000);
Assert.AreEqual(Driver.Url, "http://qa-URL-Omitted");
}
[Given(@"I have logged on")]
public void GivenIHaveLoggedOn()
{
Driver = UserActions.IntializeDriver();
SignInPage signinpage = new SignInPage(Driver);
UserActions.FillLogInField(Config.Credentials.Valid.Username, Config.Credentials.Valid.Password, Driver);
signinpage.SubmitButtonS.Click();
Thread.Sleep(1000);
}
[Then(@"I am taken to the Dashboard ServiceSchedules homepage")]
public void ThenIAmTakenToTheDashboardServiceSchedulesHomepage()
{
var homePage = new HomePage(Driver);
var UserActions = new UserActions(Driver);
UserActions.WaitForElement(Driver, homePage.BreadCrumbServiceSchedules);
}
[Then(@"the top navigation is present")]
public void ThenTheTopNavigationIsPresent()
{
var menu = new Menu(Driver);
bool MenuAdmin = menu.Admin.Displayed;
bool MenuWorkShop = menu.WorkShops.Displayed;
bool MenuParts = menu.JobTemplate.Displayed;
bool MenuSearch = menu.Search.Displayed;
}
[Then(@"the correct breadcrumb of ""(.*)"" and ""(.*)"" are present")]
public void ThenTheCorrectBreadcrumbOfAndArePresent(string breadcrumb1, string breadcrumb2)
{
var homePage = new HomePage(Driver);
var UserActions = new UserActions(Driver);
UserActions.WaitForElement(Driver, homePage.BreadCrumbDashboard);
Assert.AreEqual(breadcrumb1, homePage.BreadCrumbDashboardS.Text);
UserActions.WaitForElement(Driver, homePage.BreadCrumbServiceSchedules);
Assert.AreEqual(breadcrumb2, homePage.BreadCrumbServiceSchedulesS.Text);
}
[Then(@"the Customer Details search options appear")]
public void ThenTheCustomerDetailsSearchOptionsAppear()
{
var homePage = new HomePage(Driver);
var UserActions = new UserActions(Driver);
//Pane Expand Button
UserActions.WaitForElement(Driver, homePage.FilterSchedulesExpandButton);
UserActions.WaitForElement(Driver, homePage.CustomerNameField);
UserActions.WaitForElement(Driver, homePage.CustomerEmailField);
UserActions.WaitForElement(Driver, homePage.CustomerPhoneField);
UserActions.WaitForElement(Driver, homePage.CustomerPostcodeField);
}
[Then(@"the Export and Search buttons appear")]
public void ThenTheExportAndSearchButtonsAppear()
{
var homePage = new HomePage(Driver);
var UserActions = new UserActions(Driver);
UserActions.WaitForElement(Driver, homePage.ExportButton);
UserActions.WaitForElement(Driver, homePage.SearchButton);
}
[Then(@"the results pane appears")]
public void ThenTheResultsPaneAppears()
{
var homePage = new HomePage(Driver);
var UserActions = new UserActions(Driver);
UserActions.WaitForElement(Driver, homePage.CustomerResultsTable);
UserActions.WaitForElement(Driver, homePage.RTableCustomerNo);
UserActions.WaitForElement(Driver, homePage.RTableCustomer);
UserActions.WaitForElement(Driver, homePage.RTableWatch);
UserActions.WaitForElement(Driver, homePage.RTableTotalCosts);
UserActions.WaitForElement(Driver, homePage.RTableDates);
UserActions.WaitForElement(Driver, homePage.RTableActions);
UserActions.WaitForElement(Driver, homePage.Pagination);
}
[Then(@"the results pane has a quick filter")]
public void ThenTheResultsPaneHasAQuickFilter()
{
var homePage = new HomePage(Driver);
var UserActions = new UserActions(Driver);
UserActions.WaitForElement(Driver, homePage.QuickFilter);
}
}
}
希望我已经付出了足够的努力 - 其他一切正常,只是无法理解为什么 LoginPageSteps.cs 中的“并且浏览器已关闭”步骤不会与 ServiceSchedules.feature 中的场景/测试共享文件。我在想这可能与方式有关,我首先在哪里初始化驱动程序?不知道我该如何做不同的事情..
我确实发现我能够在 ServiceSchedules.feature 和 ServiceSchedulesSteps.cs 文件中创建一个新步骤“浏览器关闭”,而且效果很好,但这当然意味着我有两个相同的步骤,他们真的应该从一个地方和文件共享 - 这就是我认为它应该全部工作的方式!
非常感谢对此提供的任何帮助 - 我对此表示歉意,这是我错过或没有理解的明显和愚蠢的事情 - 我正在学习并且对编码相对较新:)
干杯
【问题讨论】: