How to call built in plugin alongside custom plugin with python nosetests - python

I am trying to write a custom plugin for nosetests ( a plugin to run as a custom selector) which works fine and i can use it by calling
nose.run(plugins=[CustomSelectorPlugin()])
However i also want to run nose with the built-in xunit plugin but I am unsure as to how to do this.
I have tried
nose.main(plugins=[CustomSelectorPlugin()], argv=['--with-xunit'])
and calling my program with --with-xunit option but these do not seem to work (well, everythion runs fine but there is no nosetests.xml generated)
How do i run both my plugin and xunit pragmatically?
Thanks

Solved the problem
I needed to call
nose.run(addplugins=[CustomSelectorPlugin()])
note the addplugins (as opposed to plugins) call. This allows me to call my program with command line arg --with-xnuit. Just having plugins meant the default plugin manager was not invoked/called/was overridden.
Also I should mention to be able to specify the args in code the first arg in argv is ignored by nose so something like this should be used:
nose.run(addplugins=[CustomSelectorPlugin()], argv=['foo', '--with-xunit'])
Hope this helps future googlers

Related

How to run pylint from inside Python?

I want to run pylint on all my modules, which are in different locations in a big directory. Because running pylint in this directory is still not supported, I assume I need to walk through each module in my own Python scripts and run pylint on each module from there.
To run pylint inside a Python script, the documentation seems clear:
It is also possible to call Pylint from another Python program, thanks
to the Run() function in the pylint.lint module (assuming Pylint
options are stored in a list of strings pylint_options) as:
import pylint.lint
pylint_opts = ['--version']
pylint.lint.Run(pylint_opts)
However, I cannot get this to run successfully on actual files. What is the correct syntax? Even if I copy-paste the arguments that worked on the command-line, using an absolute file path, the call fails:
import pylint.lint
pylint_opts = ["--load-plugins=pylint.extensions.docparams /home/user/me/mypath/myfile.py"]
pylint.lint.Run(pylint_opts)
The output is the default fallback dialogue of the command-line tool, with my script's name instead of pylint:
No config file found, using default configuration
Usage: myscript.py [options] module_or_package
Check that a module satisfied a coding standard (and more !).
myscript.py --help`
[...]
What am I missing?
I know that epylint exists as an alternative, and I can get that to run, but it is extremely inconvenient that it overrides the --msg-format and --reports parameters and I want to figure out what I am doing wrong.
The answer is to separate the options into a list, as shown in this related question:
pylint_opts = ["--load-plugins=pylint.extensions.docparams", "/home/user/me/mypath/myfile.py"]

pytest: how to override command line option in python program?

By default, pytest inflates the error traceback massively and printly some information into sysout stream that are redundant: Considering that I'm using PyCharm, it is really obfuscating to see code snippet out of context, while they are already available in the IDE & debugging interface.
As a result, I intend to set pytest traceback to native permanently. However, according to the documentation, the only way to do so is to add extra command line argument when launching the test runner:
-tb=native
I would like to make my test to always use the native traceback regardless of how it was run. Is it possible to use a TestCase API to do so?
Thanks a lot for your help.
You can add this option to the pytest.ini file and it would be automatically picked by pytest. For your specific case, a pytest.ini with following contents should work:
[pytest]
addopts = --tb=native
Note the double hyphens with tb; I am using pytest 4.6.4 and that is how it works for me.
Also, Refer pytest docs for another alternative by modifying PYTEST_ADDOPTS env variable.
I'm not sure how you can do this using pytest, nor am I familiar with this package. With that being said, you can always create a bash function to accomplish this:
function pytest() {
pytest -tb=native "$#"
}
The "$#" symbol will pass all arguments following pyt to the function (kind of like *args in python), so running pyt arg1 arg2 ... argn will be the same as running
pytest -tb=native arg1 arg2 ... argn
If you are unfamiliar with creating bash shortcuts, see this question.
Update
I misunderstood and thought OP was calling pytest from the cli. Instead of creating the pyt function, if you override pytest directly, PyCharm might invoke your bash version of it instead (I'm not really sure though).
That being said, yaniv's answer seems superior to this, if it works.

How do I force setup.py to auto-generate a console script with unbuffered output mode?

In Python 3, it's my understanding that the recommended way to build a Python command line script is to treat it as an "entry point" into a python package, and then use setup.py in order to auto-generate the actual script itself, based upon a main() function found somewhere within in the package.
I've found some decent tutorials here, here and here which explain exactly how to do that.
The problem with auto-generating the script is that I'm not sure how to control the contents of the "shebang" line (e.g., #!/usr/bin/env python) which would typically appear near the top of the script--that part is auto-generated for me.
I would like to design the command line script so that the "shebang" line automatically calls python with certain python flags enabled by default
In particular, I want to run the script as python -u in order to turn off stdout buffering as described here.
What would I need to put in my setup.py file in order to tell setuptools to do that for me? Of course I could just edit the auto-generated script by hand afterward, but that seems like it would utterly defeat the purpose of having a system to auto-generate console scripts in the first place. Is there a way to do it, or is this just a fundamental limitation of the "package entry point" model for creating command line scripts?
There are various ways this topic is treated on Stack Overflow.
I will list two examples:
accomplish what you want programmatically (which is based on https://stackoverflow.com/a/882060/5682996)
modify sys.executable / provide 'execute' argument (Remark: I don't know exactly if this works for the -u option)

Override existing configuration when using nose in Python in a script

I'm trying to setup Python to execute nose, but only on an existing application I'm developing locally. I don't want nose running around all libraries that are currently installed. I do, however, want nose to discover any tests within the current working directory and child directories.
To start with, all I'm trying to do is make sure that the arguments I'm passing are being used (solved by #need-batchelder below). However, at the moment it looks like the arguments I am passing are being ignored, and global discovery of the tests is occurring (i.e. picking up tests from the python folder too.
From the docs:
-V, --version
Output nose version and exit
Running nosetests -V from the command line produces the expected version output:
nosetests -V
nosetests-script.py version 1.2.1
However, the following test script starts running every test it can find, including those of libraries installed in the python path and not part of the current working directory , even though it is located in the root of the application:
import nose, os
def main():
print os.getcwd()
x=raw_input() #This is just so I can see the output of the cwd before it launches into testing everything it can find.
result = nose.run(argv=['-V'])
if __name__ == '__main__':
main()
Here's what I've tried:
Using nose.main() , x=nose.core.run() , x=nose.run().
Passing the arguments directly to nose.run() and using a list.
Using a nose.cfg file.
Thanks
EDIT: Trying #ned-batchelder 's suggestion allows me to run nose with given arguments, but doesn't allow discovery of tests within the application folders. So if I do that, I can pass arguments but I can't test my application.
I believe nose expects argv to be the complete argv, meaning the first element should be the name of the program:
nose.run(argv=['me.py', '-V'])
Probably, what you want is:
arguments = sys.argv[:1] + my_custom_argument_list + sys.argv[1:]
nose.run(argv=arguments)
This will allow you to use your custom arguments as well as those from the command line that invokes your script. It also address the issue that Ned points out about nose requiring that the first argument point to the script.

print statement is not working in python proboscis

We started writing our functional and unit test cases in python using nose framework. We started learning python while writing these tests. Since there are lot of dependencies between our test classes/functions, we decided to use proboscis framework on top of nose to control order of execution.
We have quite a few 'print' statements in our tests and proboscis seems to be ignoring these! Tests are running in expected order and testing them all but not printing our print statement data to console. Any idea what we are missing here?
BTW, we stopped deriving our classes from 'unittest.TestCase' once we moved to proboscis and decorated all classes and their member functions with #test.
Note: According to the Proboscis documentation "unused arguments get passed along to Nose or the unittest module", so the following should apply to Proboscis by replacing nosetests with python run_tests.py.
As #Wooble has mentioned in his comment, by default nose captures stdout and only displays it for failed tests. You can override this behaviour with the nosetests -s or --nocapture switch:
$ nosetests --nocapture
Like #Wooble also mentions in his comment, I recommend using the logging module instead of print. Then you only need to pass nosetests the -l DEBUG or --debug=DEBUG switch, where DEBUG is replaced by a comma separated list of the names of the loggers you want to display, to enable displaying of the logging output from your modules:
$ nosetests --debug=your-logger-name

Categories

Resources