Nose test script with command line arguments
Solution 1
Alright, I hate "why would you want to do that?" answers just as much as anyone, but I'm going to have to make one here. I hope you don't mind.
I'd argue that doing whatever you're wanting to do isn't within the scope of the framework nose. Nose is intended for automated tests. If you have to pass in command-line arguments for the test to pass, then it isn't automated. Now, what you can do is something like this:
import sys
class test_something(object):
def setUp(self):
sys.argv[1] = 'arg'
del sys.argv[2] # remember that -s is in sys.argv[2], see below
def test_method(self):
print sys.argv
If you run that, you get this output:
[~] nosetests test_something.py -s
['/usr/local/bin/nosetests', 'arg']
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
(Remember to pass in the -s flag if you want to see what goes on stdout)
However, I'd probably still recommend against that, as it's generally a bad idea to mess with global state in automated tests if you can avoid it. What I would likely do is adapt whatever code I'm wanting to test to take an argv
list. Then, you can pass in whatever you want during testing and pass in sys.argv
in production.
UPDATE:
The reason why I need to do it is because I am testing multiple implementations of the same library. To test those implementations are correct I use a single nose script, that accepts as a command line argument the library that it should import for testing.
It sounds like you may want to try your hand at writing a nose plugin. It's pretty easy to do. Here are the latest docs.
Solution 2
You could use another means of getting stuff into your code:
import os
print os.getenv('KEY_THAT_MIGHT_EXIST', default_value)
Then just remember to set your environment before running nose.
Solution 3
I think that is a perfectly acceptable scenario. I also needed to do something similar in order to run the tests against different scenarios (dev, qa, prod, etc) and there I needed the right URLS and configurations for each environment.
The solution I found was to use the nose-testconfig plugin (link here). It is not exactly passing command line arguments, but creating a config file with all your parameters, and then passing this config file as argument when you execute your nose-tests.
The config file has the following format:
[group1]
env=qa
[urlConfig]
address=http://something
[dbConfig]
user=test
pass=test
And you can read the arguments using:
from testconfig import config
print(config['dbConfig']['user'])
Solution 4
For now I am using the following hack:
args = sys.argv[1:]
sys.argv = sys.argv[0:1]
which just reads the argument into a local variable, and then deletes all the additional arguments in sys.argv
so that nose does not get confused by them.
Solution 5
Just running nose and passing in parameters will not work as nose will attempt to interpret the arguments as nose parameters so you get the problems you are seeing.
I do not think nose support parameter passing directly yet but this nose plug-in nose-testconfig Allows you to write tests like below:
from testconfig import config
def test_os_specific_code():
os_name = config['os']['type']
if os_name == 'nt':
pass # some nt specific tests
else:
pass # tests for any other os
D R
Updated on September 26, 2020Comments
-
D R almost 4 years
I would like to be able to run a nose test script which accepts command line arguments. For example, something along the lines:
test.py
import nose, sys def test(): # do something with the command line arguments print sys.argv if __name__ == '__main__': nose.runmodule()
However, whenever I run this with a command line argument, I get an error:
$ python test.py arg E ====================================================================== ERROR: Failure: ImportError (No module named arg) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/nose-0.11.1-py2.6.egg/nose/loader.py", line 368, in loadTestsFromName module = resolve_name(addr.module) File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/nose-0.11.1-py2.6.egg/nose/util.py", line 334, in resolve_name module = __import__('.'.join(parts_copy)) ImportError: No module named arg ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (errors=1)
Apparently, nose tries to do something with the arguments passed in sys.argv. Is there a way to make nose ignore those arguments?
-
D R over 14 yearsThe reason why I need to do it is because I am testing multiple implementations of the same library. To test those implementations are correct I use a single nose script, that accepts as a command line argument the library that it should import for testing.
-
André Caron about 11 yearsThe link at the end is dead.
-
André Caron about 11 yearsNote that there a lots of good reasons to pass extra context. Consider that the test starts a web server, you may want to control on which port the server runs to avoid conflicts with other tests (or other running programs).
-
Charles Merriam almost 10 yearsThanks for the answer; I find I need it for checking programs that call argparse.
-
Thiago Burgos about 9 yearsI forgot to mention that to call you use 'nosetests --tc-file qa.conf'