正文

Selenium Remote Control: 教程2008-11-01 15:18:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/lym51/39191.html

分享到:

Selenium Remote Control: 教程
这个Selenium Remote Control 教程将会教你怎么从命令行开始Selenium Server, 并且怎么在交互模式下使用Server。它要求你熟悉怎么从命令行运行程序。最后,我们会演示怎么写一个简单的和我们在交互模式里做的同样的测试。


--------------------------------------------------------------------------------

Selenium Server 是用Java编写的,需要Java Runtime Environment (JRE)1.5.0 或者更高版本去运行。如果你已经安装了,试一下这个命令行:

java -version

你应该看到一个简短的消息告诉你安装了什么版本的Java,例如:

java version "1.5.0_07"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode)

如果你看到一个错误消息,你也许需要安装JRE,或者需要添加它到你的PATH环境变量。

对于这个例子,你还需要确定你已经安装了一个支持的浏览器。

Windows: 如果你使用Windows XP 或 Windows 2003,你可以只是使用IE去运行这个例子,或者安装Mozilla Firefox 或Opera。如果你使用Windows 2000,你将会需要[install reg.exe]去使用IE,但是即使你不装,Firefox也应该会工作。我们建议(但是不是必须)你添加你的浏览器执行文件到PATH环境变量。(如果你没有明确添加你的浏览器安装目录到这个路径,你必须安装你的浏览器到它的标准地址,Firefox的标准路径是"c:\Program Files\Mozilla Firefox\firefox.exe",IE的标准路径是"c:\Program Files\Internet Explorer\iexplore.exe"。)
Unix/Linux: 对这个教程来说,安装Firefox并且添加Firefox路径到你的PATH环境参数。注意在Unix/Linux 上,我们将会试着调用"firefox-bin"路径,所以确定执行文件在那个目录下,并且别忘记添加Firefox库到你的LD_LIBRARY_PATH。如果需要,我们可以使用一个shell 脚本去调用Firefox (例如."firefox" 或者是"run-mozilla.sh"),但是如果那样的话,我们也许不能停止Firefox直到server被关掉。
Mac OS X: 在 Mac OS X上安装Firefox.app在你的应用目录(/Applications)下就够了。注意为了控制浏览器的精确性,我们需要直接在/Applications/Firefox.app/Contents/MacOS调用内嵌的Firefox可执行二进制文件,如果你的浏览器没有安装在那里,那么你需要添加正确的嵌入地址到你的PATH环境参数以及DYLD_LIBRARY_PATH 环境参数。(译者注:也就是在你的.profile里面加上export BROWSER_PATH=/Applications/Firefox.app/Contents/MacOS/firefox-bin,但是如果你的Firefox.app文件夹变了名字,你需要将相应的目录添加到DYLD_LIBRARY_PATH变量里面。)
交互模式
Selenium Server "交互模式"提供了一种快速的原型测试的方法,并且不需要code,所以这是一个介绍新用户去使用Selenium Remote Control的好方法。在交互模式下,你一个一个的敲入你的命令到Selenium Server 命令窗口,这允许你马上在工作的浏览器里看到命令行的运行结果。也就是说,往常你需要把这些测试用你喜欢的语言进行编码,所以整个事情都被自动化。
一旦你让Java安装并且可以运行,有能够从下面的命令行运行Selenium Server:

java -jar selenium-server.jar -interactive

这会启动Selenium Server 并且允许你在命令行窗口敲入命令。在一些记录消息之后,你可以看到下面的消息:

{{Entering interactive mode... type Selenium commands here (e.g: cmd=open&1=http://www.yahoo.com) }}

让我们开始使用Selenium Server 去打开一个浏览器。如果你在一个窗口上并且想用IE运行你的Selenium 命令行,试着录入这个:

cmd=getNewBrowserSession&1=*iexplore&2=http://www.google.com

如果你想使用Firefox,用这个:

cmd=getNewBrowserSession&1=*firefox&2=http://www.google.com

你正在运行"getNewBrowserSession"命令,使用你选择的浏览器 (IE 用*iexplore , Firefox用*firefox , Opera 用*opera ),从www.google.com开始。在这个窗口敲入命令自动的发起HTTP web请求到Selenium Server,请求被完成。(在非交互模式,你可以使用任何你喜欢的自动工具去传递这些HTTP 请求到服务器,而不是手动的敲入命令。)当你按回车键后,你将看到一个形容你刚才作出的请求的消息:

---> Requesting http://localhost:4444/selenium-server/driver?cmd=getNewBrowserSession&1=*firefox&2=http://www.google.com

如果所有一切进行得不错,你应该看到一个你选择的新的浏览器窗口启动起来。回到Selenium Server 命令窗口,你应该看到下面这些信息:

Got result: OK,260113 on session 260113

(如果这些没有发生,你需要看一下我们的Troubleshooting 指南.)

这个消息的开始部分"Got result: OK" 说明你提出的需求工作正常。第二部分,那些数字,是一个序列号。你每次从命令行运行"getNewBrowserSession"命令得到的序列号都会不同。

让我们尝试更多的命令,开始一个Google 搜索。我们从打开一个Google 页面开始。把这个敲入到Selenium Server 命令窗口,用你运行"getNewBrowserSession"得到的数字替代序列号:

cmd=open&1=http://www.google.com/webhp&sessionId=260113

When this command finishes, your browser window should reveal google.com in the lower frame. (The /webhp makes sure we stay on www.google.com; otherwise, we might get redirected to a country-specific Google server, e.g., www.google.fr.) Don't forget that you need to replace the Session ID above with your own personal Session ID, the one you got when you ran the "getNewBrowserSession" command. (If you use the wrong Session ID, you won't see an error message; the Selenium Server will just sit there, waiting for some browser to come in and do its work.)

Now that Google is open, let's try typing something in the search box. Type this in the Selenium Server command window:

cmd=type&1=q&2=hello world&sessionId=260113

Again, don't forget to replace the Session ID with your own Session ID. If all goes to plan, you should see "hello world" in the search box for your Google search.

Now, let's do a search!

cmd=click&1=btnG&sessionId=260113

You should now see the results of your Google Search in your browser window. You can run dozens of Selenium commands to automate all manner of browsing tasks. For more information on particular commands, you can go look at the Selenium Core section at the Open QA website, or check out the reference materials available for any of our Client Drivers (Java, .NET, Perl, Python or Ruby).

The next thing we might want to do is read some information back out of the page... for example, let's retrieve the HTML title of the current page, like this:

cmd=getTitle&sessionId=260113

The browser will return the title of the HTML page we've loaded, like this:

Got result: OK,hello world - Google Search on session 260113

That's enough Interactive Mode for now; let's move on to writing some code! But before we go, let's stop the browser we started. Type this command in the Selenium Server command window:

cmd=testComplete&sessionId=260113

When this command finishes, your browser window should automatically close. To quit the Selenium Server, type "quit" or just press Ctrl-C.

Programming a Selenium RC Test
Now that you know how to run commands in interactive mode, let's code this test up! Here's examples of writing the test we just wrote in four different programming languages:

Java (JUnit)
import com.thoughtworks.selenium.*;
import junit.framework.*;
public class GoogleTest extends TestCase {
    private Selenium sel;
    public void setUp() {
        sel = new DefaultSelenium("localhost",
            4444, "*firefox", "
http://www.google.com");
        sel.start();
    }
   
    public void testGoogle() {
        sel.open("
http://www.google.com/webhp");
        sel.type("q", "hello world");
        sel.click("btnG");
        sel.waitForPageToLoad("5000");
        assertEquals("hello world - Google Search", sel.getTitle());
    }
   
    public void tearDown() {
        sel.stop();
    }
}C# (NUnit)
using Selenium;
using NUnit.Framework;
namespace MyTests {
    [TestFixture]
    public class GoogleTest {
        private ISelenium sel;
       
        [SetUp]
        public void SetUp() {
            sel = new DefaultSelenium("localhost",
                4444, "*firefox", "
http://www.google.com");
            sel.Start();
        }
       
        [Test]
        public void testGoogle() {
            sel.Open("
http://www.google.com/webhp");
            sel.Type("q", "hello world");
            sel.Click("btnG");
            sel.WaitForPageToLoad("5000");
            Assert.AreEqual("hello world - Google Search", sel.GetTitle());
        }
       
        [TearDown]
        public void TearDown() {
            sel.stop();
        }
    }
}Perl (Test::More)
(+) Perl (Test::More)
use WWW::Selenium;
use Test::More;

plan tests => 1;

my $sel = WWW::Selenium->new( host => "localhost",
                              port => 4444,
                              browser => "*iexplore",
                              browser_url => "
http://www.google.com";,
                            );
$sel->start();
$sel->open("
http://www.google.com");
$sel->type("q", "hello world");
$sel->click("btnG");
$sel->wait_for_page_to_load(5000);
like($sel->get_title(), qr/Google Search/);
$sel->stop();Python (unittest)
import unittest
import selenium

class GoogleTest(unittest.TestCase):
    def setUp(self):
        self.selenium = selenium.selenium_class("localhost", \
            4444, "*firefox", "
http://www.google.com")
        self.selenium.start()
       
    def test_google(self):
        sel = self.selenium
        sel.open("
http://www.google.com/webhp")
        sel.type("q", "hello world")
        sel.click("btnG")
        sel.wait_for_page_to_load(5000)
        self.assertEqual("hello world - Google Search", sel.get_title())
   
    def tearDown(self):
        self.selenium.stop()

if __name__ == "__main__":
    unittest.main()Ruby (Test::Unit)
require 'test/unit'
require 'selenium'

class GoogleTest < Test::Unit::TestCase

 def setup
  @sel = Selenium::SeleniumDriver.new("localhost", 4444,
   "*firefox", "
http://www.google.com", 15000)
  @sel.start
 end
  
 def test_google
  @sel.open("
http://www.google.com/webhp")
  @sel.type("q", "hello world")
  @sel.click("btnG")
  @sel.wait_for_page_to_load("5000")
  assert_equal("hello world - Google Search", @sel.get_title())
 end
 
 def teardown
  @sel.stop
 end
endThe Same Origin Policy
As you were running your tests, you may have noticed that your browser started at the following URL:

http://www.google.com/selenium-server/RemoteRunner.html?sessionId=260113

That's a rather unusual URL, because, of course, there is no such file available on www.google.com. If you open up your browser manually and browse to that URL, you'll get a 404 error. What's going on?

The Selenium Server is attempting to circumvent a very difficult problem in JavaScript automated testing: normally, JavaScript you write yourself can't be run on google.com, due to a policy known as the same origin policy. (That write-up is from the Mozilla website, but all modern JavaScript browsers enforce this policy.) The same origin policy makes a lot of sense. Let's say you've got your browser window pointing at, let's say, your bank's website, but you also have another webpage open pointing to someone's blog. JavaScript is allowed to read values from web pages, as well as change data appearing on webpages you've loaded. A malicious blogger could read your bank data, or worse, rewrite your bank page to make it think it was saying something else. He could use this to trick you into giving him sensitive information. The Same Origin Policy states that JavaScript is only allowed to read/modify HTML from the same origin as its source.

That creates a big problem for Selenium automated tests. If you wrote a .js file designed to test google.com, the same origin policy denies you the right to just run that .js file on google.com; instead, you'd have to somehow install that .js file on google.com in order to write automated tests against it. In the case of google.com we don't have the right to do this; but even if we did, it would be a hassle to do so.

That's where the Selenium Server comes in. The Selenium Server is acting as a client-configured proxy for the browser that you automatically started with "getNewBrowserSession". Specifically, it configures your browser to use the Selenium Server as a proxy in its browser preferences.

A proxy normally fetches HTML pages on your behalf; if a page can't be found, it honestly reports that the page wasn't there. But the Selenium Server is a very different kind of proxy; when the browser requests a page through the proxy that contains "/selenium-server/" in its URL, the Selenium Server doesn't simply fetch the page from the remote server, but instead automatically returns its own page instead. That makes the browser think that the remote server itself actually contained the page in question, which allows us to "inject" arbitrary JavaScript into google.com without modifying google.com in any way at all.

 

However, the solution isn't perfect. Try running your tests like this:

cmd=getNewBrowserSession&1=*iexplore&2=http://www.yahoo.com
{{cmd=open&1=http://www.google.com&sessionId=260113 }}
cmd=type&1=q&2=hello world&sessionId=260113

In this case, the "start URL" was yahoo.com, so the browser opened to

{{http://www.yahoo.com/selenium-server/RemoteRunner.html?sessionId=260113 }}

and then we tried to open up google.com (which did work...) and type "Hello World" into the search box. But yahoo.com doesn't have the right to modify google.com, so that operation fails.

All this means is that you have to choose your browser's start URL wisely: if you open up the browser to yahoo.com, you can't use it to test google.com, and vice versa.

However, in some cases, you may be required to test more than one domain at once. The most common case is when you need to test both http://blah.com and https://blah.com. "http:" and "https:" are considered different "origins" from JavaScript perspective, so tests running on one can't run on the other. In that case, for now, you'll have to use one of our experimental browser launchers which support running in multiple domains.

Automatically Launching Other Browsers
Selenium Server can automatically launch/kill other browsers that we don't yet explicitly support. (Most of the browsers on the "Should Work" supported list need to be launched in this way.) When running your "getNewBrowserSession" command, use the "*custom" browser launcher instead of "*firefox" or "*iexplore", specifying the absolute path to your browser.

cmd=getNewBrowserSession&1=*custom c:\Program Files\Netscape\Netscape\Netscp.exe&2=http://www.google.com

Note that when we launch the browser in this way, you'll have to manually configure your browser to use the Selenium Server as a proxy. (Normally this just means opening your browser preferences and specifying "localhost:4444" as an HTTP proxy, but instructions for this can differ radically from browser to browser, so consult your browser's documentation for details.)

If you attempt to launch a *custom browser but don't configure the proxy correctly, you won't be able to get through even a simple Google test, because you'll get a 404 (File not found) error trying to access http://www.google.com/selenium-server/. Remember, that directory doesn't really exist on Google.com; it only appears to exist when the proxy is properly configured.

Also beware that Mozilla browsers can be a little fidgety about how they start and stop. Avoid launching your browser using a shell script; always prefer to use the binary executable directly. You may need to set the MOZ_NO_REMOTE environment variable to make Mozilla browsers behave a little more predictably.

If you want to use one of the explicitly supported browsers but have installed it in an unusual location, you can tell us that by using the special browser string followed by the absolute path to the executable.

cmd=getNewBrowserSession&1=*firefox c:\firefox\firefox.exe&2=http://www.google.com

That will automatically configure Firefox's proxy settings, but does not require you to add Firefox directly to the path. (You can use this to test multiple different versions of Firefox installed in separate directories.)

You can also use "*custom" to automatically launch a supported browser without configuring its proxy. For example, you could launch Firefox like this:

cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\firefox.exe&2=http://www.google.com

Again, note that you'll need to manually configure your proxy prior to launching Firefox in this way; otherwise you'll get a 404 error while following the steps in the tutorial.

Running without a Session ID - the "null" session
If you get annoyed with typing out your Session ID over-and-over, or if you want to try manually testing with another browser that we don't yet officially support, you can always just launch the browser yourself and browse to "/selenium-server/RemoteRunner.html" manually. (Don't forget to set your proxy settings, as discussed in the previous section.)

If you just point straight at "/selenium-server/RemoteRunner.html" you can send commands to that browser without specifying a Session ID. When no Session ID is specified, the Selenium Server uses the "null" session to communicate with any browser that comes to speak with it.

You can even make up your own Session IDs, just by starting your browser while pointing to "/selenium-server/RemoteRunner.html?sessionId=foo". That will use the Session ID "foo" instead of some crazy long number. (Session IDs don't have to be numbers, though they usually are when the Selenium Server generates one.) Hence, if you use a Session ID that isn't on record with the Selenium Server, no error message will be thrown; the Selenium Server will just wait patiently for some browser to come along and request work from that Session ID.

Run tests under multi-window mode
By default, Selenium runs the application under test in a subframe. (Running the AUT in a subframe gives us a great deal of control over the AUT.) But some apps don't run properly in a subframe, preferring to be loaded into the top frame of the window. In that case, you need to make your application under test run in a seperate window rather than in the default frame. To do that, start selenium server with the -multiWindow parameter:

java -jar selenium-server.jar -multiWindow
Note that multiWindow mode is a little less stable than running in a frame, so you should probably avoid doing this if you can possibly help it.

Support for HTTPS
Because of the unique proxy-based nature of Selenium RC, tests that require HTTPS can be a challenge. There are two options available:
Use the [experimental] *chrome or *iehta browser launchers, which can typically bypass security restrictions that the other modes cannot.
Use the HTTPS support outlined below.
To get started with testing on HTTPS, you have to use the custom browser launcher (*custom). The reason for this is that you need to import a Certificate Authority in to the main browser profile. Look in the advanced/security settings in Firefox/IE for this option.
You can find the CA at
http://dangerous-certificate-authority.openqa.org/

Once you have the CA imported to the browser and have changed your tests to use the custom browser launcher, you can begin testing against HTTPS. Everything should just work.

How it works

Unlike other similar web testing tools, this solution doesn't require you to prepare the web browser for each domain you want to test. Rather, you only need to prepare the browser once by importing the CA.

What happens behind the schenes is that as each HTTPS connection is opened to a unique server/host combination, a mini-instance of Jetty is spawned off and used to tunnel SSL connections to the server. However, that Jetty instance needs a keystore that is signed by a trusted CA and is associated with the domain in question.

That keystore could be generated through a series of keytool and openssl commands, but we didn't want you to have to install these locally, since that can be a pain, especially for openssl. So instead, we created a web service at the dangerous-certificate-authority.openqa.org domain that generates the keystore for you.

The downside to this approach is that you must be online for HTTPS support to work. In the future we may offer a fallback that issues the keytool/openssl commands if the online service can't be accessed.


--------------------------------------------------------------------------------

With that, you're ready to try out one of our Client Drivers. We have Client Drivers available in a variety of languages, allowing you to automatically submit HTTP requests to the Selenium Server and automate your browsing tasks. Click on one of them on the left to get more information about any particular Client Driver, or get information on how to write your own from scratch.

Good luck!


 Add Comment

阅读(8621) | 评论(2)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册