需要传递多个链接的参数才能在黄瓜中测试

时间:2016-10-26 23:01:37

标签: cucumber cucumber-java

我已经编写了这个功能文件,用于测试主页中的多个链接。我试图通过功能文件传递参数来减少步骤定义的数量。 我在功能文件中写入元素名称时遇到问题,该文件可以获取每个标签。没有提到的id所以我不得不采用xpath(我知道在功能文件&#34中不太理想;。你建议任何替代方式对吗?

Homepage.feature

  Scenario: To Test Home Tab
      Given I am on Homepage
      When I Click on ".//*[@id='oneHeader']/div[3]/div/div[2]/nav/ul/li[1]/a/span"
      Then I am on "Home"
      And application should be closed

  Scenario: To Test Calender Tab
    Given I am on Homepage
    When I Click on "Calender"
    Then I am on "Calender"
    And application should be closed

  Scenario: To Test Lead Tab
    Given I am on Homepage
    When I Click on "Leads"
    Then I am on "Leads"
    And application should be closed

  Scenario: To Test Oppurtunities Tab
    Given I am on Homepage
    When I Click on "Oppurtunities"
    Then I am on "Oppurtunities"
    And application should be closed

  Scenario: To Test Accounts Tab
    Given I am on Homepage
    When I Click on "Accounts"
    Then I am on "Accounts"
    And application should be closed


  Scenario: To Test Contacts Tab
    Given I am on Homepage
    When I Click on "Contacts"
    Then I am on "Contacts"
    And application should be closed

  Scenario: To Test Dashboard Tab
    Given I am on Homepage
    When I Click on "Dashboards"
    Then I am on "Dashboards"
    And application should be closed

  Scenario: To Test Reports Tab
    Given I am on Homepage
    When I Click on "Reports"
    Then I am on "Reports"
    And application should be closed

步骤定义看起来像这样

package stepDefination;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class SmokeTest {
    WebDriver driver;

    public SmokeTest() {
    }

    @Given("^Open firefox and start application$")
    public void Open_chrome_and_start_application() throws Throwable {
        this.driver = new FirefoxDriver();
        this.driver.manage().window().maximize();
        this.driver.get("http://test.salesforce.com/");
    }

    @When("^I enter valid \"([^\"]*)\" and valid \"([^\"]*)\"$")
    public void I_enter_valid_and_valid(String unam, String pass) throws Throwable {
        this.driver.findElement(By.xpath(".//*[@id=\'username\']")).sendKeys(new CharSequence[]{unam});
        this.driver.findElement(By.xpath(".//*[@id=\'password\']")).sendKeys(new CharSequence[]{pass});
    }

    @Then("^I should be able to login successfully$")
    public void user_should_be_able_to_login_successfully() throws Throwable {
        this.driver.findElement(By.id("Login")).click();
    }

    @Given("^I am on Homepage$")
    public void i_am_on_Homepage() throws Throwable {
        this.driver.findElement(By.xpath(".//*[@id=\'salesforceLogo\']"));
    }

    @When("^I Click on \"([^\"]*)\"$")
    public void i_Click_on(String Link) throws Throwable {
        this.driver.findElement(By.id(Link)).click();
    }

    @Then("^I am on \"([^\"]*)\"$")
    public void i_am_on(String Tab) throws Throwable {
        this.driver.findElement(By.id(Tab));
    }

    @Then("^application should be closed$")
    public void application_should_be_closed() throws Throwable {
        this.driver.quit();
    }
}

2 个答案:

答案 0 :(得分:0)

编码WHERE t1.ID IS NULL,其中密钥作为链接的名称,值作为链接的xpath。使用要素文件中的密钥并访问步骤定义中的xpath。

extension NSData {
    class func dataFromHexString(hex: String) -> NSData? {
        let regex = try! NSRegularExpression(pattern: "^[0-9a-zA-Z]*$", options: .CaseInsensitive)
        let validate = regex.firstMatchInString(hex, options: NSMatchingOptions.init(rawValue: 0), range: NSRange(location: 0, length: hex.characters.count))
        if validate == nil || hex.characters.count % 2 != 0 {
            return nil
        }
        let data = NSMutableData()
        for i in 0..<hex.characters.count/2 {
            let hexStr = hex.substring(i * 2, length: 2)
            var ch: UInt32 = 0
            NSScanner(string: hexStr).scanHexInt(&ch)
            data.appendBytes(&ch, length: 1)
        }
        return data
    }
}

let a = 0xabcd1234
print(String(format: "%x", a)) // Hex to String
NSData.dataFromHexString("abcd1234") // String to hex

如果您想使用其他混合定位器策略,例如id,name,css等,请考虑创建一个类并在Map中使用它而不是值。

Map

查看ScenarioOutline而不是编写多个类似的场景。

    private static Map<String, String> links = new HashMap<>();
    links.put("Home","//*[@id='oneHeader']/div[3]/div/div[2]/nav/ul/li[1]/a/span");
    ....
    ....

答案 1 :(得分:0)

您在这里做的只是测试主页上的导航。这是一个非常低价值的测试,它需要相当多的工作,你不会从中获得那么多。也就是说有时我会编写这些场景。我就是这样做的。

Feature: Navigation from home page
  As a user 
  I want to be able to get to important places from the home page
  So I can use the home page as a starting point

Background: 
  Given I am on the homepage

Scenario: Navigate to contacts
  When I navigate to contacts
  Then I should see my contacts

我会为每个导航做一个场景,因为

  1. 更清楚
  2. 减少步骤定义的数量相对不重要
  3. 我按如下方式实施步骤定义(注意这是ruby,你必须翻译成java。

    # features/step_definitions/homepage/navigation_steps.rb
    
    When 'I navigate to contacts' do
      click_link '.nav-to-contacts'
    end
    

    我再次为每件事做一个步骤定义,因为它更简单。 请注意我是如何使用css进行点击的,这意味着如果有人出现并更改了文字,请说“我的联系人”,我们不必更新我们的方案。 / p>

    最后,我会为'thens&#39;

    做同样的事情
    Then 'I should see my contacts' do
      expect(page).to have_css('.contacts')
    end
    

    有些观点:

    • 您不需要在每个方案中关闭应用程序。它乏味而且不必要。黄瓜为你做这件事。
    • 在场景中使用正则表达式通常会适得其反。对于一个简单明了的场景而言,它要简洁得多,这一点更为重要。当场景失败时,这尤其适用。
    • 包括&#39;如何&#39;在场景中完成的事情是一个坏主意。这会让事情变得更加昂贵。当一些设计师出现并将标签更改为其他UI控件时,此测试仍将完成其工作。您的方案中的内容包括:网址和点击
    • 您有一个完整的文件系统来存储您的功能和方案。明智地使用它来组织功能和步骤定义。 scenario / step_defintion的位置应该告诉你很多关于它的功能。

    最后情景大纲是最被高估的黄瓜之一,我强烈建议避免它们。它们减少了代码,在最不重要的地方,增加了复杂性并且更难实现。当一个失败时,诊断问题需要更长的时间。拥有5个简单场景而非复杂场景确实要好得多。