/*
 * Robot Testing Framework
 *
 * Copyright (C) 2015-2019 Istituto Italiano di Tecnologia (IIT)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

/**

@page robottestingframework_python_plugin_example Using Python to develop test cases

\author Ali Paikan

<br>
\section python-desc Description
Test cases can be written using Python scripting language (e.g., .py) to be
loaded and executed as separate plug-ins.
This allows to have a simple test runner which loads and run the tests at run
time without any needs to recompile the test runner.
Using a simple example, we  show how this can be done.

\note The source code of the tutorial can be also found in the
\c 'examples/python-plugin' folder within the Robot Testing Framework project
directory.

<br>
\section python-req Requirements
You need the Python development library to use the plug-ins.
On most of the Linux distribution it can be easily installed using the package
manager (e.g., `   $ sudo apt-get install python-dev`).
If you use Windows, try
<a href="https://www.python.org/downloads/windows/">Python Releases for Windows</a>.
OSX users can also follow the instruction from
http://docs.python-guide.org/en/latest/starting/install/osx/.

After installing the Python development package, you need to enable the Python
plug-in system in the Robot Testing Framework and recompile it:

\verbatim
   $ cd robot-testing-framework/build
   $ cmake ../ -DENABLE_PYTHON_PLUGIN=ON
\endverbatim

<br>
\section python-write Writing the test case in Python
Writing test cases in Python is simple.
All you need is to declare a `TestCase` class and implement your test functional
code inside the `run()` method.
The `setup()` and `tearDown()` can be also optionally defined to setup or tear
down the user defined fixture.
By default, the name of the test case is the name of its plug-in file.
This cane be changed by using using `setName()`.

\htmlonly
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #a31515">&#39;&#39;&#39;</span>
<span style="color: #a31515"> robottestingframework module is automatically imported by the python plugin loader</span>
<span style="color: #a31515"> to invoke the corresponding test case methods. To develop a new </span>
<span style="color: #a31515"> test case simply implement the following class; (setup and tearDown </span>
<span style="color: #a31515"> methods are optional) :</span>

<span style="color: #a31515"> class TestCase:</span>
<span style="color: #a31515">     def setup(self, param):</span>
<span style="color: #a31515">         return True</span>

<span style="color: #a31515">     def run(self):</span>

<span style="color: #a31515">     def tearDown(self):</span>


<span style="color: #a31515"> The following methods are for reporting, failure or assertions: </span>

<span style="color: #a31515"> robottestingframework.setName(name)             : sets the test name (defualt is the test filename)</span>
<span style="color: #a31515"> robottestingframework.testReport(msg)           : reports a informative message</span>
<span style="color: #a31515"> robottestingframework.testCheck(condition, msg) : reports the test message and marks the test as failed if condition is false</span>
<span style="color: #a31515"> robottestingframework.assertError(msg)          : throws an error exception with message</span>
<span style="color: #a31515"> robottestingframework.asserFail(msg)            : throws a failure exception with message</span>
<span style="color: #a31515">&#39;&#39;&#39;</span>

<span style="color: #0000ff">class</span> <span style="color: #2b91af">TestCase</span>:
    <span style="color: #008000"># setup is called before the test&#39;s run to setup </span>
    <span style="color: #008000"># the user defined fixture</span>
    <span style="color: #008000"># @return Boolean (True/False uppon success or failure)</span>
    <span style="color: #0000ff">def</span> setup(self, param):
        robottestingframework.testReport(<span style="color: #a31515">&quot;Preparing setup...&quot;</span>)
        <span style="color: #0000ff">return</span> True

    <span style="color: #008000"># The implementation of the test goes here</span>
    <span style="color: #0000ff">def</span> run(self):
        robottestingframework.testCheck(5&gt;3, <span style="color: #a31515">&quot;5 is bigger than 3.&quot;</span>)
        robottestingframework.testCheck(5&lt;3, <span style="color: #a31515">&quot;5 is smaller than 3.&quot;</span>)

    <span style="color: #008000"># tearDown is called after the test&#39;s run to tear down</span>
    <span style="color: #008000"># the user defined fixture</span>
    <span style="color: #0000ff">def</span> tearDown(self):
        robottestingframework.testReport(<span style="color: #a31515">&quot;Tearing down...&quot;</span>)
</pre></div>
\endhtmlonly


<br>
\section python-runner Writing the test runner
\note Basically you do not need to develop a test runner.
There is the \c robottestingframework-testrunner utility (see
\ref robottestingframework-testrunner) already implemented in
Robot Testing Framework which does the job for you.
However, the following example is just for your reference and to understand
better how a Python test plug-ing can be loaded and executed from the code.

Your plug-in is ready and can be simply executed using the
\c robottestingframework-testrunner utility.
However, we show how to use \c robottestingframework::PythonPluginLoader to
develop a simple test runner for loading the plug-in and running the test.
It is quite simple.
First create an instance of \c robottestingframework::plugin::PythonPluginLoader
class and call its \c open() method with the plug-in library (i.e., .py)
filename as its parameter.
The \c robottestingframework::plugin::PythonPluginLoader loads the library and
returns a pointer to the \c robottestingframework::TestCase implemented into the
plug-in.
If the Python plug-in cannot be loaded or it is not an Robot Testing Framework
plug-in file, the \c robottestingframework::plugin::PythonPluginLoader::open()
returns a null pointer and the error message can be gotten using
\c robottestingframework::plugin::PythonPluginLoader::getLastError().
When you have an instance of your test case, it can be used to run the test as
usual (see \ref robottestingframework_examples if you are not familiar with
running a test case).
In the following example we use a \c robottestingframework::TestRunner to
execute our test:

\include python-plugin/run.cpp

<br>
\section python-build Building the test runner and run the test
Now you can compile and build the the runner.
There is a CMake file in the \c examples/python-plugin folder which helps you to
compile and build your simple test runner.
Make sure that \c RobotTestingFramework_DIR environment variable is correctly
set to point your Robot Testing Framework build or installed directory so that
CMake can find the required modules to configure the project.

\include python-plugin/CMakeLists.txt
<br>
Now you can build and run the test as follows:
\verbatim
$ cd examples/python-plugin; mkdir build
$ cd build; cmake ../; make;
$ ./simple_run ../mytest.py
Loading the plugin...
Starting test runner.
Test case  started...
[INFO]  (mytest.lua) reports: Preparing setup...
[INFO]  (mytest.lua) checks: 5 is bigger than 3
[FAIL]  (mytest.lua) checks: 5 is less than 3
[INFO]  (mytest.lua) reports: Tearing down...
Test case MyTest failed!
Ending test runner.
\endverbatim

*/
