I am currently working on adding support for execution of Robot scripts from our home-grown Automation Framework. I understand that Robot, by default, generates the output.xml file upon the execution of the Robot scripts.
So as to maintain uniformity, I am exploring the option of using the Robot Logging module for our custom automation scripts as well. On checking the source code, I see there is a Logger class under robot.output directory which logs messages on the console. However, I want to generate the same log and report files as it is done for the Robot scripts. For that, I need to know how the output.xml is generated and how it works.
Can someone point me to the correct module/direction to move forward on this?
robot/running/model.py defines a class named TestSuite. In that class definition is a method named run which is responsible for running the test. As part of its initialization it creates an instance of Output, which is the xml logger. This logger is defined in the file robot/output/output.py.
Related
Some Background:
While building the documentation of a library with sphinx I measure some rendering times (for rendering videos with that library) using a custom Directive and save them to an csv file. To get a readable log I don't want to print them right away, but as soon as a all of them have been run, for example right at the end of the build log. I already have a script producing that rendering summary.
The actual question:
Where do I need to call my logging script so that it is executed once after the step "reading sources" is done? I don't really care about the exact position at which it is added to the log.
Sphinx defines several events that can be used to trigger event handlers (via a setup() function). I am not sure which event is most suitable in your case, but here is the list of core events:
https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx-core-events
Earlier I was using python unittest in my project, and with it came unittest.TextTestRunner and unittest.defaultTestLoader.loadTestsFromTestCase. I used them for the following reasons,
Control the execution of unittest using a wrapper function which calls the unittests's run method. I did not want the command line approach.
Read the unittest's output from the result object and upload the results to a bug tracking system which allow us to generate some complex reports on code stability.
Recently there was a decision made to switch to py.test, how can I do the above using py.test ? I don't want to parse any CLI/HTML to get the output from py.test. I also don't want to write too much code on my unit test file to do this.
Can someone help me with this ?
You can use the pytest's hook to intercept the test result reporting:
conftest.py:
import pytest
#pytest.hookimpl(hookwrapper=True)
def pytest_runtest_logreport(report):
yield
# Define when you want to report:
# when=setup/call/teardown,
# fields: .failed/.passed/.skipped
if report.when == 'call' and report.failed:
# Add to the database or an issue tracker or wherever you want.
print(report.longreprtext)
print(report.sections)
print(report.capstdout)
print(report.capstderr)
Similarly, you can intercept one of these hooks to inject your code at the needed stage (in some cases, with the try-except around yield):
pytest_runtest_protocol(item, nextitem)
pytest_runtest_setup(item)
pytest_runtest_call(item)
pytest_runtest_teardown(item, nextitem)
pytest_runtest_makereport(item, call)
pytest_runtest_logreport(report)
Read more: Writing pytest plugins
All of this can be easily done either with a tiny plugin made as a simple installable library, or as a pseudo-plugin conftest.py which just lies around in one of the directories with the tests.
It looks like pytest lets you launch from Python code instead of using the command line. It looks like you just pass the same arguments to the function call that would be on the command line.
Pytest will create resultlog format files, but the feature is deprecated. The documentation suggests using the pytest-tap plugin that produces files in the Test Anything Protocol.
I use robot framework 3.0 under Python 2.7.8. Robot framework's documentation (http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#programmatic-logging-apis) states that
In addition to the new public logging API, Robot Framework offers a built-in support to Python's standard logging module. This works so that all messages that are received by the root logger of the module are automatically propagated to Robot Framework's log file.
I made a short library file to test this:
from logging import debug, error, info, warn
def try_logging():
info("This is merely a humble info message.")
debug("Most users never saw me.")
warn("I warn you about something.")
error("Something bad happened.")
My test case is:
*** Test Cases ***
Logtest
Try logging
When I run it it is a PASSED case, but nothing logged into the HTML log. The test execution log has the suit and the case and the keyword as it should but when I expand them nothing is logged but the "Start / End / Elapsed" line.
How could I forward the Python logger messages to Robot? As you can see the so called automatic propagation is not working automatically. My goal is to write a library that can be run with or without Robot Fw.
Ty for your help in advance.
After hours of code digging I managed to find the answer. I think it is worth sharing as it may be help you if you have some similar issue.
In my case I had some unused libraries imported. One of them was a class that was instantiated when Robot Framework imported the library file. This object had some logger settings that messed up the defaults, that is why I got no result in the robot log.
Without it I got the expected results and automatic propagation worked fine.
In python unittest, can how do i define a custom unittest.TextTestRunner class? I need to use the Python logger module and ensure that all logs go to the log file created by the Python logger module. Especially when exceptions and assert errors are thrown up they need to go to this log file. I need to be able to user the logger.info() and logger.warning() functions and so on.
Can anyone give me some sample code or link to sample code or steps to do so.
I am currently working on adding some features to a plone website and I would like to be able to run a python script using content rules. For example, I've written an article and I want to publish it : using a rule triggered by a condition I want to run a certain script which is not related to the object.
I have already installed Runscript but the problem is that apparently the script has to be related to the object that triggered the action.
I have a simple script that just opens a text file to write 'Hello World' in it :
with open("hello.txt", "w") as fichier:
fichier.write("Hello world")
and plone give me the following error on my script (which works outside of plone) :
Module script, line 1, in hello
<FSPythonScript at /Plone2/hello used for /Plone2/news/azertyazert> Line 1
NameError: global name 'open' is not defined
On other scripts I also get the page I don't have sufficient rights to change the state of the article (thus triggering the condition rule).
Anyway, that was with Runscript, does anyone know either a another way to do execute scripts when rules are triggered or how to make runscript any script ?
Python scripts inside Zope / Plone run in a restricted environment. The error is thrown because you cannot open files from the filesystem there.
Use an External Method instead to point to a file-system stored script if you want to execute Python code that is not restricted.
The runscript action only uses the object as a context. Your script is free to ignore that context.