How to run python script in robot framework properly - python

I'm new to robot framework, I have a python script that I want to run in robot framework but it's not running properly, it fails and the output is empty of the script(the error: '' does not contain 'hello')
the robot framework file:
*** Settings ***
Library OperatingSystem
Library Process
*** Test Cases ***
Simple pyhton example
${result} = Run Process python3 hello.py -c arg1 -b arg2
Log ${result.stdout}
Should Contain ${result.stdout} hello
the py file:
import sys
print("This is the name of the script:", sys.argv[0])
print("Number of arguments:", len(sys.argv))
print("The arguments are:", str(sys.argv))
print("hello world")

First of all your hello.py file needs to contain a function (or a class with methods). Not sure what you want to do with the specific arguments, but the content could look like this:
def hello_world(name, friend):
return "hello " + name + " and " + friend
Now you may import it as a library into your robot file and call the function:
*** Settings ***
Library hello.py
*** Test Cases ***
Simple Pyhton Example
${result} Hello World bitrex superman
Log ${result}
Should Contain ${result} hello
More information: https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#creating-test-libraries

Related

2-way interop/IPC between SWI Prolog & Python

There is module to call from Python (pyswip) =to=> Prolog, but is there a way to call the other way around from Prolog =to=> Python ?
I need it so I can call Spacy-NLP module from SWI-Prolog
couldn't find if SWI supports ZeroMQ.
This is the sample python code in a file "c:\hello.py" that extracts the argumentq on the command line (optional). It's results are echoed to the standard output stream.
import sys
def hello():
return 'hello world: ' + ','.join(sys.argv[1:])
if __name__ == '__main__':
print(hello())
Here is the prolog program in file "c:\hello.pl" invoking the above python code as a process:
do :-
process_create(path('python3.7'),
['c:/hello.py', foo, bar],
[stdout(pipe(In))]), %output stream named In
read_string(In, Len, X), %In=input stream to read_string/3
write(X), nl, halt.
To activate this prolog/python combo and writting the results to the output stream
$ swipl -g do c:\hello.pl
hello world: foo,bar
Does this do what you wanted?

How to call a python method from robot framework

I need to call a python method from robot framework.
def getRandomEmails():
a = ''.join(random.choice(string.ascii_lowercase + string.digits) for i in range(16))
email = a + '#' + 'gmail.com'
return email
This function is written in EnvVar.py file
How can I use the returned value from this method in Robot Framework. I have tried almost many ways, but nothing works.
please help.
Using Evaluate
Exactly how to do it on your system depends on how your files are organized and how you've configured robot, but in short, Evaluate from the BuiltIn library is the keyword that lets you run arbitrary methods from importable modules.
Example:
For this example I've created a file named EnvVar.py in the current working directory. It has the following contents:
import random, string
def getRandomEmails():
a = ''.join(random.choice(string.ascii_lowercase + string.digits) for i in range(16))
email = a + '#' + 'gmail.com'
return email
I then created a file named "example.robot" that looks like this:
*** Test cases ***
Example
${result}= evaluate EnvVar.getRandomEmails() modules=EnvVar
log result: ${result}
Since the current working directory isn't by default on my PYTHONPATH (your setup may be different), I have to tell robot to include the current directory on PYTHONPATH. I can do that with the --pythonpath option.
$ robot --pythonpath . example.robot
Creating a keyword library
Another solution is to create your own keyword library that exposes this function as a keyword.
For example, assuming you can import EnvVar, you could write a library named "Util" (Util.py) that creates a keyword that calls this function:
# Util.py
import EnvVar
def get_random_emails():
return EnvVar.getRandomEmails()
You would then use this in a test like any other keyword library:
*** Settings ***
Library Util.py
*** Test Cases ***
Example
${result}= Get Random Emails
log result: ${result}
If it's the only method you want to add than you could add keyword decorator i.e:
from robot.api.deco import keyword
#keyword
def getRandomEmails():
a = ''.join(random.choice(string.ascii_lowercase + string.digits) for i in range(16))
email = a + '#' + 'gmail.com'
return email
And obviously you should import in settings as library

Python3 - output __main__ file prints when running unittests (from actual program, not unittests)

How can I make that my __main__ file prints are outputted, when I run tests? I mean prints from that file, not unittests files prints.
I have this sample structure (all files are in the same directory):
main.py:
import argparse
print('print me?') # no output
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('name')
args = parser.parse_args()
print(args.name) # no output
other.py:
def print_me():
print('ran print_me')
test.py:
import unittest
import sh
import other
class TestMain(unittest.TestCase):
def test_main(self):
print('test_main') # prints it.
sh.python3('main.py', 'test123')
def test_other(self):
print('test_other') # prints it.
other.print_me()
And I run it with python3 -m nose -s or python3 -m unittest, but it makes no difference, prints are not outputted from main.py, only the ones that are defined directly on test file. Here is what I do get:
user#user:~/python-programs/test_main$ python3 -m nose -s
test_main
.test_other
ran print_me
.
----------------------------------------------------------------------
Ran 2 tests in 0.040s
OK
P.S. Of course if I run main.py without using tests, then it prints normally (for example using python shell/interpreter and calling main.py with sh, just like in unittests)
sh.python3 starts new process and its output is not captured by nose. You can redirect the output printing the result from it:
print(sh.python3('main.py', 'test123'))

Robotframework treats variables passed from python class as 'None'

i have a python class Wiresharking.py
from subprocess import Popen, CREATE_NEW_CONSOLE,PIPE,STDOUT
import time
import subprocess
import datetime
import os
#import envSI
class Wiresharking:
"""Wireshark Server subclass"""
def __init__(self,**kwargs):
self.filters=''
self.window_ip = kwargs.get('ip')
print type(self.window_ip)
self.window_user= kwargs.get('username')
self.window_password= kwargs.get('password')
self.dest_path= kwargs.get('Target_path')
self.interface= kwargs.get('interface')
self.terminal='cmd'
self.home=kwargs.get('Home_path')
def test(self):
print 'hi'
return self.window_ip
i can call it from another python file (env.py) like below
SERVER_01 = Wiresharking(
name='WIRESHARK_ENV91',
ip='192.168.1.16',
username=r'INTRA\pmmm', #always prepend r , before giving your username and password
password='jan#2018',
prompt='$ ',
autostart=False,
unzip_capture=True,
filter='',
#interface=['ens2f0'],
interface='Ethernet',
Target_path=r'D:\Users\pankaj-m\Desktop\Test'
)
print SERVER_01.test()
output :
<type 'str'>
hi
192.168.1.16
however , the problem arises when i use env.py file as --variable file with robotframework
command
pybot -V env.py Check.robot
Check.robot file is below
*** Settings ***
Library Wiresharking.py
*** Test Cases ***
Test
check
*** Keywords ***
check
${abc} = test
log ${abc}
the output i here getting is 'None'
16:13:37.279 INFO None
can anyone point out what wrong i am doing here.
Your env.py defines a single variable named ${SERVER_01}. However, Check.robot never uses that variable.
Check.robot imports Wiresharking.py without passing any arguments. That causes its self.window_ip to be None, and thus the keyword returns None.
If you want to see the values from env.py, you need to look at the ${SERVER_01} variable. For example:
log ${SERVER_01.window_ip}
This is the way i was able to pass **kwargs and able to resolve error .
I am still looking for a cleaner way to pass **kwargs
*** Settings ***
Library Wiresharking.py ip=${SERVER_01.window_ip} username=${SERVER_01.window_user} password=${SERVER_01.window_password} Target_path=${SERVER_01.dest_path} interface=${SERVER_01.interface} Home_path=${SERVER_01.home} WITH NAME Mylib
*** Variables ***
${window_ip }
#&{names} = Create Dictionary 0=First Name 2=Email
*** Test Cases ***
Test
check
*** Keywords ***
check
${abc} = test
log ${abc}
Output
INFO 192.168.1.16

In robot framework how do you to create object of class and call the methods in corresponding class?

In robot framework how do you to create object of class and call the methods in corresponding class? This is the code snippet.
*** Settings ***
Documentation A resource file with reusable keywords and variables.
... Use keywords in this file in testcases directory.
Library /home/kirti/src/Helper/utilities.py
Library /home/kirti/src/Helper/config_parser.py
#Library /home/kirti/qa/src/executor/cleanup.CleanUp
Library /home/kirti/qa/src/executor/cleanup.py
*** Variables ***
${RESULT} 0
*** Keywords ***
Read Json Config Values
Log To Console "Setting up the config values globally"
config_parser.Json Config Parser
Import Variables /home/kirti/src/Helper/variables.py
Log Variables INFO
Check Machines Reachability
utilities.Check All Machines Status
Check SNMP Counter
utilities.Get Snmp 192.178.1.2 PPSessionCount
Call Clean Up
#${cleanupobj}= cleanup.create cleanup
#${name}= ${cleanupobj.cc()}
Import Library /home/kirti/src/executor/cleanup.py
${cmp}= Get library instance CleanUp
Log To Console ${cmp}.__class__.__name__
#${name}= Call method ${cmp} Create cleanup
${name}= Call method ${cmp} cc
#${name}= Call method ${cleanupobj} env cleanup
#Log To Console "${name}"
#Log Variables INFO
utilities.Check All Machines Status
Here is a way you can achieve the desired result.
Lets take example of demo.py which have class Sample
Sample class has init ,getting_path() as methods
class Sample(object):
def __init__(self,path,device):
self.device=device
self.path = path
def getting_path(self):
return self.path
Lets use these methods in Robotfile
*** Settings ***
#in the Library section you reference python class in below format
# (file.class_name) so file is demo.py and class is Sample
Library demo.Sample ${path} ${device} WITH NAME obj
#path and device are two arguments required by __init__,'obj' will be used to
#access the methods in python class
Library Collections
*** Variables ***
${path} c:
${device} samsung
*** Test Cases ***
Test
Test_python_class
*** Keywords ***
Test_python_class
#with obj you now call the method of python file
${result} = obj.getting_path
#if method need any argument , this can be passed like
#${result} = obj.getting_path ${arg1} ${arg2}
log to console ${result}
If you want to use a specific instance of a class you can use
${instance} = obj arg1
log to console ${instance.function(args)}

Categories