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

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.

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 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 Those tests are do not focus of this review.
I will provide the code below and then indicate what I like / dislike about it.


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")

        (JsonProvider, {"filename": VALID_JSON_DB}),
        (KeePassProvider, {"filename": VALID_KEEPASS_DB, "master_password": "password"})
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):

@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):

        ("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).