I am trying to set a new argument in my test suite and I would like to pass it along pytest commands (e.g. pytest --arg=foo, or pytest --arg=bar path/to/test.py::test_func). Then, those arguments must be used inside some other module. Not test one.
I tried with sys.argv as it is the easiest method and I only need one argument.
To import into Python Scripts you need to parse arguments.
#!/usr/bin/env python
import argparse
def main(def_args=sys.argv[1:]):
args = arguments(def_args)
user_name = args.user_name
....
//Rest of code
def arguments(argsval):
parser = argparse.ArgumentParser()
parser.add_argument('-un', '--user_name', type=str, required=False,
help="""Overrides user.name git config.
If not specified, the global config is used.""")
Then pass your args in your pytest file.
How to pass arguments in pytest by command line
Related
I have a conftest.py file looking like this:
from testdevice import TestDevice
from pytest import fixture
def pytest_addoption(parser):
parser.addoption("--n", action="store", default="Name")
#fixture()
def name(request):
return request.config.getoption("--n")
def pytest_configure(config):
"""
Allows plugins and conftest files to perform initial configuration.
This hook is called for every plugin and initial conftest
file after command line options have been parsed.
"""
def pytest_sessionstart(session):
"""
Called after the Session object has been created and
before performing collection and entering the run test loop.
"""
name = 'device_name'
TestDevice(name)
def pytest_sessionfinish(session, exitstatus):
"""
Called after whole test run finished, right before
returning the exit status to the system.
"""
def pytest_unconfigure(config):
"""
called before test process is exited.
"""
I am testing an embedded device, using ssh in the tests. Before the test I want to prepare the device, using the class TestDevice(name). "name" is the key of a dictionary containing device information.
Instead of hardcoding name in sessionstart. I have created a fixture where i can access the name argument, however I am only able to use the fixture in the tests. I am not able to access the fixture in "pytest_sessionstart", as i am not able to access the "request" argument.
Can anything be done to access the python arguments on "pytest_sessionstart"?
You don't have to use an extra fixture.
You can get name in pytest_sessionstart via session object:
def pytest_addoption(parser):
parser.addoption("--n", action="store", default="Name")
def pytest_sessionstart(session):
name = session.config.getoption('--n'):
TestDevice(name)
I have a question about the functionality of argparse. I use argparse for custom functions and it's great, but sometimes I'd like to move the use of argparse and supplemental code into a separate function and use it there to reduce boilerplate / visual noise.
This is a partial example of what I'd like to do:
function A
set --local options ... # some definition.
argparse_wrapper --name A $options -- $argv; or return 1
end
instead of
function A
set --local options ... # some definition.
argparse --name A $options -- $argv; or return 1
# Code validating flags set by argparse in some way that argparse is unable to do,
# i.e. validation that requires values from two flags (so f/flag!script would not
# work).
#
# Or, changing flag names to names more appropriate inside the function.
#
# Other boilerplate related to options, but
# unrelated to the purpose of the function.
#
end
But, I'm unable to set values inside of a function and transfer those values seamlessly to the caller. As in, argparse sets values in the outer scope (the function calling argparse), but I'm unable to do the same with a custom argparse wrapper of my own. At least, I'm unsure of how to do so if there is a clean way. In particular, argparse can set local variables in its outer scope, and I want to keep that functionality in the supposed argparse wrapper. Is that possible?
I'm the person who designed and implemented argparse. The approach I recommend is the one you'll find in the share/functions/fish_opt.fish module. Execute the argparse in the function that implements the command. Define a helper function with the --no-scope-shadowing flag to give it direct access to the vars in the parent function. Then call that function to validate the args (or do whatever is needed) after argparse returns.
I am trying to suppress Pylint warnings from Squish, but not have same code written in front of the code like is described here: https://kb.froglogic.com/display/KB/Example+-+Using+PyLint+with+Squish+test+scripts+that+use+source%28%29
I would like to know if is a file that I can configure and uploaded into Squish
The article describes the only option, to define the Squish functions and symbols yourself.
However, it is showing what to do in a single file Squish test script file only for sake of simplicity.
You should of course put those Squish function definitions in a separate, re-usable file, and use import to "load" the definitions into your test.py file:
from squish_definitions import *
def main():
...
in squish_definitions.py:
# Trick Pylint and Python IDEs into accepting the
# definitions in this block, whereas upon execution
# none of these definitions will take place:
if -0:
class ApplicationContext:
pass
def startApplication(aut_path_or_name, optional_squishserver_host, optional_squishserver_port):
return ApplicationContext
# etc.
Also, you should generally switch over to using Python's import in favor of Squish's source() function.
I have had no success in locating a good precommit hook I can use to validate that a Jinja2 formatted file is well-formed without attempting to substitute variables. The goal is something that will return a shell code of zero if the file is well-formed without regard to whether variable are available, 1 otherwise.
You can do this within Jinja itself, you'd just need to write a script to read and parse the template.
Since you only care about well-formed templates, and not whether or not the variables are available, it should be fairly easy to do:
#!/usr/bin/env python
# filename: check_my_jinja.py
import sys
from jinja2 import Environment
env = Environment()
with open(sys.argv[1]) as template:
env.parse(template.read())
or something that iterates over all templates
#!/usr/bin/env python
# filename: check_my_jinja_recursive.py
import sys
import os
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('./mytemplates'))
templates = [x for x in env.list_templates() if x.endswith('.jinja2')]
for template in templates:
t = env.get_template(template)
env.parse(t)
If you have incorrect syntax, you will get a TemplateSyntaxError
So your precommit hook might look like
python check_my_jinja.py template.jinja2
python check_my_jinja_recursive.py /dir/templates_folder
I have a simple script like this (based on the docs for argparse):
def Main():
parser = argparse.ArgumentParser()
parser.add_argument("issuenumber", help="Create a local branch based on the specified issue number", type=int)
args = parser.parse_args()
if args.issuenumber:
print("Starting work on issue #"+str(args.issuenumber))
if __name__ == "__main__":
Main()
When I run it however, it never recognises the argument I'm passing it:
C:\Projects\PyTools>Gritter.py 1
usage: Gritter.py [-h] issuenumber
Gritter.py: error: the following arguments are required: issuenumber
If I call the script via a python call it works however:
C:\Projects\PyTools>python Gritter.py 1
Starting work on issue #1
If I print out sys.argv I get:
C:\Projects\PyTools>Gritter 1
['C:\\Projects\\PyTools\\Gritter.py']
C:\Projects\PyTools>Python Gritter.py 1
['Gritter.py', '1']
So I guess something is not passing on the arguments when the script is called directly. I wonder if there's anything that can be done so that the script can be called directly?
The C\ indicates you are using Windows. You have take extra effort to ensure that this 'direct call' passes arguments through to python.
Looking up windows shebang I find, from Python docs that you need to use
#!/usr/bin/python -v
to pass arguments
See https://docs.python.org/3/using/windows.html
argparse uses sys.argv. If that only has the script name then the call isn't passing arguments.
Based on mckoss` answer, I modified the following registry key:
HKEY_CLASSES_ROOT\Applications\python.exe\shell\open\command
From this:
"C:\Python34\python.exe" "%1"
To this:
"C:\Python34\python.exe" "%1" %*
And now my script works as I'd previously expected.