6 new revisions:
Revision: 51a7b0202736
Author: Pekka Klärck
Date: Mon Jun 13 03:27:37 2011
Log: Pass setup/teardown type to all start/end_keyword listener
methods exe...
http://code.google.com/p/robotframework/source/detail?r=51a7b0202736
Revision: 61f5f29f8af6
Author: Pekka Klärck
Date: Mon Jun 13 03:43:55 2011
Log: (whitespace) cleanup
http://code.google.com/p/robotframework/source/detail?r=61f5f29f8af6
Revision: c7682275527e
Author: Pekka Klärck
Date: Mon Jun 13 03:54:35 2011
Log: bump
http://code.google.com/p/robotframework/source/detail?r=c7682275527e
Revision: 36dc4f55cc18
Author: Pekka Klärck
Date: Mon Jun 13 03:55:56 2011
Log: Documented new type attribute of start/end_keyword listener
methods...
http://code.google.com/p/robotframework/source/detail?r=36dc4f55cc18
Revision: addacfa6082a
Author: Pekka Klärck
Date: Mon Jun 13 03:56:00 2011
Log: regen
http://code.google.com/p/robotframework/source/detail?r=addacfa6082a
Revision: d2749a2e0a63
Author: Pekka Klärck
Date: Mon Jun 13 03:56:11 2011
Log: Automated merge with https://robotframework.googlecode.com/hg/
http://code.google.com/p/robotframework/source/detail?r=d2749a2e0a63
==============================================================================
Revision: 51a7b0202736
Author: Pekka Klärck
Date: Mon Jun 13 03:27:37 2011
Log: Pass setup/teardown type to all start/end_keyword listener
methods executed as a part of setup/teardown. Also changed the type to
title case (e.g. 'test setup' -> 'Test Setup').
Update issue 859
I thought about this a bit myself and come to conclusion that it's better
if all keywords executd as a part of setup/teardown got a correct type.
http://code.google.com/p/robotframework/source/detail?r=51a7b0202736
Modified:
/atest/testdata/misc/setups_and_teardowns.txt
/atest/testresources/listeners/listeners.py
/src/robot/output/listeners.py
=======================================
--- /atest/testdata/misc/setups_and_teardowns.txt Sat Jun 11 15:59:22 2011
+++ /atest/testdata/misc/setups_and_teardowns.txt Mon Jun 13 03:27:37 2011
@@ -1,11 +1,29 @@
***Settings***
Documentation This suite was initially created for testing keyword types
with
... listeners but can be used for other purposes too.
-Suite Setup Log Suite Setup
-Suite Teardown Log Suite Teardown
-Test Setup Log Test Setup
-Test Teardown Log Test Teardown
+Suite Setup Suite Setup
+Suite Teardown Suite Teardown
+Test Setup Test Setup
+Test Teardown Test Teardown
***Test Cases***
+
Test with setup and teardown
+ Keyword
+
+***Keywords***
+
+Suite Setup
+ Log Suite Setup
+
+Suite Teardown
+ Log Suite Teardown
+
+Test Setup
+ Log Test Setup
+
+Test Teardown
+ Log Test Teardown
+
+Keyword
Log Keyword
=======================================
--- /atest/testresources/listeners/listeners.py Sat Jun 11 15:59:22 2011
+++ /atest/testresources/listeners/listeners.py Mon Jun 13 03:27:37 2011
@@ -66,9 +66,10 @@
ROBOT_LISTENER_API_VERSION = '2'
def start_keyword(self, name, attrs):
- if attrs['type'] != attrs['args'][0].lower():
+ expected = attrs['args'][0] if name == 'BuiltIn.Log' else name
+ if attrs['type'] != expected:
raise RuntimeError("Wrong keyword type '%s', expected '%s'."
- % (attrs['type'], attrs['args'][0].lower()))
+ % (attrs['type'], expected))
end_keyword = start_keyword
=======================================
--- /src/robot/output/listeners.py Sat Jun 11 15:59:22 2011
+++ /src/robot/output/listeners.py Mon Jun 13 03:27:37 2011
@@ -30,8 +30,9 @@
_end_attrs = _start_attrs +
['endtime', 'elapsedtime', 'status', 'message']
def __init__(self, listeners):
- self._running_test = False
self._listeners = self._import_listeners(listeners)
+ self._running_test = False
+ self._setup_or_teardown_type = None
def __nonzero__(self):
return bool(self._listeners)
@@ -95,23 +96,32 @@
li.call_method(li.start_keyword, kw.name, kw.args)
else:
attrs = self._get_start_attrs(kw, 'args', '-longname')
- attrs['type'] = self._get_keyword_type(kw)
+ attrs['type'] = self._get_keyword_type(kw, start=True)
li.call_method(li.start_keyword, kw.name, attrs)
- def _get_keyword_type(self, kw):
- if kw.type == 'kw':
- return 'keyword'
- return '%s %s' % (('test' if self._running_test else 'suite'),
kw.type)
-
def end_keyword(self, kw):
for li in self._listeners:
if li.version == 1:
li.call_method(li.end_keyword, kw.status)
else:
attrs =
self._get_end_attrs(kw, 'args', '-longname', '-message')
- attrs['type'] = self._get_keyword_type(kw)
+ attrs['type'] = self._get_keyword_type(kw, start=False)
li.call_method(li.end_keyword, kw.name, attrs)
+ def _get_keyword_type(self, kw, start=True):
+ # When running setup or teardown, only the top level keyword has
type
+ # set to setup/teardown but we want to pass that type also to all
+ # start/end_keyword listener methods called below that keyword.
+ if kw.type == 'kw':
+ return self._setup_or_teardown_type or 'Keyword'
+ kw_type = self._get_setup_or_teardown_type(kw)
+ self._setup_or_teardown_type = kw_type if start else None
+ return kw_type
+
+ def _get_setup_or_teardown_type(self, kw):
+ return '%s %s' % (('Test' if self._running_test else 'Suite'),
+ kw.type.title())
+
def log_message(self, msg):
for li in self._listeners:
if li.version == 2:
==============================================================================
Revision: 61f5f29f8af6
Author: Pekka Klärck
Date: Mon Jun 13 03:43:55 2011
Log: (whitespace) cleanup
http://code.google.com/p/robotframework/source/detail?r=61f5f29f8af6
Modified:
/doc/userguide/src/ExtendingRobotFramework/ListenerInterface.txt
=======================================
--- /doc/userguide/src/ExtendingRobotFramework/ListenerInterface.txt Thu
Sep 16 12:37:09 2010
+++ /doc/userguide/src/ExtendingRobotFramework/ListenerInterface.txt Mon
Jun 13 03:43:55 2011
@@ -2,16 +2,15 @@
------------------------
Robot Framework has a listener interface that can be used to receive
-notifications about test execution. Listeners are classes with certain
special
-methods, and they can be implemented both with Python and Java. Starting
from
-version 2.0.2, it is also possible to implement listeners as Python
modules.
-Example uses of the listener interface include external test monitors,
sending
-a mail message when a test fails, and communicating with other systems.
-
-.. contents::
+notifications about test execution. Listeners are classes or modules
+with certain special methods, and they can be implemented both with
+Python and Java. Example uses of the listener interface include
+external test monitors, sending a mail message when a test fails, and
+communicating with other systems.
+
+.. contents::
:depth: 2
- :local:
-
+ :local:
Taking listeners into use
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -22,14 +21,14 @@
listener interface, similarly as `test library names`_ are got from classes
implementing them. The specified listeners must be in the same `module
search
path`_ where test libraries are searched from when they are imported. Other
-option is to give an absolute or a relative path to the listener file
-`similarly as with test libraries`__. It is possible to take multiple
listeners
+option is to give an absolute or a relative path to the listener file
+`similarly as with test libraries`__. It is possible to take multiple
listeners
into use by using this option several times.
Starting from version 2.0.2, it is also possible to give arguments to
listener
-classes from the command line. Arguments are specified after the listener
name
-(or path) using a colon as a separator. This approach provides only string
-type arguments and arguments obviously cannot contain colons. However, it
+classes from the command line. Arguments are specified after the listener
name
+(or path) using a colon as a separator. This approach provides only string
+type arguments and arguments obviously cannot contain colons. However, it
should be pretty easy to listeners to go around these limitations.
__ `Using physical path to library`_
@@ -43,7 +42,6 @@
pybot --listener ListenerWithArgs:arg1:arg2
pybot --listener path/to/MyListener.java:argument tests.html
-
Available listener interface methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -55,7 +53,6 @@
implement any official interface, and it only needs to have the methods it
actually needs.
-
Listener interface versions
'''''''''''''''''''''''''''
@@ -65,14 +62,13 @@
will continue to work, but they will be deprecated in some future version,
so
all new listeners should be implemented with signatures described in the
table
below. The most recent detailed description of the old listener interface
can
-be found in User Guide of Robot Framework 2.0.4.
-
-.. note:: A listener must have attribute :code:`ROBOT_LISTENER_API_VERSION`
+be found in User Guide of Robot Framework 2.0.4.
+
+.. note:: A listener must have attribute :code:`ROBOT_LISTENER_API_VERSION`
defined in order to be recognized as a new style listener. Value of the
:code:`ROBOT_LISTENER_API_VERSION` attribute must be 2, either as a
string or
as an integer. The examples below are implemented as new style listeners.
-
Listener interface method signatures
''''''''''''''''''''''''''''''''''''
@@ -82,8 +78,8 @@
following table lists all the available methods in the listener interface
and
the contents of the :code:`attributes` dictionary, where applicable. Keys
of
the dictionary are strings. All of these methods have also `camelCase`
aliases.
-Thus, for example, :code:`startSuite` is a synonym to :code:`start_suite`.
-
+Thus, for example, :code:`startSuite` is a synonym to :code:`start_suite`.
+
.. table:: Available methods in the listener interface
:class: tabular
@@ -104,7 +100,7 @@
| | | * totaltests: total number of
tests in this suite|
| | | and all its sub-suites as an
integer |
| |
| |
- | | | The last four were added in Robot
Framework 2.5 |
+ | | | The last four were added in Robot
Framework 2.5. |
+---------------+------------------+--------------------------------------------------+
| end_suite | name, attributes | Keys in the attributes
dictionary: |
| |
| |
@@ -228,7 +224,6 @@
void debugFile(String path);
void close();
}
-
Listener examples
~~~~~~~~~~~~~~~~~
@@ -242,7 +237,7 @@
def start_test(name, attrs):
print 'Executing test %s' % name
-
+
def start_keyword(name, attrs):
print 'Executing keyword %s with arguments %s' % (name,
attrs['args'])
@@ -252,7 +247,6 @@
def close():
print 'All tests executed'
-
The second example, which still uses Python, is slightly more complicated.
It
writes all the information it gets into a text file in a temporary
directory
without much formatting. The filename may be given from the command line,
but
@@ -269,31 +263,30 @@
class PythonListener:
ROBOT_LISTENER_API_VERSION = 2
-
+
def __init__(self, filename='listen.txt'):
outpath = os.path.join(tempfile.gettempdir(), filename)
self.outfile = open(outpath, 'w')
-
+
def start_suite(self, name, attrs):
self.outfile.write("%s '%s'\n" % (name, attrs['doc']))
-
+
def start_test(self, name, attrs):
tags = ' '.join(attrs['tags'])
self.outfile.write("- %s '%s' [ %s ] :: " % (name,
attrs['doc'], tags))
-
+
def end_test(self, name, attrs):
if attrs['status'] == 'PASS':
self.outfile.write('PASS\n')
else:
self.outfile.write('FAIL: %s\n' % attrs['message'])
-
+
def end_suite(self, name, attrs):
self.outfile.write('%s\n%s\n' % (attrs['status'],
attrs['message']))
-
+
def close(self):
self.outfile.close()
-
The third example implements the same functionality as the previous one,
but uses Java instead of Python.
.. sourcecode:: java
@@ -304,7 +297,7 @@
public class JavaListener {
-
+
public static final int ROBOT_LISTENER_API_VERSION = 2;
public static final String DEFAULT_FILENAME = "listen_java.txt";
private BufferedWriter outfile = null;
@@ -312,14 +305,14 @@
public JavaListener() throws IOException {
this(DEFAULT_FILENAME);
}
-
+
public JavaListener(String filename) throws IOException {
String tmpdir = System.getProperty("java.io.tmpdir");
String sep = System.getProperty("file.separator");
- String outpath = tmpdir + sep + filename;
+ String outpath = tmpdir + sep + filename;
outfile = new BufferedWriter(new FileWriter(outpath));
}
-
+
public void startSuite(String name, Map attrs) throws IOException {
outfile.write(name + " '" + attrs.get("doc") + "'\n");
}
@@ -332,7 +325,7 @@
}
outfile.write(" ] :: ");
}
-
+
public void endTest(String name, Map attrs) throws IOException {
String status = attrs.get("status").toString();
if (status.equals("PASS")) {
@@ -342,11 +335,11 @@
outfile.write("FAIL: " + attrs.get("message") + "\n");
}
}
-
+
public void endSuite(String name, Map attrs) throws IOException {
outfile.write(attrs.get("status") + "\n" + attrs.get("message")
+ "\n");
}
-
+
public void close() throws IOException {
outfile.close();
}
==============================================================================
Revision: c7682275527e
Author: Pekka Klärck
Date: Mon Jun 13 03:54:35 2011
Log: bump
http://code.google.com/p/robotframework/source/detail?r=c7682275527e
Modified:
/src/robot/version.py
=======================================
--- /src/robot/version.py Fri May 27 12:00:12 2011
+++ /src/robot/version.py Mon Jun 13 03:54:35 2011
@@ -3,8 +3,8 @@
import sys
VERSION = 'trunk'
-RELEASE = '20110527'
-TIMESTAMP = '20110527-215819'
+RELEASE = '20110613'
+TIMESTAMP = '20110613-134844'
def get_version(sep=' '):
if RELEASE == 'final':
==============================================================================
Revision: 36dc4f55cc18
Author: Pekka Klärck
Date: Mon Jun 13 03:55:56 2011
Log: Documented new type attribute of start/end_keyword listener
methods
Update issue 859
Status: Done
Now this is also documented in the user guide. I consider this done but
comments are still appreciated.
http://code.google.com/p/robotframework/source/detail?r=36dc4f55cc18
Modified:
/doc/userguide/src/ExtendingRobotFramework/ListenerInterface.txt
=======================================
--- /doc/userguide/src/ExtendingRobotFramework/ListenerInterface.txt Mon
Jun 13 03:43:55 2011
+++ /doc/userguide/src/ExtendingRobotFramework/ListenerInterface.txt Mon
Jun 13 03:55:56 2011
@@ -140,7 +140,12 @@
| |
| |
| | | * doc: keyword
documentation |
| | | * starttime: execution start
time |
- | | | * args: keyword arguments as a
list of strings |
+ | | | * args: keyword's arguments as a
list of strings |
+ | | | * type: string :code:`Keyword` for
normal |
+ | | | keywords and :code:`Test
Setup`, :code:`Test |
+ | | | Teardown`, :code:`Suite Setup`
or :code:`Suite |
+ | | | Teardown` for keywords used in
suite/test |
+ | | | setup/teardown. New in Robot
Framework 2.6. |
+---------------+------------------+--------------------------------------------------+
| end_keyword | name, attributes | Keys in the attributes
dictionary: |
| |
| |
@@ -151,6 +156,7 @@
| | | as an
integer |
| | | * args: keyword's arguments as a
list of strings |
| | | * status: either :code:`PASS`
or :code:`FAIL` |
+ | | | * type: Same as
with :code:`start_keyword` |
+---------------+------------------+--------------------------------------------------+
| log_message | message | Called when an executed keyword
writes a log |
| | | message. :code:`message` is a
dictionary with |
==============================================================================
Revision: addacfa6082a
Author: Pekka Klärck
Date: Mon Jun 13 03:56:00 2011
Log: regen
http://code.google.com/p/robotframework/source/detail?r=addacfa6082a
Modified:
/doc/userguide/RobotFrameworkUserGuide.html
=======================================
--- /doc/userguide/RobotFrameworkUserGuide.html Fri May 27 12:02:05 2011
+++ /doc/userguide/RobotFrameworkUserGuide.html Mon Jun 13 03:56:00 2011
@@ -488,7 +488,7 @@
<body>
<div class="document" id="robot-framework-user-guide">
<h1 class="title">Robot Framework User Guide</h1>
-<h2 class="subtitle" id="version-version">Version trunk 20110527</h2>
+<h2 class="subtitle" id="version-version">Version trunk 20110613</h2>
<!-- This data file has been placed in the public domain. -->
<!-- Derived from the Unicode character mappings available from
@@ -12680,11 +12680,11 @@
<div class="section" id="using-listener-interface">
<h2><a class="toc-backref" href="#id519">4.3 Using
listener interface</a></h2>
<p>Robot Framework has a listener interface that can be used to receive
-notifications about test execution. Listeners are classes with certain
special
-methods, and they can be implemented both with Python and Java. Starting
from
-version 2.0.2, it is also possible to implement listeners as Python
modules.
-Example uses of the listener interface include external test monitors,
sending
-a mail message when a test fails, and communicating with other systems.</p>
+notifications about test execution. Listeners are classes or modules
+with certain special methods, and they can be implemented both with
+Python and Java. Example uses of the listener interface include
+external test monitors, sending a mail message when a test fails, and
+communicating with other systems.</p>
<div class="contents local topic" id="id206">
<ul class="auto-toc simple">
<li><a class="reference internal" href="#taking-listeners-into-use"
id="id578">4.3.1 Taking listeners into use</a></li>
@@ -12787,7 +12787,7 @@
<li>totaltests: total number of tests in this suite
and all its sub-suites as an integer</li>
</ul>
-<p class="last">The last four were added in Robot Framework 2.5</p>
+<p class="last">The last four were added in Robot Framework 2.5.</p>
</td>
</tr>
<tr><td>end_suite</td>
@@ -12842,7 +12842,12 @@
<ul class="last simple">
<li>doc: keyword documentation</li>
<li>starttime: execution start time</li>
-<li>args: keyword arguments as a list of strings</li>
+<li>args: keyword's arguments as a list of strings</li>
+<li>type: string <span class="code">Keyword</span> for normal
+keywords and <span class="code">Test Setup</span>, <span class="code">Test
+Teardown</span>, <span class="code">Suite Setup</span> or <span
class="code">Suite
+Teardown</span> for keywords used in suite/test
+setup/teardown. New in Robot Framework 2.6.</li>
</ul>
</td>
</tr>
@@ -12857,6 +12862,7 @@
as an integer</li>
<li>args: keyword's arguments as a list of strings</li>
<li>status: either <span class="code">PASS</span> or <span
class="code">FAIL</span></li>
+<li>type: Same as with <span class="code">start_keyword</span></li>
</ul>
</td>
</tr>
@@ -14098,7 +14104,7 @@
<div class="footer">
<hr class="footer" />
<p>Generated by <a class="reference external"
href="http://docutils.sourceforge.net/rst.html">reStructuredText</a>.
Syntax highlighting by <a class="reference external"
href="http://pygments.org/">Pygments</a>.</p>
-<p>Generated on: 2011-05-27 19:01 UTC.
+<p>Generated on: 2011-06-13 10:54 UTC.
</p>
</div>
==============================================================================
Revision: d2749a2e0a63
Author: Pekka Klärck
Date: Mon Jun 13 03:56:11 2011
Log: Automated merge with https://robotframework.googlecode.com/hg/
http://code.google.com/p/robotframework/source/detail?r=d2749a2e0a63