Selenide简介

2023/07/22

1. 简介

在本文中,我们将介绍用于UI自动化测试的Selenide项目,我们将介绍它是什么以及如何使用它来测试我们的UI项目。

2. 什么是Selenide?

Selenide是一个构建在Selenium WebDriver之上的免费开源框架,它使我们能够访问Selenium的所有功能来对我们的Web应用程序执行自动化测试。尽管如此,它还是被大大简化了,这样我们就可以只关注重要的事情。

特别是,Selenide将简化所有Web浏览器的管理。如果测试失败,它还会自动截取浏览器窗口的屏幕截图。然后,它为我们提供了一个更加简化的API,用于与Web浏览器交互,包括一些无法从Selenium直接获得的功能,并简化了其他可用的功能。

3. 入门

让我们快速看一下使用Selenide的简单示例。

3.1 Maven依赖项

在做任何事情之前,我们需要将Selenide添加到我们的项目中:

<dependency>
    <groupId>com.codeborne</groupId>
    <artifactId>selenide</artifactId>
    <version>6.15.0</version>
    <scope>test</scope>
</dependency>

最新版本可以在Maven中央仓库中找到。

这将自动引入所有必要的内容,包括相应版本的Selenium WebDriver。

我们还需要一个可用的测试框架-例如JUnit。这将用于像往常一样编写我们的测试,Selenide只是我们可以在测试代码中使用的另一个库。

3.2 我们的第一个测试

现在我们已经设置了依赖项,让我们编写一个测试。我们将进行一次检查,以检查Baeldung是否确实是搜索引擎搜索时的第一个命中结果。

我们首先需要的是一些导入,我们并不强制需要这些,但它们更容易阅读代码:

import static com.codeborne.selenide.Selenide.*;
import static com.codeborne.selenide.Condition.*;
import org.openqa.selenium.By;

现在我们可以编写测试了:

@Test
public void searchBaeldung() throws Exception {
    open("https://duckduckgo.com/");

    SelenideElement searchbox = $(By.id("searchbox_input"));
    searchbox.click();
    searchbox.sendKeys("Baeldung");
    searchbox.pressEnter()

    SelenideElement firstResult = $(By.id("r1-0"));
    firstResult.shouldHave(text("Baeldung"));
}

首先要注意的是这里的东西很少。我们对浏览器管理、等待加载或任何其他通常使这些测试变得如此复杂的事情一无所知。相反,我们在这里看到的所有内容都与所讨论的测试直接相关

我们首先打开我们的网页,然后我们点击搜索框,输入搜索词,然后按回车键。最后,我们找到第一个结果(我们从页面的HTML中知道r1-0是赋予第一个结果的ID)并确保它具有预期的文本。

我们在这里看到的$()是我们查询浏览器页面的方法,这需要一个选择器并返回一个SelenideElement,表示整个页面中的第一个匹配元素。我们还可以使用$$()方法,它将返回所有匹配元素的集合。

一旦我们有了SelenideElement,我们就可以使用相同的模式继续获得更具体的信息-只是这一次我们使用的是SelenideElement.$和SelenideElement.$$。

一旦我们有了SelenideElement,我们就可以开始与它交互-例如使用click()、sendKeys()和pressEnter()等方法。

我们还可以使用should()、shouldBe()和shouldHave()来断言该元素符合我们的预期。这三种方法是相同的,只是为了让测试更好读而措辞不同-例如,firstResult.should(text(“Baeldung”))功能相同,但阅读效果不佳。

4. 页面对象

页面对象是我们可以在UI测试中使用的有用模式,这涉及编写类来封装整个网页或其部分,然后我们可以在测试中使用这些对象。这样做的好处是,如果我们更改页面的工作方式,我们会更改单个页面对象,并且使用它的每个测试都会自动正确。

毫不奇怪,Selenide允许我们像Selenium WebDriver一样轻松地使用页面对象模式。我们可以根据需要编写直接使用Selenide类的类,要么使用$static方法,它允许我们与整个页面交互,要么通过包装表示页面较小部分的SelenideElement值。

让我们使用此模式重写原始测试,看看它是什么样子。首先,我们需要一个页面模型来表示搜索表单:

public class SearchFormPage {
    public void open() {
        Selenide.open("http://duckduckgo.com/");
    }

    public void search(String term) {
        SelenideElement searchbox = $(By.id("searchbox_input"));
        searchbox.click();
        searchbox.sendKeys(term);
        searchbox.pressEnter();
    }
}

这有两种方法可以使用-一种打开搜索页面,另一种实际执行对提供的术语的搜索。

接下来,我们需要一个页面模型来表示搜索结果页面:

public class SearchResultsPage {
    public SearchResult getResult(int index) {
        SelenideElement result = $(By.id("r1-" + index));
        result.shouldBe(visible);

        return new SearchResult(result);
    }
}

这为我们提供了访问单个结果的单一方法。这将返回另一个页面对象,这次在页面中包装单个SelenideElement:

public class SearchResult {
    private SelenideElement result;

    public SearchResult(SelenideElement result) {
        this.result = result;
    }

    public String getText() {
        return result.getText();
    }
}

然后,该页面对象包装该SelenideElement并允许我们与其精确交互。在本例中,通过从搜索结果中获取文本。

现在我们可以实际编写一个测试:

@Test
public void searchBaeldung() {
    SearchFormPage searchFormPage = new SearchFormPage();
    searchFormPage.open();
    searchFormPage.search("Baeldung");

    SearchResultsPage results = new SearchResultsPage();

    SearchResult firstResult = results.getResult(0);
    assertTrue(firstResult.getText().contains("Baeldung"));
}

该测试与以前相同,但我们现在根据类来编写它,以便更好地解释正在发生的事情。这样做的好处是,对于那些不确切知道HTML是如何呈现的人来说,测试更具可读性。

它还使我们能够轻松更改页面的交互方式。例如,如果查找单个搜索结果的方法要更改,那么我们只需更改此处的getResult()方法,而不是单独更改许多不同的测试。

5. 测试失败

当我们编写测试时,一个重要的细节是能够轻松识别测试失败的原因。如果没有这一点,我们可能会花费大量精力来找出问题所在。

让我们尝试更改原始测试,使其失败。为此,我们将调整它以搜索错误的术语:

SelenideElement searchbox = $(By.id("searchbox_input"));
searchbox.click();
searchbox.sendKeys("Something Else");
searchbox.pressEnter();

运行这个测试显然会失败-搜索“Something Else”不会找到Baeldung作为第一个结果。但失败时会是什么样子呢?

毫不奇怪,失败在于我们的第一个断言:

但实际的错误是什么样的呢?

由此,我们可以立即看到我们断言的确切HTML元素,以及它的确切值。在本例中,我们对文本内容进行断言,因此这就是我们所看到的。

但还有更多。我们已经捕获了屏幕截图和页面源文件,我们可以打开这些来查看发生错误时网页的确切状态:

立即查看此屏幕截图,我们可以看到我们搜索了错误的内容,因此我们得到了错误的搜索结果。这可以帮助我们轻松识别问题并修复测试。

或者,它实际上可能会强调应用程序未按预期运行。在这种情况下,测试很好,但在我们的代码中发现了回归。

6. 配置Selenide

我们刚刚看到Selenide为失败的测试保存屏幕截图,但它需要知道将屏幕截图放在哪里。

Selenide具有开箱即用的合理默认行为。例如,我们的屏幕截图默认存储在build/reports/tests中。

但是,这些默认值并不总是适用于所有情况,因此我们必须能够调整它们。我们可以通过以下三种方式之一来做到这一点:

  • 使用properties文件
  • 使用系统属性
  • 编程方式

我们控制这些设置的最高优先级的方式是在我们的代码中,我们通过在测试期间更改com.codeborne.selenide.Configuration对象的属性来实现此目的。这可以直接在测试本身中、在@BeforeEach方法中或在适当时间执行的任何地方。所有这些属性都有JavaDoc准确解释它们的含义,以便我们可以正确地更改它们。

下一个最高优先级是使用系统属性。我们可以以标准方式提供这些属性,就像为运行的测试提供系统属性一样。属性名称与Configuration类中的字段名称完全相同,只是带有“selenide.”前缀。例如,selenide.reportsFolder对应于Configuration.reportsFolder。

最后,我们可以在类路径根目录下的selenide.properties文件中定义所有这些属性。例如,在Maven项目中,这将位于src/test/resources中。该文件具有与系统属性完全相同的属性,但它们存在于项目内,而系统属性可以从外部指定-例如,通过我们的CI系统。

这里需要了解的最重要的属性是有关如何使用Web浏览器以及文件存储位置的属性。例如,我们可以通过以下方式使用Firefox代替Chrome:

  • 以在我们的代码中编程方式设置Configuration.browser=”firefox”;。
  • 将-Dselenide.browser=firefox添加到命令行。
  • 将selenide.browser=firefox添加到selenide.properties文件中。

这三者将具有相同的效果。这意味着,例如,作为CI构建的一部分,我们可以使用系统属性方法在各种不同的Web浏览器上运行完全相同的测试。

7. 总结

在这里,我们介绍了Selenide库以及如何使用它来编写UI自动化测试。

与往常一样,示例代码可以在GitHub上找到。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章