python – Parameterize the pytest test package to work in multiple classes

Context:
I am working on a package that allows users to access credentials (stored with a defined structure) from a database. The "database" can be a real KeePass database or other text-based formats like json.
The logic to read from the database is encapsulated in Provider classes, one for each format.
The user interacts with a CredentialsManager class that selects the correct provider and represents user queries to the provider.

Issue:
Naturally everyone Provider Classes have the same interface and (except for some provider specific details) should show the same behavior.
So a lot of the unit tests apply to all of them, they only differ in creating Provider example.
If I had to write another Provider class i don't want to copy paste the entire test suite and end with north implementations of the same test cases that must be maintained.

My opinion on this:
I have created a unit test module test_common_tests_for_all_providers.py which uses a parameterized test device to create the provider. This module contains all test cases that apply equally to all providers. After adding a new provider, the developer only needs to change the parameterization for the tests, not the implementation of the test cases.
Vendor-specific test cases (for example, to verify the different possibilities of unlocking a KeePass database with a master key) go in own test modules like test_keepass_provider.py. Those tests are do not focus of this review.
I will provide the code below and then indicate what I like / dislike about it.

Code:

import os.path

import pytest

from refarch.framework.credentials import errors
from refarch.framework.credentials.providers.json_provider import JsonProvider
from refarch.framework.credentials.providers.keepass_provider import KeePassProvider


RESOURCE_DIR = os.path.join(os.path.dirname(__file__), "..", "resources")
VALID_JSON_DB = os.path.join(RESOURCE_DIR, "JSON_Database.json")
INVALID_JSON_DB = os.path.join(RESOURCE_DIR, "Invalid_JSON_Database.json")
VALID_KEEPASS_DB = os.path.join(RESOURCE_DIR, "KeePass_with_password.kdbx")
INVALID_KEEPASS_DB = os.path.join(RESOURCE_DIR, "Invalid_KeePass_with_password.kdbx")


@pytest.fixture(
    params=(
        (JsonProvider, {"filename": VALID_JSON_DB}),
        (KeePassProvider, {"filename": VALID_KEEPASS_DB, "master_password": "password"})
    ),
    ids=(
        "JsonProvider",
        "KeePassProvider"
    )
)
def provider_instance(request):
    provider_class, kwargs = request.param
    return provider_class(**kwargs)


@pytest.mark.parametrize("provider_class", (JsonProvider, KeePassProvider))
def test_initialize_with_non_existing_file_raises_credentialsdbnotfound_error(provider_class):
    with pytest.raises(errors.CredentialsDBNotFoundError):
        provider_class("/this/does/not/exist.json")


@pytest.mark.parametrize("provider_class,invalid_db_file", (
    (JsonProvider, INVALID_JSON_DB),
    (KeePassProvider, INVALID_KEEPASS_DB)
))
def test_initialize_with_invalid_json_file_raises_credentialsdbinvalid_error(provider_class, invalid_db_file):
    with pytest.raises(errors.CredentialsDBInvalidError):
        provider_class(invalid_db_file)


@pytest.mark.parametrize(
    "device,connection_type,username,expected_password",
    (
        ("Laptop", "SSH", "defaultuser", "defaultpassword"),
        ("Laptop", "SSH", "root", "rootpassword"),
        ("Laptop", "HTTP", "Admin", "Adminpassword"),
        ("TV", "Bluetooth", "me", "mypw")
    )
)
def test_get_existing_credentials(provider_instance, device, connection_type, username, expected_password):
    credentials = provider_instance.get_credentials(device, connection_type, username)

    assert credentials.username == username
    assert credentials.password == expected_password


def test_get_default_credentials(provider_instance):
    credentials = provider_instance.get_credentials("Laptop", "SSH")

    assert credentials.username == "defaultuser"
    assert credentials.password == "defaultpassword"


def test_non_existing_group_raises_credentialsgroupnotfound_error(provider_instance):
    with pytest.raises(errors.CredentialGroupNotFoundError):
        provider_instance.get_credentials("Space Shuttle", "WiFi")


def test_no_default_user_raises_credentialsnotfound_error(provider_instance):
    with pytest.raises(errors.CredentialsNotFoundError):
        provider_instance.get_credentials("TV", "Bluetooth")

My opinion:

I like:

  • the main objective is met: the test cases themselves do not need to be changed, only the parameterization
  • Thanks to Pytest, test cases get meaningful identifications and can be easily distinguished

I do not like

  • The definition of the test device is cryptic. Maybe it's easier for people who do a lot of work with pytest and parameterized accessories to understand, but if I had to read that code myself, I'd probably have to do a double take.
  • Adding a new provider currently requires changes to Three places (apart from import declarations): device parameterization, parameterization of the first test case, parameterization of the second test case.

The question:
How could this code become more readable?
Is this the best approach for the intended goal, or is there a better way to reuse test cases with pytest?

Parameterize numeric fields III [duplicate]

This question is an exact duplicate of:

  • Parameterize numeric fields II

Leave $ X $ Be an integral scheme. Leave $ f: X rightarrow mathrm {Spec} ( mathbb {Q}) $ be a locally separated finite-type map (not necessarily quasi-compact).

Can it happen that for every kind of isomorphism? $ F $ of finite extensions of $ mathbb {Q} $ There is at least one closed point whose residue field is in $ F $? What is the simplest such $ f $? Can it be of relative dimension 1?

SSIS: How to parameterize the connection string for a DTSX package at run time

I have a very simple dtsx package in which I created a package parameter called pSourceFilePath and set its connection string to a path on a local disk. "Parametricé" the connection string for the flat file connection manager and configure it to point to the parameter (pSourceFilePath). Everything works very well when I run it in Visual Studio.

But when I run it from an application c # Winforms (after implementing the SSIS package in SQL Server), I configure a package parameter with the path of the flat file that I want the package to use as data entry for processing. The problem is: the packet ALWAYS uses the value defined at the time of design in the flat file connection manager and not the value of the pSourceFilePath parameter that I dynamically configured in my C # program and I passed it.

How can I make the package use the value of the parameter?

This is using SQL Server 2017 and Visual Studio 2017 (Winforms application).