Objective : To Create UnitTestCases for main.py
How can we import another python file which will dynamically return result
File : main.py
import os
_ENV = os.popen("echo ${RPM_ENVIRONMENT}").read().split('\n')[0]
_HOST = os.popen("echo $(hostname)").read().split('\n')[0]
_JOB_TYPE=os.popen("echo ${JOB_TYPE}").read().split('\n')[0]
SERVER_URL = {
'DEV':{'ENV_URL':'https://dev.net'},
'UAT':{'ENV_URL':'https://uat.net'},
'PROD':{'ENV_URL':'https://prod.net'}
}[_ENV]
Import another python file to our testing script
when i import main.py , i will receive error on SERVER_URL = { KeyError '${RPM_ENVIRONMENT}'
I believe the only reason why its returning error is because it does not recognize RPM_ENVIRONMENT, how can we mock _ENV variables in our main file and print server url as https://dev.net
After i have succesfully import main.py in my test case file, then i will create my unitTest cases as the ENV variable is required for me.
Testing : test_main.py
import unittest, sys
from unittest import mock
# --> Error
sys.path.insert(1, 'C:/home/src')
import main.py as conf
# For an example : we should be able to print https://dev.net when we include this in our line
URL = conf.SERVER_URL.get('ENV_URL')
ENV = conf._ENV
#URL should return https://dev.net & ENV should return DEV
class test_tbrp_case(unittest.TestCase):
def test_port(self):
#function yet to be created
pass
if __name__=='__main__':
unittest.main()
There's little reason to shell out of Python. You can read an environment variable with os.environ. os.environ['RPM_ENVIRONMENT'].
import os
_ENV = os.environ['RPM_ENVIRONMENT']
SERVER_URL = {
'DEV':{'ENV_URL':'https://dev.net'},
'UAT':{'ENV_URL':'https://uat.net'},
'PROD':{'ENV_URL':'https://prod.net'}
}[_ENV]
Now your test can set RPM_ENVIRONMENT before importing main.py.
os.environ['RPM_ENVIRONMENT'] = 'UAT'
sys.path.insert(1, 'C:/home/src')
import main.py as conf
Related
I have a test automation project where so far everything was working great.
I was able to run all the test by setting the Python path by typing the below command:
set PYTHONPATH="projectpath"
then
python .\"testscriptpath"
Now this week I started seeing this error:
ModuleNotFoundError : No Module named 'tests'
I tried the solution of adding a blank __init__.py file, but it didn't help.
I am looking for a solution to generate XML report files.
Below is the code:
import unittest
import allure
import xmlrunner
from selenium.webdriver.common.by import By
from tests.common import WICSUtils
from tests.common.GenericUtils import wics_select_by_visible_text, wics_utils_click, wics_select_by_index, \
wics_utils_get_text
from tests.icc.ICC_Common_Methods import search_by_offender_id_icc, make_initial_decision, \
go_to_inmate_classification_report, go_to_job_submitter_screen_and_submit_report, \
refresh_job_queue_until_job_finished
class ICCInmateInitialClassification(unittest.TestCase):
#classmethod
def setUpClass(cls):
# Get new driver instance
global myDriver
global emailAddress
global userFolder
myDriver = GenericUtils.get_new_driver_instance()
#allure.step("Logging into WICS")
def test_01_logging_into_WICS(self):
global emailfolderforreports
emailfolderforreports = "Reports"
WICSUtils.loginToWICS(myDriver, WICSUtils.Environment.UAT1, test)
expectedTitle = "ODSP590 - My Landing Page"
actualTitle = WICSUtils.get_page_main_title(myDriver)
GenericUtils.wics_assertion_is_substring(expectedTitle, actualTitle, myDriver)
#classmethod
def tearDownClass(cls):
WICSUtils.logOutWICS(myDriver)
myDriver.quit()
if __name__ == '__main__':
# main method to run xmlrunner to produce xml report in test-reports folder
with open('../../../test-results/ICC_R001_Inmate_Initial_Classification.xml', 'wb') as output:
unittest.main(
testRunner=xmlrunner.XMLTestRunner(output=output),
failfast=False, buffer=False, catchbreak=False)
Below is the error stack trace:
PS C:\Users\VellaSR\PycharmProjects\wics-selenium-scripts> python .\tests\icc\High\ICC_R001_Inmate_Initial_Classification.py
Traceback (most recent call last):
File ".\tests\icc\High\ICC_R001_Inmate_Initial_Classification.py", line 8, in <module>
from tests.common import WICSUtils
ModuleNotFoundError: No module named 'tests'
In order to make Python resolves all your relative imports, you must execute your script from the root working directory.
In your case, for example, the root is wics-selenium-scripts. You need to go there with your terminal, and then execute python path/to/your/script.py, e.g. python tests\icc\High\scriptName.py
I have two Python (3.8) scripts located in the same folder.
The first lookup.py is simply:
#! /usr/bin/env python3
import os
from getimp import session0
print (session0)
The second script getimp.py identifies a cookie and sets it as a variable which is imported into the first script. I have omitted some of the code here, but hopefully have the critical parts.
#! /usr/bin/env python3
import os
import json
import base64
import sqlite3
import shutil
from datetime import datetime, timedelta
import win32crypt # pip install pypiwin32
from Crypto.Cipher import AES # pip install pycryptodome
def get_chrome_datetime(chromedate):
"""Return a `datetime.datetime` object from a chrome format datetime
....
....
# you can also search by domain, e.g thepythoncode.com
cursor.execute("""
SELECT host_key, name, value, creation_utc, last_access_utc, expires_utc, encrypted_value
FROM cookies
WHERE name like '%user_id%'""")
# get the AES key
key = get_encryption_key()
for host_key, name, value, creation_utc, last_access_utc, expires_utc, encrypted_value in cursor.fetchall():
if not value:
decrypted_value = decrypt_data(encrypted_value, key)
else:
# already decrypted
decrypted_value = value
print(f"""
{decrypted_value}
===============================================================""")
session0 = decrypted_value
if __name__ == "__main__":
main()
If I run getimp.py on its own it generates the correct result but when I run lookup.py I get an error:
File "lookup", line 4, in <module>
from getimp import session0
ImportError: cannot import name 'session0' from 'getimp' (D:\Documents\ptest\getimp.py)
Am I losing the variable once the script getimp.py finishes?
Your problem is that the variablesession0 is defined inside the scope of get_chrome_datetime and therefore can not be addressed from import.
Try importing the function and create the variable inside the scope of the active script.
Inside 'get_chrome_datetime' change session0=decrypted_value into return decrypted_value
and in lookup.py :
import os
from getimp import get_chrome_datetime
print (get_chrome_datetime(argument))
Your problem is that session0 is defined inside the function.
I would suggest the following
session0 = None
def get_chrome_datetime(chromedate):
global session0
... (your code here)
Also you should call the function outside of if __name__ == '__main__' because when you're importing a module, the __name__ wouldn't be "__main__"
I have three files and I need to use one variable in these three files but the problem is when I use the variable in the third file test.py, it uses the first value from var.py. Also, when I define a new variable in the run.py and import the variable in the third file test.py, it keeps running without run the third file test.py and give this message non-resource variables are not supported in the long term. In addition, I still have a file env.py that I import in 'test.py' using the modified 'var.demend'
var.py
demend=-1
run.py
import var
print(var.demend)
for i in range(0,6) :
var.demend=i
gc.collect()
bots = [subprocess.check_call(["python"+version, os.path.join(current_dir, "test.py")])])]
modules = map(__import__,bots)
import multiprocessing,subprocess
for bot in (bots):
p = multiprocessing.Process(target=lambda: __import__(bot))
p.start()
test.py
import env
import var
print(var.demend)
env.py
import var
print(var.demend)
I use the demend in run.py file and then I pass the new parameter str(i)
run.py
import os
import var
import subprocess,_multiprocessing
import sys
import gc # Garbage Collector
print(var.demend)
version = ".".join(map(str, sys.version_info[:3]))
if len(version) >3:
version=version[:-2];
current_dir = os.path.dirname(os.path.realpath(__file__))
for i in range(0,6) :
demend=i
gc.collect()
bots = [subprocess.check_call(["python"+version, os.path.join(current_dir, "test.py"),str(i)])]
modules = map(__import__,bots)
import multiprocessing,subprocess
for bot in (bots):
p = multiprocessing.Process(target=lambda: __import__(bot))
p.start()
In the test.py file
import env
from sys import argv
demend=int(argv[1])
print(demend)
In the env.py file
from sys import argv
demend=int(argv[1])
print(demend)
I have a flask app that is giving me 500 when I import a file using sys.path.append('path/to/file.py)
Here is my file located in /var/www/html/ip.py which flask is calling:
import sys
sys.path.append('/auto/conf/')
from config import config
server_username = config['server_username']
server_password = config['server_prod_password']
def check_ip(ip_addr):
return "test"
Here is my /auto/conf/config.py:
import os
import ConfigParser
# Define names of dir and file
CRED_DIR = 'cred'
FILE_NAME = 'cred.conf'
# Path to cred file
my_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
cred_dir = os.path.join(my_dir, CRED_DIR)
file_path = os.path.join(cred_dir, FILE_NAME)
# Load the conf file with ConfigParser
config = ConfigParser.SafeConfigParser()
config.read(file_path)
# Build a config dictionary
config = {
'server_username': config.get('server', 'username'),
'server_password': config.get('server', 'password'),
}
and cred.conf is located in /auto/cred/cred.conf and contains server info.
Now, here is the issue. If I run python ip.py, it runs fine. I added print statement and it was fetching proper server username and password. But when I run it via Flask, it gives me 500 error.
Here are some of the things I tried:
-- If I comment out "from config import config" from ip.py, Flask runs returns "test" meaning it worked. It will not get server un and pw but atleast it does not 500.
-- If I move cred.conf and config.py to same directory as ip.py and comment out "sys.path.append('/auto/conf/')" and uncomment "from config import config", Flask works.
Any ideas why its happening? I am thinking Flask does not like sys.path.append. Is there any alternative I can use so Flask works?
Edit:
I changed ip.py to this:
import sys
sys.path.append('/auto/conf/')
import config
and removed all code in config.py and it is still gving me error. If I comment out "import config", Flask works. Definitely it does not like importing in this fashion..
I have file tree:
f:/src/
restore.ini
config.py
log.py
service.py
test.py
the test.py code like this:
import service
import log
import config
class Test(object):
def __init__(self):
super(Test, self).__init__()
def setUp(self):
self.currentRound = int(config.read_config_co(r'restore.ini', 'Record')['currentRound'])
def testAction(self):
log.info(self.currentRound)
def tearDown(self):
config.write_config_update_co(self.currentRound-1, 'Record', 'currentRound', r'restore.ini')
class PerfServiceThread(service.NTServiceThread):
def run (self):
while self.notifyEvent.isSet():
try:
test = Test()
test.setUp()
test.testAction()
test.tearDown()
except:
import traceback
log.info(traceback.format_exc())
class PerfService(pywinservice.NTService):
_svc_name_ = 'myservice'
_svc_display_name_ = "My Service"
_svc_description_ = "This is what My Service does"
_svc_thread_class = PerfServiceThread
if __name__ == '__main__':
pywinservice.handleCommandLine(PerfService)
Now, I use cmdline python test.py install and python test.py start to action service, but error.
If I move all files in directory src to C:\Python27\Lib\site-packages\win32\src, and change code:
self.currentRound = int(config.read_config_co(r'src\restore.ini', 'Record')['currentRound'])
config.write_config_update_co(self.currentRound-1, 'Record', 'currentRound', r'src\restore.ini')
Now, it's OK!
I want not move directory src, how do I do?
Thanks!
if you use relative paths for file or directory names python will look for them (or create them) in your current working directory (the $PWD variable in bash; something similar on windows?).
if you want to have them relative to the current python file, you can use (python 3.4)
from pathlib import Path
HERE = Path(__file__).parent.resolve()
RESTORE_INI = HERE / 'restore.ini'
or (python 2.7)
import os.path
HERE = os.path.abspath(os.path.dirname(__file__))
RESTORE_INI = os.path.join(HERE, 'restore.ini')
if your restore.ini file lives in the same directory as your python script.
then you can use that in
def setUp(self):
self.currentRound = int(config.read_config_co(RESTORE_INI,
'Record')['currentRound'])