将场景大纲与Specflow结合使用&;硒C#

将场景大纲与Specflow结合使用&;硒C#,c#,selenium,specflow,C#,Selenium,Specflow,我试图在Specflow中使用一个场景大纲,它将根据我拥有的示例数量生成测试,然后我可以通过C#绑定使用selenium编写测试。因此,我创建了以下功能: Scenario Outline: Login Given I have navigated to the Login Page When I enter a valid '<Login>' And I enter the correct '<Password>' And I press the Login CTA T

我试图在Specflow中使用一个场景大纲,它将根据我拥有的示例数量生成测试,然后我可以通过C#绑定使用selenium编写测试。因此,我创建了以下功能:

Scenario Outline: Login
Given I have navigated to the Login Page
When I enter a valid '<Login>'
And I enter the correct '<Password>'
And I press the Login CTA
Then I am logged into the Home Page

Examples: 
| Login  | Password   |
| LoginA | passwordA  | 
| LoginB | passwordB  |
我已将它们放入SpecFlow步骤定义文件中

我还生成了两个名为 登录(“LoginA”、“passwordA”、null) 登录(“LoginB”,“passwordB”,空)

到目前为止还不错(我认为)。接下来的步骤是编写代码来完成步骤定义,以便每个测试都将运行并使用相关数据。这是我一直坚持的一点

例如,我知道数据是否在标准场景中的表中,我可以从表中调用,因此-

Scenario: Login
Given I have navigated to the Login Page
When I enter a valid Login
| Login   |
| loginA  |
And I enter the correct Password
| Password   |
| passwordA |
And I press the Login CTA
Then I am logged into the Home Page
您可以对以下代码感到满意:

 public void WhenIEnterAValidLogin(Table table)
    {
        IWebElement loginField = WebBrowser.Current.FindElement(By.Name("loginBox"));
        string loginText = table.Rows[0]["Login"].ToString();
        usernameField.SendKeys(loginText);
    }
但基本上,我不知道如何编写代码,使其在“示例”表中显示,并获取每个测试的相关数据。这是可能的还是我必须为每个测试单独编写代码,即键入“loginA”的步骤和键入“loginB”的步骤?我环顾了一下网络,还没有找到一个对我有帮助的例子


提前谢谢你的帮助!如果我不清楚自己的意思或者犯了一些基本错误,请告诉我,因为我是堆栈溢出新手,这是我的第一篇文章。

我认为你想得太深了。如果您执行以下操作:

    [When(@"I enter a valid '(.*)'")]
    public void WhenIEnterAValid(string p0)
    {
        ScenarioContext.Current.Pending();
    }

    [When(@"I enter the correct '(.*)'")]
    public void WhenIEnterTheCorrect(string p0)
    {
        ScenarioContext.Current.Pending();
    }
Scenario Outline: Login
Given I have navigated to the Login Page
When I enter a valid '<Login>'
And I enter the correct '<Password>'
And I press the Login CTA
Then I am logged into the Home Page

Examples: 
| Login  | Password   |
| LoginA | passwordA  | 
| LoginB | passwordB  |
步骤代码得到重用。
场景大纲是一种很好的方法,可以创建一系列场景,在短时间内只使用不同的数据完成相同的任务

关于创建的两个测试,您是对的,这使您的testrunner更易于管理。这两个测试是调用名为Login的内部方法的实际
TestMethods

   // this method is created to be called from a scenario outline
   // this contains the steps that one iteration of the outline should take.
   public virtual void Login(string login, string password, string[] exampleTags)
    {
        TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Login", exampleTags);
        #line 13
        this.ScenarioSetup(scenarioInfo);
        #line 14
        testRunner.Given("I have navigated to the Login Page", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given ");
        #line 15
        testRunner.When(string.Format("I enter a valid \'{0}\'", login), ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
        #line 16
        testRunner.And(string.Format("I enter the correct \'{0}\'", password), ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
        #line 17
        testRunner.And("I press the Login CTA", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
        #line 18
        testRunner.Then("I am logged into the Home Page", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
        #line hidden
        this.ScenarioCleanup();
    }

    [Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
    [Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute("Login")]
    [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("VariantName", "LoginA")]
    [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("Parameter:Login", "LoginA")]
    [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("Parameter:Password", "passwordA")]
    public virtual void Login_LoginA()
    {
        // Calling the inner method Login
        this.Login("LoginA", "passwordA", ((string[])(null)));
    }

    [Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
    [Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute("Login")]
    [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("VariantName", "LoginB")]
    [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("Parameter:Login", "LoginB")]
    [Microsoft.VisualStudio.TestTools.UnitTesting.TestPropertyAttribute("Parameter:Password", "passwordB")]
    public virtual void Login_LoginB()
    {
        this.Login("LoginB", "passwordB", ((string[])(null)));
    }

您可以这样访问堆栈跟踪。经过考验。您不仅限于一个属性名

        var stackTraces = new StackTrace();
        foreach (var stackFrame in stackTraces.GetFrames())
        {
            MethodBase methodBase = stackFrame.GetMethod();
            TestPropertyAttribute[] attributes = methodBase.GetCustomAttributes(typeof(TestPropertyAttribute), false) as TestPropertyAttribute[];
            if (attributes != null && attributes.Length >= 1)
            {
                variantName = attributes.FirstOrDefault(x => x.Name.Equals("VariantName"))?.Value;
            }
        }

虽然我的代码看起来与你的代码略有不同,但这可能是因为NUnit插件。我没有预料到Specflow/NUnit会为我做所有的工作,我需要做的就是在SendKey中放置适当的字符串,然后Specflow知道在适当的时间去获取适当的字符串,例如,“WebBrowser.Current.FindElement(By.Id(“userField”))。SendKey(stringName);”将满足这两种情况。谢谢大家!@dno11 NUnit对标记和描述使用其他属性,但应归结为相同的概念。MSTest使用的是
Microsoft.VisualStudio.TestTools.UnitTesting.TestProperty
属性,而NUnit使用的是
NUnit.Framework.Property
属性。我们看到的是SpecFlow代码生成器的内部工作;大多数测试人员不会走那么远:)。
        var stackTraces = new StackTrace();
        foreach (var stackFrame in stackTraces.GetFrames())
        {
            MethodBase methodBase = stackFrame.GetMethod();
            TestPropertyAttribute[] attributes = methodBase.GetCustomAttributes(typeof(TestPropertyAttribute), false) as TestPropertyAttribute[];
            if (attributes != null && attributes.Length >= 1)
            {
                variantName = attributes.FirstOrDefault(x => x.Name.Equals("VariantName"))?.Value;
            }
        }