<commit_before>Creating test libraries
-----------------------

Robot Framework's actual testing capabilities are provided by test
libraries. There are many existing libraries, some of which are even
bundled with the core framework, but there is still often a need to
create new ones. This task is not too complicated because, as this
chapter illustrates, Robot Framework's library API is simple
and straightforward.

.. contents::
   :depth: 2 
   :local: 


Introduction
~~~~~~~~~~~~

Supported programming languages
'''''''''''''''''''''''''''''''

Robot Framework itself is written with Python_, so naturally, test 
libraries extending it can be implemented using the same
language. Additionally, it is possible to write libraries using Java_,
which requires running the framework on the Jython_ interpreter. Pure
Python code works both on Python and Jython interpreters, assuming
that it does not use syntax or libraries that are not available on
Jython.

It is also possible to implement a test library with C by using
`Python C API`_. Another, and in most cases easier, method to
interact with C code from a library is using Python's ctypes_ module.

.. _Python C API: http://docs.python.org/api/api.html
.. _ctypes: http://docs.python.org/lib/module-ctypes.html

Finally, it is possible to implement the actual test library
functionality using any language and call that from a thin Python or
Java wrapper library. Possible approaches include calling external
scripts or tools through the operating system or using XML-RPC to
connect the wrapper with the real implementation. The former approach
is quite widely used and there is a proof-of-concept prototype also
for the latter. The plan is to have XML-RPC support built in to Robot
Framework in the future.


Different test library APIs
'''''''''''''''''''''''''''

Robot Framework has three different test library APIs. 

Static API 

  The simplest approach is having a module (in Python) or a class
  (in Python or Java) with methods the names of which map more or less
  directly to `keyword names`_. Keywords also take the same `arguments`__ as
  the code implementing them.  Keywords `report failures`__ with
  exceptions, `log`__ by writing to standard output and can `return
  values`__ using the :code:`return` statement.

Dynamic API

  Dynamic libraries are classes that implement a method to get the names
  of the keywords they implement, and another method to execute a named 
  keyword with given arguments. The names of the keywords to implement, as
  well as how they are executed, can be determined dynamically at
  runtime, but reporting the status, logging and returning values is done
  similarly as in the static API.

Hybrid API

  This is a hybrid between the static and the dynamic API. Libraries are
  classes with a method telling what keywords they implement, but
  those keywords must be available directly. Everything else except
  discovering what keywords are implemented is similar as in the
  static API.
  
All these APIs are described in this chapter. Everything is based on
how the static API works, so its functions are discussed first. How
the `dynamic library API`_ and the `hybrid library API`_ differ from it
is then discussed in sections of their own.

The examples in this chapter are mainly about using Python, but they
should be easy to understand also for Java-only developers. In those
few cases where APIs have differences, both usages are explained with
adequate examples.

__ `Keyword arguments`_
__ `Reporting keyword status`_
__ `Logging information`_
__ `Returning values`_


Creating test library class or module
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Test libraries can be implemented as Python modules or Python or Java classes. 
In Robot Framework 2.0.1 and earlier, it is possible to use only classic
classes as test libraries. Both classic and new style classes are 
supported from 2.0.2 onwards.


Test library names
''''''''''''''''''

The name of a test library that is used when a library is imported is
the same as the name of the module or class implementing it. For
example, if you have a Python module :code:`MyLibrary` (that is, the
file :path:`MyLibrary.py`), it will create a library with a name
:name:`MyLibrary`. Similarly, a Java class :code:`YourLibrary`, when
it is not in any package, creates a library with exactly that name.

Python classes are always inside a module. If the name of a class
implementing a library is the same as the name of the module, Robot
Framework allows dropping the module name when importing the
library. For example, the class :code:`MyLib` in the :path:`MyLib.py`
file can be used as a library with the name :name:`MyLib`. If the
module name and class name are different, libraries must be taken into
use using both module and class names, such as
:name:`mymodule.MyLibrary`.

Java classes in a non-default package must be taken into use with the
full name. For example, the class :code:`MyLib` in the
:code:`com.mycompany.myproject` package must be imported with the name
:name:`com.mycompany.myproject.MyLib`.

.. Tip:: If the library name is really long, for example when the Java
         package name is long, it is recommended to give the library a
         simpler alias by using the `With Name syntax`_.
<commit_msg>With Name -> WITH NAME (although that's caseinsensitive I prefer the latter format)<commit_after>Creating test libraries
-----------------------

Robot Framework's actual testing capabilities are provided by test
libraries. There are many existing libraries, some of which are even
bundled with the core framework, but there is still often a need to
create new ones. This task is not too complicated because, as this
chapter illustrates, Robot Framework's library API is simple
and straightforward.

.. contents::
   :depth: 2 
   :local: 


Introduction
~~~~~~~~~~~~

Supported programming languages
'''''''''''''''''''''''''''''''

Robot Framework itself is written with Python_, so naturally, test 
libraries extending it can be implemented using the same
language. Additionally, it is possible to write libraries using Java_,
which requires running the framework on the Jython_ interpreter. Pure
Python code works both on Python and Jython interpreters, assuming
that it does not use syntax or libraries that are not available on
Jython.

It is also possible to implement a test library with C by using
`Python C API`_. Another, and in most cases easier, method to
interact with C code from a library is using Python's ctypes_ module.

.. _Python C API: http://docs.python.org/api/api.html
.. _ctypes: http://docs.python.org/lib/module-ctypes.html

Finally, it is possible to implement the actual test library
functionality using any language and call that from a thin Python or
Java wrapper library. Possible approaches include calling external
scripts or tools through the operating system or using XML-RPC to
connect the wrapper with the real implementation. The former approach
is quite widely used and there is a proof-of-concept prototype also
for the latter. The plan is to have XML-RPC support built in to Robot
Framework in the future.


Different test library APIs
'''''''''''''''''''''''''''

Robot Framework has three different test library APIs. 

Static API 

  The simplest approach is having a module (in Python) or a class
  (in Python or Java) with methods the names of which map more or less
  directly to `keyword names`_. Keywords also take the same `arguments`__ as
  the code implementing them.  Keywords `report failures`__ with
  exceptions, `log`__ by writing to standard output and can `return
  values`__ using the :code:`return` statement.

Dynamic API

  Dynamic libraries are classes that implement a method to get the names
  of the keywords they implement, and another method to execute a named 
  keyword with given arguments. The names of the keywords to implement, as
  well as how they are executed, can be determined dynamically at
  runtime, but reporting the status, logging and returning values is done
  similarly as in the static API.

Hybrid API

  This is a hybrid between the static and the dynamic API. Libraries are
  classes with a method telling what keywords they implement, but
  those keywords must be available directly. Everything else except
  discovering what keywords are implemented is similar as in the
  static API.
  
All these APIs are described in this chapter. Everything is based on
how the static API works, so its functions are discussed first. How
the `dynamic library API`_ and the `hybrid library API`_ differ from it
is then discussed in sections of their own.

The examples in this chapter are mainly about using Python, but they
should be easy to understand also for Java-only developers. In those
few cases where APIs have differences, both usages are explained with
adequate examples.

__ `Keyword arguments`_
__ `Reporting keyword status`_
__ `Logging information`_
__ `Returning values`_


Creating test library class or module
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Test libraries can be implemented as Python modules or Python or Java classes. 
In Robot Framework 2.0.1 and earlier, it is possible to use only classic
classes as test libraries. Both classic and new style classes are 
supported from 2.0.2 onwards.


Test library names
''''''''''''''''''

The name of a test library that is used when a library is imported is
the same as the name of the module or class implementing it. For
example, if you have a Python module :code:`MyLibrary` (that is, the
file :path:`MyLibrary.py`), it will create a library with a name
:name:`MyLibrary`. Similarly, a Java class :code:`YourLibrary`, when
it is not in any package, creates a library with exactly that name.

Python classes are always inside a module. If the name of a class
implementing a library is the same as the name of the module, Robot
Framework allows dropping the module name when importing the
library. For example, the class :code:`MyLib` in the :path:`MyLib.py`
file can be used as a library with the name :name:`MyLib`. If the
module name and class name are different, libraries must be taken into
use using both module and class names, such as
:name:`mymodule.MyLibrary`.

Java classes in a non-default package must be taken into use with the
full name. For example, the class :code:`MyLib` in the
:code:`com.mycompany.myproject` package must be imported with the name
:name:`com.mycompany.myproject.MyLib`.

.. Tip:: If the library name is really long, for example when the Java
         package name is long, it is recommended to give the library a
         simpler alias by using the `WITH NAME syntax`_.

{'fraction_non_alphanumeric': 0.06845070422535211, 'fraction_numerical': 0.0013145539906103286, 'mean_word_length': 4.2675568743818, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '678989', 'n_tokens_mistral': 2687, 'n_tokens_neox': 2596, 'n_words': 1587}