Aritz
Aritz

Reputation: 31679

Testing web application urls

I'm developing a bookmarkable web application having, let's say, fifty different url patterns which are accessed with different parameters. My aim is to have a test environment setting up a database with some predefined values. Later on, I would be interested in checking everything works fine, as an example:

I have tried a little bit with cUrl:

GET Login page

curl -i http://localhost:8080/myapp/login

Returns 200 code.

POST for authorization

curl -i  http://localhost:8080/myapp/login/post -X POST -d j_username="user" 
    -d j_password="pass" -c cookie.txt

Performs the login properly and stores the authorized cookie, but it returns 302 Moved (As it's expected because I perform a redirection to home page).

GET some secured url

curl -i http://localhost:8080/myapp/securedurl -b cookie.txt

The secured resource is properly accesed, but I'm using a url rewriting framework, so it forces a redirection and 302 code is returned again.

The problem I'm dealing with cUrl is that it's request specific, so I can't check redirections properly performed. Also even if I could get them properly working, I would need to parse each of the responses to check their code.

So probably I need to emulate a browser behaviour to check the whole cycle instead of focusing in each of the requests.

Any ideas about that?

Upvotes: 1

Views: 1728

Answers (2)

Aritz
Aritz

Reputation: 31679

I finally ended up using Selenium Web Driver and its java API in order to make the tests. The performed steps are:

  • GET the login page
  • Fulfill the login form
  • Iterate over all the possible urls and check they're properly loaded

I perform it with this code piece:

/*
*   Constants declaring the urls to test
*/
private static final String[] URLS = { URL1, URL2, URL3 };

/*
*   Here we've to check that the return page is 404. In my case this comparison works, 
*   however it may vary for different implementations of web applications 
*/
private boolean check404(WebDriver driver) {
    return driver.getPageSource().contains("404.xhtml");
}

@Test
public void test() throws InterruptedException {

    WebDriver driver = new FirefoxDriver();

    driver.get(APP_URL + "/login");

    Assert.assertEquals(driver.getTitle(), "Login");

    WebElement formName = driver.findElement(By.name("j_username"));
    formName.sendKeys("[email protected]");
    Thread.sleep(50);
    WebElement formPassword = driver.findElement(By.name("j_password"));
    formPassword.sendKeys("password1");
    formName.submit();
    Assert.assertTrue(driver.getCurrentUrl().equals(APP_URL + "/home"));

    // Get some nonexistent url and check that returns 404 code
    driver.get(MODULE_URL + "/sss");

    Assert.assertTrue(check404(driver));

    logger.info("Checking " + URLS.length + " of the application");

    for (String url : URLS) {
        driver.get(url);
        logger.info("Checking " + url);
        //I look for the title here, to verify it's properly loaded. 
        //This implementation may also vary
        Assert.assertTrue(driver.getTitle().equals("MyApp Title"));
        Assert.assertFalse(check404(driver));
    }

    driver.quit();

}

Upvotes: 1

Alexey Melezhik
Alexey Melezhik

Reputation: 971

Interesting example ...

Swat DSL is kind of tool to easy handle such issue but still using curl! Yes, curl is request oriented as you said, and it's true. Sometimes it's problem.

Swat uses curl as well (under the hood), but swat allows sequential http (curl) requests - called swat modules which are just reusable http requests. Like for end user this is a single use case splitted under the hood on many multiples curl requests:

Let me rewrite your selenuim example to swat:

$ mkdir -p myapp/login/post

$ nano myapp/login/post/swat.ini

swat_module=1 # this is reusable curl request
curl_params="-c ${test_root_dir}/cookie.txt -d j_username='%username%' -d j_password=%password%"

$ nano myapp/login/post/post.txt

# authentication post should succeed
200 OK
# should see http redirect code at headers
302
# this is where we are redirected upon successful login
generator: [ resource().'/HOME' ]

$ mkdir -p myapp/check_secured_urls

$ nano myapp/check_secured_urls/hook.pm

# this is a fake resource is not going to be requested 
# spoofing server response
set_response('OK');

run_swat_module(
  POST => '/login/post', {
    username => 'j_username',
    password => 'password1'
  }
)

# GET secured urls
# we should succeed as we already authenticated
   for my $uri ( qw{ FOO FOO/BAR FOR/BAR/BAZ } ) {
         run_swat_module( GET => '/any_url', { uri => $uri }  )
   }

$ nano myapp/check_secured_urls/get.txt

# this is spoofed server response
OK

$ mkdir -p myapp/any_url/

$ nano myapp/any_url/get.txt

200 OK
# always should see this one? 
# not very clear from your example 
<title>MyApp Title</title>

$ nano myapp/any_url/swat.ini

swat_module=1 # this is reusable curl request
curl_params="-b ${test_root_dir}/cookie.txt"

$ nano myapp/any_url/hook.pm

# this is just adapter to GET ANY url:
# so we need dynamically set requested resource:

modify_resource( sub {  module_variable('uri') } );

And finally last one , check none existed pages return 404

$ mkdir myapp/sss

$ echo 'ignore_http_err=1' > myapp/sss/swat.ini

$ echo 'try_num=1' >> myapp/sss/swat.ini

$ echo '404' > myapp/sss/get.txt

$ swat ./ localhost:8080

PS No need to implement check404 for secured URLs as swat does this for you by default.

DISCLOSURE - I am the author of swat.

Upvotes: 4

Related Questions