I am trying to execute test suit by importing class from another file.
I have file list as below -
enter image description here
I am using below -
import unittest
import HTMLTestRunner
from Enhancement.Exercise18_WriteExcel import TestEx18
from UnitTest.Exercise14_OrderFood import TestEx14
if __name__ == "__main__":
# import sys;sys.argv = ['', 'Test.testName']
unittest.main()
# get all tests from Login and SignUp class
tc1 = unittest.TestLoader().loadTestsFromTestCase(TestEx18)
tc2 = unittest.TestLoader().loadTestsFromTestCase(TestEx14)
# create a test suite combining tc1 and tc2
test_suite = unittest.TestSuite([tc1, tc2])
# run the suite
unittest.TextTestRunner(verbosity=1).run(test_suite)
#unittest.main(testRunner=HTMLTestRunner.HTMLTestRunner(output="demo/reports"))
But getting error -
enter image description here
Kindly advise how can I resolve this issue.
Take a look at the answer found here ==> https://stackoverflow.com/a/28224295/16879293
basically, you have 2 options, one would be to add your Enhancement to the PYTHONPATH, or you can simply add to your code :
import sys
sys.append("..")
Run the same command from /path/to/Selenium_Practice/ folder (and not /path/to/Selenium_Practice/Reporting/ folder)
Related
Objective : To Create UnitTestCases for main.py
How can we run subprocess.run as unittest case
File : main.py
import os
_ENV = os.environ['server']
BASE_PATH = '/home/test'
SERVER_URL = {
'DEV':{'ENV_URL':'https://dev.net'},
'UAT':{'ENV_URL':'https://uat.net'},
'PROD':{'ENV_URL':'https://prod.net'}
}[_ENV]
if _CYBERARK=='DYNAMIC' and _ENV.upper() in ('DEV','UAT','PROD') :
TOKEN = json.load(open(BASE_PATH + "secrets/cyberark_env.json"))
APPID = CONFIGURE_TOKEN.get('desc').get('appID')
## --> error on this because its running .sh files
VALUE=subprocess.run(["sh",BASE_PATH + "bin/cyberark.sh",APPID],capture_output=True,text=True).stdout.strip()
In my test_main.py
I am trying to import main.py to my test.py without any issues, but i find it challenging on how we to manually make VALUE variable return as 'ABCD'
Similar to below scripts
Testing : test_main.py
import unittest, sys
from unittest import mock
os.environ['server']='DEV'
# Similar to os.environ , i want to create temporarily VALUE before import main is called.
sys.path.insert(1, 'C:/home/src')
import main.py as conf
class test_tbrp_case(unittest.TestCase):
def test_port(self):
#function yet to be created
pass
if __name__=='__main__':
unittest.main()
Is this achieveable or i need to relogic my whole function
I have a file TestProtocol.py that has unittests. I can run that script and get test results for my 30 tests as expected. Now I want to run those tests from another file tester.py that is located in the same directory. Inside tester.py I tried import TestProtocol, but it runs 0 tests.
Then I found the documentation which says I should do something like this:
suite = unittest.TestLoader().discover(".", pattern = "*")
unittest.run(suite)
This should go through all files in the current directory . that match the pattern *, so all tests in all files. Unfortunately it again runs 0 tests.
There is a related QA that suggests to do
import TestProtocol
suite = unittest.findTestCases(TestProtocol)
unittest.run(suite)
but that also does not find any tests.
How do I import and run my tests?
You can try with following
# preferred module name would be test_protol as CamelCase convention are used for class name
import TestProtocol
# try to load all testcases from given module, hope your testcases are extending from unittest.TestCase
suite = unittest.TestLoader().loadTestsFromModule(TestProtocol)
# run all tests with verbosity
unittest.TextTestRunner(verbosity=2).run(suite)
Here is a full example
file 1: test_me.py
# file 1: test_me.py
import unittest
class TestMe(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
if __name__ == '__main__':
unittest.main()
file 2: test_other.py, put this under same directory
# file 2: test_other.py, put this under same directory
import unittest
import test_me
suite = unittest.TestLoader().loadTestsFromModule(test_me)
unittest.TextTestRunner(verbosity=2).run(suite)
run each file, it will show the same result
# python test_me.py - Ran 1 test in 0.000s
# python test_other.py - Ran 1 test in 0.000s
I have a script call run_test.py, here's the content:-
if __name__ == '__main__':
nose.main(argv=sys.argv)
Running all my tests is as simple as doing this:
run_test.py unittests/test_*.py
I'm trying to now incorperate the output reporting for this into teamcity.
I'm referring to this https://github.com/JetBrains/teamcity-messages
I tried changing all my unittests/test_*.py program following the documentation. It works if running the test individually like this:-
unittest/test_one.py
But it does not work when running it thru nose, like this:
run_test.py unittest/test_one.py
According to the documentation link, it says that nose reporting is enabled automatically under TeamCity build. I don't quite get what that means.
Is there anything that i'm missing out here?
Any help is greatly appreciated. Thanks.
have a look at the xunit plugin of nose.
it will generate an xml file with the results => which jenkins and teamcity can use.
some documentation for teamcity
this post tells you how to enable the plugin in your test script
if __name__ == '__main__':
argv = sys.argv[:]
argv.insert(1, "--with-xunit")
nose.main(argv=argv)
I finally found out the way to achieve that.
Here's what i modified in my run_test.py
#!/usr/bin/env python
import os
import sys
import unittest
from teamcity import is_running_under_teamcity
from teamcity.unittestpy import TeamcityTestRunner
loader = unittest.TestLoader()
start_dir = sys.argv[1]
suite = loader.discover(start_dir, pattern='test_*.py')
#runner = unittest.TextTestRunner()
runner = TeamcityTestRunner(verbosity=2)
runner.run(suite)
I'm trying to keep my code reasonably organized by putting tests in a separate directory from my app. However, imports work either for the app or for the tests, but not both. Here's a contrived example that illustrates my current problem:
myapp/
app/
main.py
settings.py
moods.py
test/
test_moods.py
Contents of files as follows:
main.py
import settings
from moods import Moods
words = Moods(settings.EXAMPLE)
print(words.excited())
settings.py
EXAMPLE = "Wow$ Python$"
DELIM = "$"
moods.py
import settings
class Moods:
def __init__(self, text):
self.text = text
def excited(self):
return self.text.replace(settings.DELIM, "!!!")
test_moods.py
import sys, os, unittest
sys.path.insert(0, os.path.abspath('..'))
from app.moods import Moods
class TestMood(unittest.TestCase):
def setUp(self):
self.words = Moods("Broken imports$ So sad$")
def test_mood(self):
self.assertEqual(self.words.excited(), "Broken imports!!! So sad!!!")
with self.assertRaises(AttributeError):
self.words.angry()
if __name__ == "__main__":
unittest.main()
In the current state, from myapp/ I can run the following successfully:
>> python3 app/main.py
Wow!!! Python!!!
But when I try to run tests, the import fails in moods.py:
>> python3 -m unittest discover test/
ImportError: Failed to import test module: test_moods
[ stack trace here pointing to first line of moods.py ]
ImportError: No module named 'settings'
If I modify line 1 of moods.py to read from app import settings, the test will pass, but normal execution of the app fails because it sees no module app.
The only solutions I can think of are
Putting the tests in the same directory as the code (which I was trying to avoid)
Adding the sys.path.insert(0, os.path.abspath('..')) to each file in my app to make the imports work the same as the test ones do (which seems messy)
Is there are more elegant way to solve this import problem?
You should have both app and test directory in PYTHONPATH.
One way is to replace this:
sys.path.insert(0, os.path.abspath('..'))
from app.moods import Moods
with this:
sys.path.insert(0, os.path.abspath('../app'))
from moods import Moods
Or you can set the PYTHONPATH environament variable before running the tests.
Why? Because when you run main.py, then app is in the path, not app/.., so you want to have the same when running tests.
I started using Python few days back and I think I have a very basic question where I am stuck. Maybe I am not doing it correctly in Python so wanted some advice from the experts:
I have a config.cfg & a class test in one package lib as follows:
myProj/lib/pkg1/config.cfg
[api_config]
url = https://someapi.com/v1/
username=sumitk
myProj/lib/pkg1/test.py
class test(object):
def __init__(self, **kwargs):
config = ConfigParser.ConfigParser()
config.read('config.cfg')
print config.get('api_config', 'username')
#just printing here but will be using this as a class variable
def some other foos()..
Now I want to create an object of test in some other module in a different package
myProj/example/useTest.py
from lib.pkg1.test import test
def temp(a, b, c):
var = test()
def main():
temp("","","")
if __name__ == '__main__':
main()
Running useTest.py is giving me error:
...
print config.get('api_config', 'username')
File "C:\Python27\lib\ConfigParser.py", line 607, in get
raise NoSectionError(section)
ConfigParser.NoSectionError: No section: 'api_config'
Now if I place thie useTest.py in the same package it runs perfectly fine:
myProj/lib/pkg1/useTest.py
myProj/lib/pkg1/test.py
myProj/lib/pkg1/config.cfg
I guess there is some very basic package access concept in Python that I am not aware of or is there something I am doing wrong here?
The issue here is that you have a different working directory depending on which module is your main script. You can check the working directory by adding the following lines to the top of each script:
import os
print os.getcwd()
Because you just provide 'config.cfg' as your file name, it will attempt to find that file inside of the working directory.
To fix this, give an absolute path to your config file.
You should be able to figure out the absolute path with the following method since you know that config.cfg and test.py are in the same directory:
# inside of test.py
import os
config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
'config.cfg')