test.py
from optparse import OptionParser
class Test(object):
def __init__(self):
pass
def _test1(self, some_val):
print(some_val)
def main(self, some_val):
self._test1(some_val)
if __name__ == "__main__":
parser = OptionParser()
parser.add_option("-a", "--abcd", dest="abcd", default=None,help="some_val")
(options, args) = parser.parse_args()
val = options.abcd
mainobj = Test()
mainobj.main(val)
Above script works, when executed python test.py --abcd=wxyz
When I run python -m pylint test.py --abcd=wxyz , doesn't execute.
Error:
strong text Usage: __main__.py [options]
__main__.py: error: no such option: --abcd
How to execute through pylint ?
Can you please help me ?
You cannot send new arguments like that using Pylint
Pylint is a static code analysis tool. It does NOT run your program. Therefore it does not matter what arguments are sent to the main program you want to test. Imagine it tests your code as it was "text" without running it.
Also the syntax you are using in the command line is not right, because after-m pylint the arguments which are sent are actually Pylint's arguments. Pylint has it's own set of options and rules you can set. you can view a summary here
or just type in your command line this:
pylint --help
The error message you get is a Pylint error. if you want to change the options you insert to Pylint you would have to change its source code i reckon...
Hope I understood your question correctly and that it helps.
Related
I used customized pytest markers like below,
#pytest.mark.test_id("AB-1234")
def test_test1():
pass
#pytest.mark.test_id("AB-1234")
def test_test2():
pass
#pytest.mark.test_id("AB-5678")
def test_test3():
pass
Here test_id is the marker name and "AB-1234" is the value.
From command line how to run all the tests with marker test_id==AB-1234? I tried different variations with -m option but couldn't find a solution.
EDIT: I tried pytest -m "AB-1234" but it runs all the tests.
Using argparse in a Jupyter Notebook throws a TypeError. The same code works fine if I execute the same code as a script. MWE:
import argparse
parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('--name', '-n', default='foo', help='foo')
args = parser.parse_args()
Result:
TypeError: 'level' is an invalid keyword argument for this function
One solution is to parse an empty list of arguments:
import argparse
parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('--name', '-n', default='foo', help='foo')
args = parser.parse_args([])
Another is to use parse_known_args:
args, _ = parser.parse_known_args()
Ipython is running some command-line arguments in the background. This interfers with argparse and optparse.
See this bug for Spyder (Ipython IDE), where -f was being added as a command option and crashing as there was no handler for -f.
You could try checking the arguments currently in play (as they did for the Spyder bug) and putting a dummy handler in place.
Run
import sys
print(sys.argv)
inside Ipython and see what it outputs.
On my system, it gives
['/usr/lib/python3.6/site-packages/ipykernel_launcher.py', '-f', '/run/user/1000/jupyter/kernel-7537e4dd-b5e2-407c-9d4c-7023575cfc7c.json']
Argparse assumes the first entry is the program name (sys.argv[0]). In order to fix this, I had to call
parser = argparse.ArgumentParser(prog='myprogram', description='Foo')
... and now argparse works in my notebook.
When I run your code in a Notebook, I get an argparse usage error message:
usage: ipykernel_launcher.py [-h] [--name NAME]
ipykernel_launcher.py: error: unrecognized arguments: -f /run/user/1000/jupyter/kernel-a6504c0c-bed2-4405-8704-c008f52dcba6.json
With a print(sys.argv) I get
['/home/paul/.local/lib/python3.6/site-packages/ipykernel_launcher.py', '-f', '/run/user/1000/jupyter/kernel-a6504c0c-bed2-4405-8704-c008f52dcba6.json']
sys.argv, which parser parses, contains the values used to launch the Notebook server, which this particular parser is not setup to handle.
parser.parse_known_args() displays:
(Namespace(name='foo'),
['-f',
'/run/user/1000/jupyter/kernel-a6504c0c-bed2-4405-8704-c008f52dcba6.json'])
That extra stuff that your parser can't handle is put in the extras list.
Run with a custom argv list works:
parser.parse_args(['-n', 'foobar'])
Namespace(name='foobar')
It's a good idea to put argparse code (at least the parse_args line) in a __main__ block, so it is not run when the script is imported. It will still run when the script is run as a script.
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('--name', '-n', default='foo', help='foo')
args = parser.parse_args()
print(args)
This script also works when using %run stack50763033.py. You can even give it arguments as you would with a script:
%run stack50763033.py -n testing
I have no idea what code is producing the level keyword error. You'll have to give us the traceback if you want help with that.
I have a file called test.py with the following code:
import pytest
#pytest.mark.webtest
def test_http_request():
pass
class TestClass:
def test_method(self):
pass
pytest -s test.py passed but gave the following warnings:
pytest -s test.py
=============================== test session starts ============================
platform linux -- Python 3.7.3, pytest-5.2.4, py-1.8.0, pluggy-0.13.1
rootdir: /home/user
collected 2 items
test.py ..
=============================== warnings summary ===============================
anaconda3/lib/python3.7/site-packages/_pytest/mark/structures.py:325
~/anaconda3/lib/python3.7/site-packages/_pytest/mark/structures.py:325:
PytestUnknownMarkWarning: Unknown pytest.mark.webtest - is this a typo? You can register
custom marks to avoid this warning - for details, see https://docs.pytest.org/en/latest/mark.html
PytestUnknownMarkWarning,
-- Docs: https://docs.pytest.org/en/latest/warnings.html
=============================== 2 passed, 1 warnings in 0.03s ===================
Environment: Python 3.7.3, pytest 5.2.4, anaconda3
What is the best way to get rid of the warning message?
To properly handle this you need to register the custom marker. Create a pytest.ini file and place the following inside of it.
[pytest]
markers =
webtest: mark a test as a webtest.
Next time you run the tests, the warning about the unregistered marker will not be there.
without updating pytest.ini, we can ignore warning using --disable-warnings
We can also use --disable-pytest-warnings
Example using your case:
pytest -s test.py -m webtest --disable-warnings
#gold_cy's answer works. If you have too many custom markers need to register in pytest.ini, an alternative way is to use the following configuration in pytest.ini:
[pytest]
filterwarnings =
ignore::UserWarning
or in general, use the following:
[pytest]
filterwarnings =
error
ignore::UserWarning
the configuration above will ignore all user warnings, but will transform all other warnings into errors. See more at Warnings Capture
test.py (updated with two custom markers)
import pytest
#pytest.mark.webtest
def test_http_request():
print("webtest::test_http_request() called")
class TestClass:
#pytest.mark.test1
def test_method(self):
print("test1::test_method() called")
Use the following commands to run desired tests:
pytest -s test.py -m webtest
pytest -s test.py -m test1
The best way to get rid of the message is to register the custom marker as per #gold_cy's answer.
However if you just wish to suppress the warning as per Jonathon's answer, rather than ignoring UserWarning (which will suppress all instances of the warning regardless of their source) you can specify the particular warning you want to suppress like so (in pytest.ini):
ignore::_pytest.warning_types.PytestUnknownMarkWarning
Note: For third party libraries/modules the full path to the warning is required to avoid an _OptionError exception
If you don't have pytest.ini and don't wanna create one just for this then you can also register it programmatically in conftest.py as described here:
def pytest_configure(config):
# register an additional marker
config.addinivalue_line(
"markers", "env(name): mark test to run only on named environment"
)
To add to the existing answers - custom markers can also be registered in pyproject.toml:
# pyproject.toml
[tool.pytest.ini_options]
markers = [
"webtest: mark a test as a webtest.",
]
Related docs.
So I tried many things (from SO and more) getting my tests running but nothing worked this is my current code:
test.py which I call to run the tests: python3 ./src/preprocess/python/test.py
import unittest
if __name__ == '__main__':
testsuite = unittest.TestLoader().discover('.')
unittest.TextTestRunner(verbosity=2).run(testsuite)
the test file looks like this:
import unittest
from scrapes.pdf import full_path_to_destination_txt_file
print(full_path_to_destination_txt_file)
class PreprocessingTest(unittest.TestCase):
def path_txt_appending(self):
self.assertEqual(full_path_to_destination_txt_file(
"test", "/usr/test"), "/usr/test/test.txt")
if __name__ == '__main__':
unittest.main(verbosity=2)
But the output is always like this:
python3 ./src/preprocess/python/test.py
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
Additional Information:
As you can see I call this not from my root directory. The test folder is in ./src/preprocess/python/test/ and has a __init__.pyfile included (there is also a init file on the level of test.py)
it would be okay for me if I have to code down all the calls for all the tests I just want to finish this
automatic search with -t does not work either so I thought the more robust method here with test.py would work...
using this framework is a requirement I have to follow
test_preprocessing.py is in the test folder and from scrapes.pdf import full_path_to_destination_txt_filescrapes is a module folder on the same level as test
When I call the single unit test directly in the command line it fails because of the relative import. But using the test.py (obviously) finds the modules.
What is wrong?
By default, unittest will only execute methods whose name starts with test:
testMethodPrefix
String giving the prefix of method names which will be interpreted as test methods. The default value is 'test'.
This affects getTestCaseNames() and all the loadTestsFrom*() methods.
from the docs.
Either change that attribute or (preferably) prefix your method name with test_.
When I run the exact same function from the python3 interpreter vs, apache via mod wsgi, they both run error free but one returns the command text from apache the stout is simply always blank. Again I am running the exact same function.
Backgorund, I want to run svn update on some code to do so I am using subprocess to simply call "svn update /path/to/repo"
def update():
p1=subprocess.Popen(["svn", "update", "/var/www/myrepocode"],stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
(ret, stderr) = p1.communicate(timeout=10)
return (str(ret.decode('utf-8')))
when i run from the python3 shell or another python 3 script called from the shell
from test import update
print(update())
it works fine and i get
"Updating '/var/www/myrepocode':\nAt revision 27.\n"
when I have a wsgi script and execute it from accessing the web page
def application(environ, start_response):
...
output = output + "---"+update() +"---"
...
response_headers = [('Content-type', 'text/html'), ('Content-Length',
str(len(output)))]
start_response(status, response_headers)
return [output.encode('utf-8')]
I get an empty string:
------
I do not have a python virtual environment, just normal python3 and there are no errors thrown either. I suspect this has to do with the user running it but I really don't know. setting shell=True doesn't change anything either. Any help is greatly appreciated.
Your update method does not return nor print stderr . Maybe you should check for errors first by adding the following line in the update method.
print(stderr)
If errors are produced, can you post them?