xiaobaoqiu Blog

Think More, Code Less

Selenium

1.什么是Selenium

Selenium 是一种 Web 应用的自动测试工具,通过模拟用户对 Web 页面的各种操作,可以精确重现软件测试人员编写的 Test Cases 步骤。它所采用的原理是通过录制应用程序产生的线性脚本进行回放从而达到自动化测试的目的。其优点是简单,通过录制就可以得到所需脚本。类似于录制/回放测试工具有很多,我们之所以选择它的原因是它是开源的,而且它测试直接在浏览器中运行,就像真实用户所做的一样。Selenium测试可以在 Windows、Linux上的 Internet Explorer、Mozilla和 Firefox 中运行。其他测试工具都不能覆盖如此多的平台,更重要的是Selenium支持多种语言、JAVA、Ruby、Python等。

Selenium的核心,也称browser bot,是用JavaScript编写的。这使得测试脚本可以在受支持的浏览器中运行。browser bot负责执行从测试脚本接收到的命令,测试脚本要么是用 HTML的表布局编写的,要么是使用一种受支持的编程语言编写的。

1.1 Selenium名字的来源

Selenium的中文名为“硒”,是一种化学元素的名字,它对汞(Mercury)有天然的解毒作用,实验表明汞暴露水平越高,硒对汞毒性的拮抗作用越明显,所以说硒是汞的克星。大家应该知道Mercury测试工具系 列吧(QTP,QC,LR,WR…),他们功能强大,但却价格不菲,大家对此又爱又恨!故thoughtworks特意把他们的Web开源测试工具命 名为Selenium,以此帮助大家脱离汞毒。

Selenium 是thoughtworks所做的,用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE、Mozilla Firefox、Mozilla Suite等。

在selenium2.0中,包含2个部分 selenium ide 和 selenium webdriver.

1.2 优势

使用 Selenium 和在浏览器中运行测试还有很多其他好处。下面是主要的两大好处:

(1).通过编写模仿用户操作的 Selenium 测试脚本,可以从终端用户的角度来测试应用程序;
(2).通过在不同浏览器中运行测试,更容易发现浏览器的不兼容性;

1.3 Selenium 模式

可以按两种模式来使用test runner 和 driven,这两种模式在复杂性和编写方式方面有所不同。driven 测试脚本编写起来往往要更复杂一些,因为它们是用编程语言编写的。

两种模式之间最大的不同点在于:如果使用 driven 脚本,测试有一部分在浏览器之外运行,而如果使用 test runner 脚本的话,测试是完全在浏览器中运行的。

不管是 test runner 还是 driven 测试用例,都可以与持续集成工具集成。

本文这里只简单介绍了 driven 模式。

2.driven 模式

driven Selenium 脚本是用多种受支持的编程语言中的一种编写的,目前可用的有 Java、Ruby 和 Python 等驱动程序。这些脚本在浏览器之外的一个单独的进程中运行。驱动程序的任务是执行测试脚本,并通过与运行在浏览器中的 browser bot 进行通信来驱动浏览器。驱动程序与 browser bot 之间的通信使用一种简单的特定于 Selenium 的连接语言 Selenese。

driven 脚本比 test runner 脚本更强大、更灵活,可以将它们与 xUnit (比如JUnit)框架集成。driven 脚本的缺点(与 test runner 脚本相比)是,这种脚本编写和部署起来更复杂。这是因为驱动程序必须执行以下任务:

(1).启动服务器;
(2).部署所测试的应用程序;
(3).部署测试脚本;
(4).启动浏览器;
(5).发送命令到 browser bot;
(6).验证 browser bot 执行的命令的结果;

3.简单case

这里用Java实现一个简单的使用Selenium的case

3.1 Maven包

使用现有的maven包:

1
2
3
4
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
</dependency>

3.2 简单case

下面结合JUnit以打开google为例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import com.google.common.collect.Lists;
import com.qunar.scm.common.BrowserDriver;
import org.apache.commons.collections.CollectionUtils;
import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * 测试Google
 *
 * @author baoqiu.xiao@qunar.com  Date: 14-12-31 Time: 下午1:42
 * @version \$Id$
 */
public class GoogleTest extends AbstractBaseTest {

    private static final Logger logger = LoggerFactory.getLogger(GoogleTest.class);

    private static final String GOOGLE_URL = "https://www.google.com.hk";

    @Test
    public void testGoogle() {
        //当前测试case名称
        caseName = Thread.currentThread().getStackTrace()[1].getMethodName();

        boolean flag = testCommonProcess(currentDriverList(), new BrowserVisiter() {
            @Override
            public boolean visit(BrowserDriver browserDriver) {
                return doTestGoogle(browserDriver);
            }
        });

        Assert.assertTrue(flag);
    }

    /**
     * 实际的测试逻辑
     *
     * @param browserDriver
     */
    private boolean doTestGoogle(final BrowserDriver browserDriver) {
        if(browserDriver == null) {
            logger.error("browserDriver is null");
            return false;
        }

        WebDriver driver = browserDriver.getWebDriver();

        //1.打开页面
        driver.get(GOOGLE_URL);
        driver.manage().window().maximize();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //2.在搜索框内输入关键字,输入回车
        WebElement keyWord = driver.findElement(By.name("q"));
        keyWord.sendKeys("xiaobaoqiu");
        keyWord.sendKeys(Keys.RETURN);

        return true;
    }



    /**
     * 当前需要测试的浏览器列表,这里只使用了firefox
     *
     * @return
     */
    @Override
    protected List<BrowserDriver> currentDriverList() {
        return Lists.newArrayList(BrowserDriver.FIREFOX_DRIVER);
    }

    /**
     * 生成测试报告
     *
     * @param driverList
     * @param result
     */
    @Override
    protected void doReportResult(List<BrowserDriver> driverList, List<Boolean> result) {
        if (CollectionUtils.isEmpty(driverList) || CollectionUtils.isEmpty(result)) {
            logger.error("isEmpty(driverList) or isEmpty(result)");
            return;
        }

        if (driverList.size() != result.size()) {
            logger.error("driverList.size() != result.size()");
            return;
        }

        logger.info("BEG====================================={}=====================================BEG", caseName);
        for (int i = 0; i < driverList.size(); i++) {
            logger.info("{} = {}", driverList.get(i).getBrowser().getName(), resultString(result.get(i)));
        }
        logger.info("END====================================={}=====================================END", caseName);
    }
}

结果:

3.3 注意点

一些Selenuim的注意点,持续补充中:

(1).Selenium默认状态下只支持Firefox,支持Chrome和IE需要安装插件;

4.参考

http://code.google.com/p/selenium/

https://www.ibm.com/developerworks/cn/java/wa-selenium-ajax/