Passing JSON string as argument to Pytest

63 views Asked by At

I'm using Pytest and configured my conftest.py to accept a few arguments:

def pytest_addoption(parser):
    parser.addoption(
        '--vm-name',
        required=True,
        metavar='vm-name',
        help='Name of the virtual machine the tests executes on',
        type=str,
        dest='vm-name'
    )
    parser.addoption(
        '--vm-ip',
        required=True,
        metavar='vm-ip',
        help='IP address of the virtual machine the tests executes on',
        type=str,
        dest='vm-ip'
    )
    parser.addoption(
        '--credentials',
        required=True,
        metavar='file',
        help='Path of the JSON file containing credentials',
        type=load_credentials,
        dest='credentials'
    )

load_credentials is a function that accepts a JSON string and initializes a JSON data class with the given string.

I'm using Pyvmomi to execute the following command in the virtual machine:

/bin/bash -c "echo user_password | sudo -S /usr/bin/python3 -m pytest /usr/local/auto/tests/shared/test_shared.py --vm-name my_vm --vm-ip 10.10.10.10 --credentials \'{\\"vcenter\\": {\\"username\\": \\"username\\", \\"password\\": \\"password\\"}, \\"vm\\": {\\"username\\": \\"Administrator\\", \\"password\\": \\"password\\"}}\' -rA --capture=tee-sys --show-capture=no --disable-pytest-warnings --junit-xml=/tmp/test_shared.xml"

However, I'm not sure why it doesn't work. I'm getting: zsh: event not found: \\. I assume it's because the JSON string isn't properly escaped or something. This is how I'm passing it in the code:

creds = Credentials(...)
creds_escaped = creds.replace('"','\\"')
f'-m pytest {test_path} --vm-name {vm.name} --vm-ip {vm.ip_address} --credentials \'{creds_escaped}\' {pytest_flags}'
1

There are 1 answers

0
Hai Vu On

I have a feeling that creds is a JSON object, if that is the case, and if you are using subprocess to launch pytest. Here is a simplified solution:

import json
import subprocess

cred = {
    "vcenter": {"username": "username", "password": "password"},
    "vm": {"username": "Administrator", "password": "password"},
}

cmd = [
    "python3",
    "script.py",  # An example, in place of pytest
    "--credentials",
    json.dumps(cred),
]
print("cmd:", cmd)
subprocess.run(cmd)

Note that I am using json.dumps() to do the quoting.