Newbie questions about Pliant

Newbie questions about Pliant

Extreme Programming, Test Framework

Eqvuivalent of perl's Test, Test::More and Test::Harness
for pliant ?
Message posted by maybe Boris Reitman on 2005/02/02 18:47:57
I have been using Test::Harness and Test 
perl modules to successfully implement
a test framework for my code, which fits
with extreme programming style. I want to also
test my pliant code in a similar fashion.

The idea is that the production code is not written in defensive style.
In other words, it is clean in the sense 
that it doesn't check for errors in the input and output
arguments, and other error conditions.  It simply is a very consise, 
and perhaps smart and cryptic piece of code that does what needs to be done.  
The corresponding tests, that are housed in seperate files make sure that code performs
correct in different scenarios.

Perl's Test framework is a protocol in which ok and not-ok messages
are sent to STDOUT.  Then, Test::Harness counts the number of ok's and not-ok's,
by reading them form STDOUT.

What do you think of the following plan to get Pliant into this game.
Implement functions ok(), is() etc. that corresponds to those in perl's Test
and Test::More modules, and then use Perl's Test::Harness to execute
each pliant program, and read from stdout.  Test::Harness would have 
to be slightly tweaked to run "pliant" as the "interpreter" instead of "perl",
on each test program.




Message posted by maybe Boris Reitman on 2006/05/07 19:05:41
First Question:
--------------
Is it possible to override functions in pliant locally, for testing purposes.
For example, if I have

my_module.pli
----8<------------
function do_network_stuff -> retval
  arg String retval
  # code to access a URL etc.
function do_work
  # some code
  van Str data := do_network_stuff
  # some more code
export do_work
--->8-------------

In my test, I would like to override the implementation of do_network_stuff
with a stub, that actually doesn't do a network operation, but returns 
some test data. Then I would call "do_work" to see if it works as expected.
do_work will call my implementation of "do_network_stuff".

my_test.pli
---8<------------
module "my_module.pli"

local_block
  # overwrite do_network_stuff
  function do_network_stuff -> retval
    arg String retval
    retval := "some fake test data"

  do_work
  check_X

# here once again do_network_stuff is the real implementation.
-->8-------------

Second Question:
---------------
I would like to use the new Pliant webserver to write a simple application.
It is a form which when it is submitted, does some operation X. Given that I
have a way to check that X was completed, how can I write a test which submits 
the data into this form with certain data ?  If it was plain HTTP protocol, 
I would submit a POST or GET request with correct values.  Since HTTP port of 
the new webserver uses lots of Ajax and sends requests back and forth 
everytime I change something on the form, and all the variable names are 
mangled, I still can't write such a test.


Thanks,
Boris
Message posted by hubert.tonneau on 2006/05/07 19:24:40
> In my test, I would like to override the implementation of do_network_stuff
> with a stub

You can try (untested):

  function do_network_stuff -> retval
    arg String retval
    strong_definition
    retval := "some fake test data"

'strong_definition' means if the new definition conflicts with an existing
one, the new one must be selected without raising and 'ambigious' error.

> I would like to use the new Pliant webserver to write a simple application.
> It is a form which when it is submitted, does some operation X.

Let's be clear: the new HTTP server (better called UI HTTP proxy fontend)
has a single goal: provide to users that prefer to use a standard Web browser
as opposed to using Pliant UI client the ability to access an application
written for Pliant UI with as fiew differences as possible.

What I don't understand is why you would like to go low level and worry about
HTTP POST method as opposed to letting it do the stuff through Ajax ?
Message posted by maybe Boris Reitman on 2006/05/07 20:06:02
I don't want to use Ajax or HTTP if I don't have to.  I would like to be 
able to test an interface written for the new UI. Testing an interface means
clicking certain buttons, and filling certain input areas and 
seeing what happens. How could I do that ? I want something like this

tester := new MyTester "pliant://my_uri"
tester set "field1" 5
tester click_button "Clickme"
if (tester get "field2") = 13
  fail
else
  pass

etc... 
Message posted by hubert.tonneau on 2006/05/07 20:14:35
Just try running Pliant UI through:
pliant 'precompile /binary/rip.dump module /pliant/graphic/image/rip.pli' module /pliant/graphic/ui/sample/run.pli command run_both

With Pliant release 96, it works only if you are using Linux (X11),
with release 97, it will also work under Windows.

Then see module:
/pliant/pliant/graphic/ui/sample/test.pli

Also, please notice that the packaging of the Pliant UI (simple way to start
a Pliant UI server or Pliant UI client) is not finished, so it's a bit harsh
to run at the moment.
This will improve with next releases, also it goes too slowly mainly because
the Pliant UI will use the Pliant PML secured streams for remote access, and
the PML secured streams will use the storage to discover public keys, and
the storage is still in bad shape at the moment :-(
So, that's why the command above that runs the client and server within a
single process, so don't use the Pliant PML secured streams is the only easy
way to go at the moment.
Message posted by maybe Boris Reitman on 2006/05/07 20:46:05
My question is how I can write a program to *simulate* all the clicking and filling 
data. This program would be the test, and will be rerun many times throughout
the development cycle. The server and the client may be running at the time
the test starts, or the test itself will initialize the server and the client,
and will drive the client.
Message posted by maybe Boris Reitman on 2006/05/07 20:57:11
Here is an example that tests standard web application that manages links in perl,

----8<--------------
BroadwayFlorists::Swapware::add_bypass_link($site, { username => "$site tester", 
  email => 'flowers@' . $site, 
  sitename => "www.$site Tester",
  url => "http://archimedes.hypervolume.com/~elbokar/test/link_bypass_tester.html",
  category => "Florists",
  description => "This is a bypass test link, it will be removed by the test",
  reciprocal_page => "http://archimedes.hypervolume.com/~elbokar/test/link_bypass_tester_reciprocal.html" });
sleep(2);
$mech = BroadwayFlorists::Swapware::admin_login($site);
contains_string($mech->content, 'http://archimedes.hypervolume.com/~elbokar/test/link_bypass_tester.html');
contains_string($mech->content, 'http://archimedes.hypervolume.com/~elbokar/test/link_bypass_tester_reciprocal.html');
contains_string($mech->content, "flowers@" . $site);
delete_tester_link($mech, qr/link_bypass_tester\.html/);
lacks_string($mech->content, "http://www.$site/test/link_bypass_tester.html");
ok($mech->find_link(text => "new first"));
is($mech->uri, "http://www.swapware.org/Swapware/siteadmin.php?sortby=id+desc&category=%");

## functions

sub delete_tester_link {
  my ($mech, $link_name_regex) = @_;

  my $uri = $mech->uri;
  $mech->follow_link(text => "new first");
  my @forms = $mech->forms;
  my $content = $mech->content;
  my $id = match_id(\$content, $link_name_regex);
  like($id, qr/^\d+$/) or die;

  my $delete_form;
  my $form_number = 1;
  foreach my $form (@forms) {
    if ($form->action() =~ /delete_client_ssl/
      && $form->find_input("id")) {
      if ($form->value("id") eq $id) {
        $delete_form = $form;
        last; } }
    $form_number++; }
  ok($delete_form);
  $mech->form_number($form_number);
  $mech->click();
  $mech->click(); # confirm YES 
  $mech->get($uri); }
--->8----------------------

So I in a same way I'd like to be able to have a pliant robot operate the 
pliant ui interface and checking the state of it after every action.  
Message posted by hubert.tonneau on 2006/05/07 22:30:19
You would need a library to help accessing a Pliant UI server from a program
instead of from the Pliant UI client.
It does not exist at the moment.
Also it would look quite similar to the Pliant UI server API in
/pliant/graphic/ui/server/api.pli

The first and only thing that I can grant that I will do at some point is
provide a tool that display in a human readable format the PML flow exchanged
by the UI client and UI server. Also I have no availability date to provide.
Then it will be easy for a contributor to write the library.

Please also notice that I have no idea at the moment about how hard it would
be to driver a Pliant UI application from a program. I mean that the UI is
intended to be graphical, so things like input fields tend to be identified by
an ID which is random. On the other hand, with most web applications, the
field ID is related to the name of the variable in the server side program.
Also it is possible to use the input field label, it is not granted to be
not empty.

I bet the easiest will be to use the Pliant VNC client scripting possibilies,
just the same way it enables to script any application, Pliant or not.
Here, the problem is also that this part of Pliant is very young, so needs
to be polished, even if it's very promising.
Message posted by maybe Boris Reitman on 2006/05/27 01:03:16
It is possible to test the UI client with Selenium IDE.
http://www.openqa.org/selenium-ide/

Selenium Core doesn't work though, because it puts pliant ui inside an iframe.
I am working on it to allow Selenium Core to load pliant in a standalone window.
If that works, I can use Selenium-Remote-Control proxy server in order to control
the web-browser from a scripting language or directly from pliant. 
(See Test::WWW::Selenium perl module).  This should suffice for now, until 
we can implement the pliant api for testing.